diff --git a/po/POTFILES b/po/POTFILES index c20781e1a8..3514aa3dca 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -21,6 +21,7 @@ src/bhyve/bhyve_process.c src/ch/ch_conf.c src/ch/ch_domain.c src/ch/ch_driver.c +src/ch/ch_hostdev.c src/ch/ch_interface.c src/ch/ch_monitor.c src/ch/ch_process.c diff --git a/src/ch/ch_hostdev.c b/src/ch/ch_hostdev.c new file mode 100644 index 0000000000..c18137b661 --- /dev/null +++ b/src/ch/ch_hostdev.c @@ -0,0 +1,94 @@ +/* + * ch_hostdev.c: Cloud Hypervisor hostdev management + * + * Copyright (C) 2021 Wei Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "ch_hostdev.h" +#include "virlog.h" + +#define VIR_FROM_THIS VIR_FROM_CH + +VIR_LOG_INIT("ch.ch_hostdev"); + +static int +virCHDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev) +{ + bool supportsPassthroughVFIO = virHostdevHostSupportsPassthroughVFIO(); + virDeviceHostdevPCIDriverName *driverName = &hostdev->source.subsys.u.pci.driver.name; + + /* assign defaults for hostdev passthrough */ + switch (*driverName) { + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT: + if (supportsPassthroughVFIO) { + *driverName = VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support passthrough of host PCI devices")); + return -1; + } + break; + + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO: + if (!supportsPassthroughVFIO) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support VFIO PCI passthrough")); + return false; + } + break; + + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_KVM: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support legacy PCI passthrough")); + return false; + + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CH does not support device assignment mode '%1$s'"), + virDeviceHostdevPCIDriverNameTypeToString(*driverName)); + return false; + + default: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_LAST: + virReportEnumRangeError(virDeviceHostdevPCIDriverName, *driverName); + break; + } + + return true; +} + +int +virCHDomainPrepareHostdev(virDomainHostdevDef *hostdev) +{ + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + return 0; + + switch (hostdev->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + return virCHDomainPrepareHostdevPCI(hostdev); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: + break; + } + + return 0; +} diff --git a/src/ch/ch_hostdev.h b/src/ch/ch_hostdev.h new file mode 100644 index 0000000000..f9ba40ab71 --- /dev/null +++ b/src/ch/ch_hostdev.h @@ -0,0 +1,27 @@ +/* + * ch_hostdev.h: Cloud Hypervisor hostdev management + * + * Copyright (C) 2021 Wei Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "ch_conf.h" +#include "domain_conf.h" + +int +virCHDomainPrepareHostdev(virDomainHostdevDef *hostdev); diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c index 9816509e49..c5b5b6ebb2 100644 --- a/src/ch/ch_process.c +++ b/src/ch/ch_process.c @@ -37,6 +37,7 @@ #include "virnuma.h" #include "virstring.h" #include "ch_interface.h" +#include "ch_hostdev.h" #define VIR_FROM_THIS VIR_FROM_CH @@ -808,6 +809,40 @@ virCHProcessStartValidate(virCHDriver *driver, return 0; } +static int +virCHProcessPrepareDomainHostdevs(virDomainObj *vm) +{ + size_t i; + + for (i = 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; + + if (virCHDomainPrepareHostdev(hostdev) < 0) + return -1; + } + + return 0; +} + +/** + * virCHProcessPrepareDomain: + * @vm: domain object + * + * This function groups all code that modifies only live XML of a domain which + * is about to start and it's the only place to do those modifications. + * + * This function MUST be called before virCHProcessPrepareHost(). + * + */ +static int +virCHProcessPrepareDomain(virDomainObj *vm) +{ + if (virCHProcessPrepareDomainHostdevs(vm) < 0) + return -1; + + return 0; +} + /** * virCHProcessStart: * @driver: pointer to driver structure @@ -839,6 +874,10 @@ virCHProcessStart(virCHDriver *driver, return -1; } + if (virCHProcessPrepareDomain(vm) < 0) { + return -1; + } + if (!priv->monitor) { /* And we can get the first monitor connection now too */ if (!(priv->monitor = virCHProcessConnectMonitor(driver, vm))) { diff --git a/src/ch/meson.build b/src/ch/meson.build index 633966aac7..ca1291c158 100644 --- a/src/ch/meson.build +++ b/src/ch/meson.build @@ -13,6 +13,8 @@ ch_driver_sources = [ 'ch_monitor.h', 'ch_process.c', 'ch_process.h', + 'ch_hostdev.c', + 'ch_hostdev.h', ] driver_source_files += files(ch_driver_sources)