diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 1a7de00704..670fd2881e 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -160,8 +160,15 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDef *dev, if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) - pcisrc->driver.name = VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN; + pcisrc->driver.name != VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT && + pcisrc->driver.name != VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN) { + + /* Xen only supports "Xen" style of hostdev */ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("XEN does not support device assignment mode '%1$s'"), + virDeviceHostdevPCIDriverNameTypeToString(pcisrc->driver.name)); + return -1; + } } if (dev->type == VIR_DOMAIN_DEVICE_VIDEO) { @@ -986,18 +993,9 @@ libxlNetworkPrepareDevices(virDomainDef *def) if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV && net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { /* Each type='hostdev' network device must also have a - * corresponding entry in the hostdevs array. For netdevs - * that are hardcoded as type='hostdev', this is already - * done by the parser, but for those allocated from a - * network / determined at runtime, we need to do it - * separately. + * corresponding entry in the hostdevs array. */ virDomainHostdevDef *hostdev = virDomainNetGetActualHostdev(net); - virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci; - - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->driver.name = VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN; if (virDomainHostdevInsert(def, hostdev) < 0) return -1; @@ -1007,6 +1005,54 @@ libxlNetworkPrepareDevices(virDomainDef *def) return 0; } + +static int +libxlHostdevPrepareDevices(virDomainDef *def) +{ + size_t i; + + for (i = 0; i < def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = def->hostdevs[i]; + virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci; + + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && + pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) { + + + pcisrc->driver.name = VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN; + + /* Q: Why do we set an explicit driver.name here even + * though Xen (currently) only supports one driver.name for + * PCI hostdev assignment? + * + * A: Setting the driver name *in the domain XML config* + * is optional (and actually pointless at the time of + * writing, since each hypervisor only supports a single + * type of PCI hostdev device assignment). But the + * hypervisor-agnostic virHostdevPrepareDomainDevices(), + * which is called immediately after this function in + * order to do any driver-related setup (e.g. bind the + * host device to a driver kernel driver), requires that + * the driver.name be explicitly set (otherwise it wouldn't + * know whether to bind to the Xen driver or VFIO driver, + * for example). + * + * NB: If there are ever multiple types of device + * assignment supported by Xen, DO NOT CHANGE the value of + * driver.name set above when the config is "default" to + * anything other than "xen", unless the guest ABI of the + * new type is compatible with that of current "xen" + * device assignment. + * + */ + } + } + + return 0; +} + + static void libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void *for_callback) { @@ -1174,6 +1220,9 @@ libxlDomainStartPrepare(libxlDriverPrivate *driver, if (libxlNetworkPrepareDevices(vm->def) < 0) goto error; + if (libxlHostdevPrepareDevices(vm->def) < 0) + goto error; + if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_INTERNAL_NAME, vm->def, hostdev_flags) < 0) goto error; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 29fbc823dd..6c843b9054 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3087,6 +3087,22 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivate *driver, VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1); + /* The only supported driverType for Xen is + * VIR_DOMAIN_HOSTDEV_PCI_DRIVER_TYPE_XEN, which normally isn't + * set in the config (because it doesn't need to be), but it does + * need to be set for the impending call to + * virHostdevPreparePCIDevices() + */ + if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) + pcisrc->driver.name = VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN; + + if (pcisrc->driver.name != VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("XEN does not support device assignment mode '%1$s'"), + virDeviceHostdevPCIDriverNameTypeToString(pcisrc->driver.name)); + goto cleanup; + } + if (virHostdevPreparePCIDevices(hostdev_mgr, LIBXL_DRIVER_INTERNAL_NAME, vm->def->name, vm->def->uuid, &hostdev, 1, 0) < 0) @@ -3395,15 +3411,6 @@ libxlDomainAttachNetDevice(libxlDriverPrivate *driver, if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { virDomainHostdevDef *hostdev = virDomainNetGetActualHostdev(net); - virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci; - - /* For those just allocated from a network pool whose driver type is - * still VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT, we need to set - * driver name correctly. - */ - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->driver.name = VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_XEN; /* This is really a "smart hostdev", so it should be attached * as a hostdev (the hostdev code will reach over into the diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.xml b/tests/libxlxml2domconfigdata/moredevs-hvm.xml index 89ad80631d..64eeeff889 100644 --- a/tests/libxlxml2domconfigdata/moredevs-hvm.xml +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.xml @@ -43,7 +43,6 @@ -
diff --git a/tests/xlconfigdata/test-fullvirt-pci.xml b/tests/xlconfigdata/test-fullvirt-pci.xml index 75aa6ac25b..6826d14b9e 100644 --- a/tests/xlconfigdata/test-fullvirt-pci.xml +++ b/tests/xlconfigdata/test-fullvirt-pci.xml @@ -37,13 +37,11 @@ -
-
diff --git a/tests/xmconfigdata/test-pci-dev-syntax.xml b/tests/xmconfigdata/test-pci-dev-syntax.xml index 5d5d29c61c..1d5d857072 100644 --- a/tests/xmconfigdata/test-pci-dev-syntax.xml +++ b/tests/xmconfigdata/test-pci-dev-syntax.xml @@ -55,13 +55,11 @@ -
-
diff --git a/tests/xmconfigdata/test-pci-devs.xml b/tests/xmconfigdata/test-pci-devs.xml index 5d5d29c61c..1d5d857072 100644 --- a/tests/xmconfigdata/test-pci-devs.xml +++ b/tests/xmconfigdata/test-pci-devs.xml @@ -55,13 +55,11 @@ -
-