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) {
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;
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)
{
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;
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)
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