[libvirt PATCH 00/15] Support for VFIO variant drivers, Part 2

Part 1 (which simply made it possible to use virsh nodedev-detach to bind a device to a manually-specified variant driver, and at guest runtime allowed libvirt to ignore the fact that the driver found to the device was something other than exactly "vfio-pci") was here: https://listman.redhat.com/archives/libvir-list/2023-August/241338.html and pushed upstream as of commit v9.6.0-153-g24beaffec3 Part 2 adds two new pieces of functionality: 1) It is possible to manually specify a VFIO variant driver (or force the generic vfio-pci driver) for a device in the domain XML with, e.g.: <driver name='mlx5_vfio_pci'/> (for the former) or: <driver name='vfio-pci'/> (for the latter). 2) By default libvirt will now find the "best match" VFIO or VFIO variant driver by comparing the device's modalias file contents (in sysfs) with vfio drivers found in the running kernel's modules.alias file. This means that "virsh nodedev-detach" of a host device will bind it to its appropriate VFIO variant driver (if one is available), and also if a <hostdev> decice in a domain config has "managed='yes'", libvirt will bind it to a variant driver if possible (in order to force binding to the basic vfio-pci driver instead, you just need to add the <driver> element mentioned above). The first 12 patches are all just getting (1) going (a lot of it is refactoring code to use common code for the four places that use the hostdev <driver> element), and the final 3 patches implement (2). More details are spread along the way. Laine Stump (15): util: properly deal with module vs. driver when binding device to driver schema: consolidate RNG for all hostdev <driver> elements conf: move/rename hostdev PCI driver type enum to device_conf.h conf: normalize hostdev <driver> parsing to simplify adding new attr conf: put hostdev PCI backend into a struct conf: use virDeviceHostdevPCIDriverInfo in network and networkport objects conf: split out hostdev <driver> parse/format to their own functions conf: use new common parser/formatter for hostdev driver in network XML tests: remove explicit <driver name='vfio'/> from hostdev test cases xen: explicitly set hostdev driver.type at runtime, not in postparse conf: replace virHostdevIsVFIODevice with virHostdevIsPCIDevice conf: support manually specifying VFIO variant driver in <hostdev> XML util: new function virStringSkipToSpace() util: new function virPCIDeviceFindBestVFIOVariant() qemu: automatically bind to a vfio variant driver, if available src/conf/device_conf.c | 75 +++ src/conf/device_conf.h | 27 ++ src/conf/domain_capabilities.c | 2 +- src/conf/domain_capabilities.h | 2 +- src/conf/domain_conf.c | 98 +--- src/conf/domain_conf.h | 18 +- src/conf/network_conf.c | 44 +- src/conf/network_conf.h | 17 +- src/conf/schemas/basictypes.rng | 20 + src/conf/schemas/domaincommon.rng | 173 ++++--- src/conf/schemas/network.rng | 10 +- src/conf/schemas/networkport.rng | 10 +- src/conf/virconftypes.h | 2 + src/conf/virnetworkportdef.c | 23 +- src/conf/virnetworkportdef.h | 4 +- src/hypervisor/virhostdev.c | 16 +- src/hypervisor/virhostdev.h | 2 - src/libvirt_private.syms | 8 +- src/libxl/libxl_capabilities.c | 2 +- src/libxl/libxl_domain.c | 65 ++- src/libxl/libxl_driver.c | 25 +- src/network/bridge_driver.c | 2 +- src/qemu/qemu_capabilities.c | 4 +- src/qemu/qemu_command.c | 14 +- src/qemu/qemu_domain.c | 29 +- src/qemu/qemu_hostdev.c | 2 +- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_validate.c | 6 +- src/security/security_apparmor.c | 2 +- src/security/security_dac.c | 4 +- src/security/security_selinux.c | 4 +- src/security/virt-aa-helper.c | 8 +- src/util/virpci.c | 434 ++++++++++++++++-- src/util/virpci.h | 2 + src/util/virstring.c | 17 + src/util/virstring.h | 1 + tests/domaincapstest.c | 4 +- tests/libxlxml2domconfigdata/moredevs-hvm.xml | 1 - tests/networkxml2xmlin/hostdev-pf-old.xml | 8 + tests/networkxml2xmlin/hostdev-pf.xml | 2 +- tests/networkxml2xmlout/hostdev-pf-old.xml | 8 + tests/networkxml2xmlout/hostdev-pf.xml | 2 +- tests/networkxml2xmltest.c | 6 + .../qemuhotplug-hostdev-pci.xml | 1 - .../qemuhotplug-base-live+hostdev-pci.xml | 2 +- ...uhotplug-pseries-base-live+hostdev-pci.xml | 2 +- tests/qemustatusxml2xmldata/modern-in.xml | 2 +- .../hostdev-pci-address-unassigned.xml | 4 - .../hostdev-pci-multifunction.xml | 7 - .../hostdev-vfio-multidomain.xml | 1 - .../hostdev-vfio-zpci-autogenerate-fids.xml | 2 - .../hostdev-vfio-zpci-autogenerate-uids.xml | 2 - .../hostdev-vfio-zpci-autogenerate.xml | 1 - .../hostdev-vfio-zpci-boundaries.xml | 2 - .../hostdev-vfio-zpci-ccw-memballoon.xml | 1 - .../hostdev-vfio-zpci-duplicate.xml | 2 - ...ostdev-vfio-zpci-invalid-uid-valid-fid.xml | 1 - .../hostdev-vfio-zpci-multidomain-many.xml | 8 - .../hostdev-vfio-zpci-set-zero.xml | 1 - .../hostdev-vfio-zpci-uid-set-zero.xml | 1 - .../hostdev-vfio-zpci-wrong-arch.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio-zpci.xml | 1 - .../hostdev-vfio.x86_64-latest.args | 5 +- tests/qemuxml2argvdata/hostdev-vfio.xml | 19 +- .../net-hostdev-vfio-multidomain.xml | 1 - tests/qemuxml2argvdata/net-hostdev-vfio.xml | 1 - tests/qemuxml2argvdata/pseries-hostdevs-1.xml | 3 - tests/qemuxml2argvdata/pseries-hostdevs-2.xml | 2 - tests/qemuxml2argvdata/pseries-hostdevs-3.xml | 2 - ...v-pci-address-unassigned.x86_64-latest.xml | 4 - ...ostdev-pci-multifunction.x86_64-latest.xml | 7 - ...io-zpci-autogenerate-fids.s390x-latest.xml | 2 - ...io-zpci-autogenerate-uids.s390x-latest.xml | 2 - ...ev-vfio-zpci-autogenerate.s390x-latest.xml | 1 - ...tdev-vfio-zpci-boundaries.s390x-latest.xml | 2 - ...-vfio-zpci-ccw-memballoon.s390x-latest.xml | 1 - ...fio-zpci-multidomain-many.s390x-latest.xml | 8 - .../hostdev-vfio-zpci.s390x-latest.xml | 1 - .../hostdev-vfio.x86_64-latest.xml | 24 +- .../net-hostdev-vfio.x86_64-latest.xml | 1 - .../pseries-hostdevs-1.ppc64-latest.xml | 3 - .../pseries-hostdevs-2.ppc64-latest.xml | 2 - .../pseries-hostdevs-3.ppc64-latest.xml | 2 - tests/virhostdevtest.c | 2 +- .../plug-hostdev-pci-unmanaged.xml | 2 +- .../plug-hostdev-pci.xml | 2 +- tests/xlconfigdata/test-fullvirt-pci.xml | 2 - tests/xmconfigdata/test-pci-dev-syntax.xml | 2 - tests/xmconfigdata/test-pci-devs.xml | 2 - tools/virsh-completer-nodedev.c | 4 +- 90 files changed, 875 insertions(+), 481 deletions(-) create mode 100644 tests/networkxml2xmlin/hostdev-pf-old.xml create mode 100644 tests/networkxml2xmlout/hostdev-pf-old.xml -- 2.41.0

Historically libvirt has treated the concept of "loadable kernel module" and "device driver" as being effectively the same (at least in the case of the vfio-pci driver used for VFIO device assignment). The code assumed that a module named "vfio-pci" implemented a driver named "vfio-pci". In reality, the module is named "vfio_pci", and it implements a device driver named "vfio-pci" (note the difference in separator characters), and our code worked only because the modprobe utility we use to load the module will always "normalize" the module name it's given by replacing all "-" (dash) with "_" (underscore) (this has been verified in the modprobe source, which is in the kmod package - there are 3 separate functions that perform this same operation!). So even though we asked modprobe to load the "vfio-pci" module, it would actually load the "vfio_pci" module. After loading the module with modprobe, libvirt then looks for the desired *driver* to be present in sysfs, by looking for the directory /sys/bus/pci/drivers/${driverName}, which would succeed because we were still looking for the original "dash version" of the name ("vfio-pci"). When we recently gained the ability to manually specify a driver to bind to with virsh nodedev-detach, the fragility of this system became apparent - if a user gives the driver name as "vfio_pci", then we would modprobe the module, but then erroneously believe it hadn't been loaded because /sys/bus/pci/drivers/vfio_pci didn't exist. For manual specification of the driver name, this could be dealt with by telling the user "always use the correct name for the driver, don't assume that it is the same as the modulename", but it would still end up confusing people, especially since some drivers do use underscore in their name (e.g. the mlx5_vfio_pci driver/module). More more importantly, when we begin looking in the modules.alias file for the "best" VFIO variant driver for a particular device (in an upcoming patch), that lookup will provide us with the name of a *module*, not a driver, and 3 of the 4 examples of vfio-pci/variant drivers I have access to use underscore in the module name and dash in the driver, while the 4th uses underscore in both, so 3 out of 4 fail with the current code. To make the current code more forgiving (and yet more correct!), as well as to make the upcoming variant auto-selection actually useful, this patch follows the following steps: 1) if the requested driver (${driverName}) is present in sysfs drivers list (/sys/bus/pci/drivers/${driverName}) then use ${driverName} - DONE 2) if underscored(${driverName}) (call it ${underName} for short) is in sysfs drivers list then use ${underName} - DONE 3) if ${underName} *isn't* in the sysfs modules list (/sys/module/${underName}) then "modprobe ${underName}" to load it. 4) look for the PCI driver implemented by this module, it will be at /sys/module/${underName}/driver/pci:${newName}. 5) use ${newName} - DONE. A few notes: a) This will *always* replace dash with underscore in the name used to load the module, which seems it could be problematic, but I have verified this is what modprobe itself does, so I don't think there will ever be a module with "-" in its name as modprobe would be unable to load it (the same can't be said for drivers though!) b) The one case where the above steps wouldn't work would be if someone implemented a driver within a module where the driver and module had names that differed other than dash vs. underscore. I haven't seen an example of this, so the convention seems to be that they will "match" (modulo - & _). If this mismatch were to ever occur, though, it could be worked around by simply loading the module out-of-band during the host system startup, and then using the driver's name in the config. c) All of this is conveniently ignoring the possibility of a VFIO variant driver that is statically linked in the kernel. The entire design of variant driver auto-detection is based on doing a lookup in modules.alias, and that only lists *loadable modules* (not drivers), so unless I'm missing something, it would be impossible to auto-detect a VFIO variant driver that was statically linked. This is beyond libvirt's ability to fix; the best that could be done would be to manually specify the driver name in the libvirt config, which I suppose is better than nothing :-) Signed-off-by: Laine Stump <laine@redhat.com> --- src/util/virpci.c | 195 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 165 insertions(+), 30 deletions(-) diff --git a/src/util/virpci.c b/src/util/virpci.c index baacde4c14..513ae948c0 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -221,6 +221,13 @@ virPCIDriverDir(const char *driver) } +static char * +virPCIModuleDir(const char *module) +{ + return g_strdup_printf("/sys/module/%s", module); +} + + static char * virPCIFile(const char *device, const char *file) { @@ -1153,44 +1160,168 @@ virPCIDeviceReset(virPCIDevice *dev, } +/** + * virPCINameDashToUnderscore: + * @path: the module/driver name or path - will be directly modified + * + * Replace all occurences of "-" with "_" in the name + * part of the path (everything after final "/" + * + * return true if any change was made, otherwise false. + */ static int -virPCIProbeDriver(const char *driverName) +virPCINameDashToUnderscore(char *path) { - g_autofree char *drvpath = NULL; + bool changed = false; + char *tmp = strrchr(path, '/'); + + if (!tmp) + tmp = path; + + while (*tmp) { + if (*tmp == '-') { + *tmp = '_'; + changed = true; + } + tmp++; + } + + return changed; +} + + +static int +virPCIProbeModule(const char *moduleName) +{ + g_autofree char *modulePath = NULL; g_autofree char *errbuf = NULL; - drvpath = virPCIDriverDir(driverName); + modulePath = virPCIModuleDir(moduleName); /* driver previously loaded, return */ - if (virFileExists(drvpath)) + if (virFileExists(modulePath)) return 0; - if ((errbuf = virKModLoad(driverName))) { - VIR_WARN("failed to load driver %s: %s", driverName, errbuf); - goto cleanup; + if ((errbuf = virKModLoad(moduleName))) { + /* If we know failure was because of admin config, let's report that; + * otherwise, report a more generic failure message + */ + if (virKModIsProhibited(moduleName)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to load PCI driver module %1$s: administratively prohibited"), + moduleName); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to load PCI driver module %1$s: %2$s"), + moduleName, errbuf); + } + return -1; } /* driver loaded after probing */ - if (virFileExists(drvpath)) + if (virFileExists(modulePath)) return 0; - cleanup: - /* If we know failure was because of admin config, let's report that; - * otherwise, report a more generic failure message + virReportError(VIR_ERR_INTERNAL_ERROR, + _("modprobe reported success loading module '%1$s', but module is missing from /sys/module"), + moduleName); + return -1; +} + +/** + * virPCIDeviceFindDriver: + * @dev: initialized virPCIDevice, including desired stubDriverName + * + * Checks if there is a driver named @dev->stubDriverName already + * loaded. If there is, we're done. If not, look for a driver with + * that same name, except with dashes replaced with underscores. + + * If neither of the above is found, then look for/load the module of + * the underscored version of the name, and follow the links from + * /sys/module/$name/drivers/pci:* to the PCI driver associated with that + * module, and update @dev->stubDriverName with that name. + * + * On a successful return, @dev->stubDriverName will be updated with + * the proper name for the driver, and that driver will be loaded. + * + * returns 0 on success, -1 on failure + */ +static int +virPCIDeviceFindDriver(virPCIDevice *dev) +{ + g_autofree char *driverPath = virPCIDriverDir(dev->stubDriverName); + g_autofree char *errbuf = NULL; + g_autofree char *moduleName = NULL; + g_autofree char *moduleDriversDir = NULL; + g_autoptr(DIR) dir = NULL; + struct dirent *ent; + int direrr; + + /* unchanged stubDriverName */ + if (virFileExists(driverPath)) + return 0; + + /* try replacing "-" with "_" */ + if (virPCINameDashToUnderscore(driverPath) + && virFileExists(driverPath)) { + + /* update original name in dev */ + virPCINameDashToUnderscore(dev->stubDriverName); + return 0; + } + + /* look for a module with this name (but always replacing + * "-" with "_", since that's what modprobe does) */ - if (virKModIsProhibited(driverName)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to load PCI driver module %1$s: administratively prohibited"), - driverName); - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to load PCI driver module %1$s"), - driverName); + + moduleName = g_strdup(dev->stubDriverName); + virPCINameDashToUnderscore(moduleName); + + if (virPCIProbeModule(moduleName) < 0) + return -1; + + /* module was found/loaded. Now find the PCI driver it implements, + * linked to by /sys/module/$moduleName/drivers/pci:$driverName + */ + + moduleDriversDir = g_strdup_printf("/sys/module/%s/drivers", moduleName); + + if (virDirOpen(&dir, moduleDriversDir) < 0) + return -1; + + while ((direrr = virDirRead(dir, &ent, moduleDriversDir))) { + + if (STRPREFIX(ent->d_name, "pci:")) { + /* this is the link to the driver we want */ + + g_autofree char *drvName = NULL; + g_autofree char *drvPath = NULL; + + /* extract the driver name from the link name */ + drvName = g_strdup(ent->d_name + strlen("pci:")); + + /* make sure that driver is actually loaded */ + drvPath = virPCIDriverDir(drvName); + if (!virFileExists(drvPath)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("pci driver '%1$s' supposedly loaded by module '%2$s' not found in sysfs"), + drvName, moduleName); + return -1; + } + + g_free(dev->stubDriverName); + dev->stubDriverName = g_steal_pointer(&drvName); + return 0; + } } + virReportError(VIR_ERR_INTERNAL_ERROR, + _("module '%1$s' does not implement any pci driver"), + moduleName); return -1; } + int virPCIDeviceUnbind(virPCIDevice *dev) { @@ -1290,7 +1421,6 @@ virPCIDeviceUnbindFromStub(virPCIDevice *dev) static int virPCIDeviceBindToStub(virPCIDevice *dev) { - const char *stubDriverName = dev->stubDriverName; g_autofree char *stubDriverPath = NULL; g_autofree char *driverLink = NULL; @@ -1302,30 +1432,35 @@ virPCIDeviceBindToStub(virPCIDevice *dev) return -1; } - if (!stubDriverName - && !(stubDriverName = virPCIStubDriverTypeToString(dev->stubDriverType))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unknown stub driver configured for PCI device %1$s"), - dev->name); - return -1; + if (!dev->stubDriverName) { + + const char *stubDriverName = NULL; + + if (!(stubDriverName = virPCIStubDriverTypeToString(dev->stubDriverType))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown stub driver configured for PCI device %1$s"), + dev->name); + return -1; + } + dev->stubDriverName = g_strdup(stubDriverName); } - if (virPCIProbeDriver(stubDriverName) < 0) + if (virPCIDeviceFindDriver(dev) < 0) return -1; - stubDriverPath = virPCIDriverDir(stubDriverName); + stubDriverPath = virPCIDriverDir(dev->stubDriverName); driverLink = virPCIFile(dev->name, "driver"); if (virFileExists(driverLink)) { if (virFileLinkPointsTo(driverLink, stubDriverPath)) { /* The device is already bound to the correct driver */ VIR_DEBUG("Device %s is already bound to %s", - dev->name, stubDriverName); + dev->name, dev->stubDriverName); return 0; } } - if (virPCIDeviceBindWithDriverOverride(dev, stubDriverName) < 0) + if (virPCIDeviceBindWithDriverOverride(dev, dev->stubDriverName) < 0) return -1; dev->unbind_from_stub = true; -- 2.41.0

On Mon, Oct 23, 2023 at 12:54:37AM -0400, Laine Stump wrote:
When we recently gained the ability to manually specify a driver to bind to with virsh nodedev-detach, the fragility of this system became apparent - if a user gives the driver name as "vfio_pci", then we would modprobe the module, but then erroneously believe it hadn't been loaded because /sys/bus/pci/drivers/vfio_pci didn't exist. For manual specification of the driver name, this could be dealt with by telling the user "always use the correct name for the driver, don't assume that it is the same as the modulename", but it would still end up confusing people, especially since some drivers do use underscore in their name (e.g. the mlx5_vfio_pci driver/module).
I think you are creating more confusion by allowing this. The driver name from module.alias should be used consistently in its exact format. Log a 'did you mean XYZ" or something if it doesn't work out. Pass the "driver name" directly to modprobe and let it sort it out Forget about modules entirely in the libvirt level, don't even check it.
c) All of this is conveniently ignoring the possibility of a VFIO variant driver that is statically linked in the kernel. The entire design of variant driver auto-detection is based on doing a lookup in modules.alias, and that only lists *loadable modules* (not drivers), so unless I'm missing something, it would be impossible to auto-detect a VFIO variant driver that was statically linked. This is beyond libvirt's ability to fix; the best that could be done would be to manually specify the driver name in the libvirt config, which I suppose is better than nothing :-)
Why? This seems wrong. Statically linked drivers appear in /sys/bus/drivers/XX too Jason

The exact same element can appear in <hostdev> and <interface type='hostdev'>, and nearly identical in <network> and <networkport> (these latter two don't include "xen" as a possible driver, but that's coincidental - there's no reason Xen couldn't also use the VF pools in virtual networks, it just doesn't). This patch modifies all 4 to use the same <ref name="hostdevDriver"/> so that it is simpler to add something new. A side effect of this patch is that the grammar for the <interface> element in domain XML has been tightened up a bit - previously it was accepted by the schema (but nonsensical) to have virtio and network interface options specified; as a part of making the two different <driver> choices each a complete element (rather than each being a collection of attributes and subelements) these extra attributes/subelements that were irrelevant to the hostdev-type <driver> were made to be valid only for an emulated interface's <driver>. Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/schemas/basictypes.rng | 13 +++ src/conf/schemas/domaincommon.rng | 173 ++++++++++++++---------------- src/conf/schemas/network.rng | 10 +- src/conf/schemas/networkport.rng | 10 +- 4 files changed, 94 insertions(+), 112 deletions(-) diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng index 26eb538077..8d5f4475ca 100644 --- a/src/conf/schemas/basictypes.rng +++ b/src/conf/schemas/basictypes.rng @@ -656,4 +656,17 @@ </choice> </define> + <define name="hostdevDriver"> + <element name="driver"> + <attribute name="name"> + <choice> + <value>kvm</value> + <value>vfio</value> + <value>xen</value> + </choice> + </attribute> + <empty/> + </element> + </define> + </grammar> diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index a26986b5ce..002587db58 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -3759,18 +3759,12 @@ </element> </optional> <optional> - <element name="driver"> - <choice> - <group> - <attribute name="name"> - <choice> - <value>kvm</value> - <value>vfio</value> - <value>xen</value> - </choice> - </attribute> - </group> - <group> + <choice> + <group> + <ref name="hostdevDriver"/> + </group> + <group> + <element name="driver"> <optional> <attribute name="name"> <choice> @@ -3808,90 +3802,90 @@ <optional> <ref name="event_idx"/> </optional> - </group> - </choice> - <ref name="virtioOptions"/> - <interleave> - <optional> - <element name="host"> - <optional> - <attribute name="csum"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="gso"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="tso4"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="tso6"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="ecn"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="ufo"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="mrg_rxbuf"> - <ref name="virOnOff"/> - </attribute> - </optional> - </element> - </optional> - <optional> - <element name="guest"> - <optional> - <attribute name="csum"> - <ref name="virOnOff"/> - </attribute> - </optional> + <ref name="virtioOptions"/> + <interleave> <optional> - <attribute name="tso4"> - <ref name="virOnOff"/> - </attribute> + <element name="host"> + <optional> + <attribute name="csum"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="gso"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="tso4"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="tso6"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ecn"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ufo"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="mrg_rxbuf"> + <ref name="virOnOff"/> + </attribute> + </optional> + </element> </optional> <optional> - <attribute name="tso6"> - <ref name="virOnOff"/> - </attribute> + <element name="guest"> + <optional> + <attribute name="csum"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="tso4"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="tso6"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ecn"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ufo"> + <ref name="virOnOff"/> + </attribute> + </optional> + </element> </optional> <optional> - <attribute name="ecn"> + <attribute name="rss"> <ref name="virOnOff"/> </attribute> </optional> <optional> - <attribute name="ufo"> + <attribute name="rss_hash_report"> <ref name="virOnOff"/> </attribute> </optional> - </element> - </optional> - <optional> - <attribute name="rss"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="rss_hash_report"> - <ref name="virOnOff"/> - </attribute> - </optional> - </interleave> - </element> + </interleave> + </element> + </group> + </choice> </optional> <optional> <ref name="alias"/> @@ -6182,16 +6176,7 @@ </attribute> <interleave> <optional> - <element name="driver"> - <attribute name="name"> - <choice> - <value>kvm</value> - <value>vfio</value> - <value>xen</value> - </choice> - </attribute> - <empty/> - </element> + <ref name="hostdevDriver"/> </optional> <optional> <ref name="teaming"/> diff --git a/src/conf/schemas/network.rng b/src/conf/schemas/network.rng index cda174ab4b..e56e07d130 100644 --- a/src/conf/schemas/network.rng +++ b/src/conf/schemas/network.rng @@ -179,15 +179,7 @@ </element> </optional> <optional> - <element name="driver"> - <attribute name="name"> - <choice> - <value>kvm</value> - <value>vfio</value> - </choice> - </attribute> - <empty/> - </element> + <ref name="hostdevDriver"/> </optional> <optional> <element name="nat"> diff --git a/src/conf/schemas/networkport.rng b/src/conf/schemas/networkport.rng index 14db949578..50995559e8 100644 --- a/src/conf/schemas/networkport.rng +++ b/src/conf/schemas/networkport.rng @@ -145,15 +145,7 @@ </optional> <interleave> <optional> - <element name="driver"> - <attribute name="name"> - <choice> - <value>kvm</value> - <value>vfio</value> - </choice> - </attribute> - <empty/> - </element> + <ref name="hostdevDriver"/> </optional> <element name="address"> <ref name="pciaddress"/> -- 2.41.0

Currently this enum is defined in domain_conf.h and named virDomainHostdevSubsysPCIDriverType. I want to use it in parts of the network and networkport config, so am moving its definition to device_conf.h which is / can be included by all interested parties, and renaming it to be less specific to its old usage (all the other parts still apply, at least functionally, to the new usage). The name change (which includes enum values) does cause a lot of churn, but it's all mechanical. Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/device_conf.c | 9 +++++++++ src/conf/device_conf.h | 12 +++++++++++ src/conf/domain_capabilities.c | 2 +- src/conf/domain_capabilities.h | 2 +- src/conf/domain_conf.c | 34 +++++++++++++------------------- src/conf/domain_conf.h | 14 +------------ src/hypervisor/virhostdev.c | 8 ++++---- src/libvirt_private.syms | 2 +- src/libxl/libxl_capabilities.c | 2 +- src/libxl/libxl_domain.c | 6 +++--- src/libxl/libxl_driver.c | 4 ++-- src/qemu/qemu_capabilities.c | 4 ++-- src/qemu/qemu_command.c | 12 +++++------ src/qemu/qemu_domain.c | 23 ++++++++++----------- src/qemu/qemu_validate.c | 2 +- src/security/security_apparmor.c | 2 +- src/security/security_dac.c | 4 ++-- src/security/security_selinux.c | 4 ++-- src/security/virt-aa-helper.c | 8 +++++--- tests/domaincapstest.c | 4 ++-- tests/virhostdevtest.c | 2 +- tools/virsh-completer-nodedev.c | 4 ++-- 22 files changed, 85 insertions(+), 79 deletions(-) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index f3d977f2b7..25a522671e 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -29,6 +29,15 @@ #define VIR_FROM_THIS VIR_FROM_DEVICE +VIR_ENUM_IMPL(virDeviceHostdevPCIDriver, + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST, + "default", + "kvm", + "vfio", + "xen", +); + + VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "none", diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index a83377417a..7513beb5e1 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -31,6 +31,18 @@ #include "virnetdev.h" #include "virenum.h" +/* the backend driver used for PCI hostdev devices */ +typedef enum { + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT = 0, /* detect automatically, prefer VFIO */ + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM, /* force legacy kvm style */ + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO, /* force vfio */ + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN, /* force legacy xen style, use pciback */ + + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST +} virDeviceHostdevPCIDriverType; + +VIR_ENUM_DECL(virDeviceHostdevPCIDriver); + typedef enum { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE = 0, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 2fa5756184..7915eb443e 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -524,7 +524,7 @@ virDomainCapsDeviceHostdevFormat(virBuffer *buf, ENUM_PROCESS(hostdev, startupPolicy, virDomainStartupPolicyTypeToString); ENUM_PROCESS(hostdev, subsysType, virDomainHostdevSubsysTypeToString); ENUM_PROCESS(hostdev, capsType, virDomainHostdevCapsTypeToString); - ENUM_PROCESS(hostdev, pciBackend, virDomainHostdevSubsysPCIBackendTypeToString); + ENUM_PROCESS(hostdev, pciBackend, virDeviceHostdevPCIDriverTypeToString); FORMAT_EPILOGUE(hostdev); } diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index 01bcfa2e39..25d3672b18 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -99,7 +99,7 @@ STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_MODE_LAST); STATIC_ASSERT_ENUM(VIR_DOMAIN_STARTUP_POLICY_LAST); STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST); STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST); -STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST); +STATIC_ASSERT_ENUM(VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST); typedef struct _virDomainCapsDeviceHostdev virDomainCapsDeviceHostdev; struct _virDomainCapsDeviceHostdev { virTristateBool supported; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 80f467ae7a..523481c92c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1053,13 +1053,6 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, "mdev", ); -VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend, - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST, - "default", - "kvm", - "vfio", - "xen", -); VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol, VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST, @@ -6276,7 +6269,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, driver_node = virXPathNode("./driver", ctxt); if (virXMLPropEnum(driver_node, "name", - virDomainHostdevSubsysPCIBackendTypeFromString, + virDeviceHostdevPCIDriverTypeFromString, VIR_XML_PROP_NONZERO, &pcisrc->backend) < 0) return -1; @@ -23342,8 +23335,9 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf, virBufferAsprintf(&sourceAttrBuf, " writeFiltering='%s'", virTristateBoolTypeToString(def->writeFiltering)); - if (pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { - const char *backend = virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend); + if (pcisrc->backend != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { + const char *backend + = virDeviceHostdevPCIDriverTypeToString(pcisrc->backend); if (!backend) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -29841,17 +29835,17 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDef *iface, switch ((virNetworkForwardDriverNameType)port->plug.hostdevpci.driver) { case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT: actual->data.hostdev.def.source.subsys.u.pci.backend = - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT; + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT; break; case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM: actual->data.hostdev.def.source.subsys.u.pci.backend = - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM; + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM; break; case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO: actual->data.hostdev.def.source.subsys.u.pci.backend = - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; break; case VIR_NETWORK_FORWARD_DRIVER_NAME_LAST: @@ -29962,26 +29956,26 @@ virDomainNetDefActualToNetworkPort(virDomainDef *dom, port->plug.hostdevpci.managed = virTristateBoolFromBool(actual->data.hostdev.def.managed); port->plug.hostdevpci.addr = actual->data.hostdev.def.source.subsys.u.pci.addr; switch (actual->data.hostdev.def.source.subsys.u.pci.backend) { - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT: port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT; break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM: port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_KVM; break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO: port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO; break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Unexpected PCI backend 'xen'")); break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST: default: - virReportEnumRangeError(virDomainHostdevSubsysPCIBackendType, + virReportEnumRangeError(virDeviceHostdevPCIDriverType, actual->data.hostdev.def.source.subsys.u.pci.backend); return NULL; } @@ -30926,7 +30920,7 @@ virHostdevIsVFIODevice(const virDomainHostdevDef *hostdev) { return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + hostdev->source.subsys.u.pci.backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9e6dd930fa..d56ed32a69 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -201,18 +201,6 @@ typedef enum { VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST } virDomainHostdevSubsysType; -/* the backend driver used for PCI hostdev devices */ -typedef enum { - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT = 0, /* detect automatically, prefer VFIO */ - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM, /* force legacy kvm style */ - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO, /* force vfio */ - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN, /* force legacy xen style, use pciback */ - - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST -} virDomainHostdevSubsysPCIBackendType; - -VIR_ENUM_DECL(virDomainHostdevSubsysPCIBackend); - typedef enum { VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE, VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI, @@ -247,7 +235,7 @@ struct _virDomainHostdevSubsysUSB { struct _virDomainHostdevSubsysPCI { virPCIDeviceAddress addr; /* host address */ - virDomainHostdevSubsysPCIBackendType backend; + virDeviceHostdevPCIDriverType backend; virBitmap *origstates; }; diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c index 4672bd8785..ce7189ffcd 100644 --- a/src/hypervisor/virhostdev.c +++ b/src/hypervisor/virhostdev.c @@ -243,14 +243,14 @@ virHostdevGetPCIHostDevice(const virDomainHostdevDef *hostdev, virPCIDeviceSetManaged(actual, hostdev->managed); - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { virPCIDeviceSetStubDriverType(actual, VIR_PCI_STUB_DRIVER_VFIO); - } else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN) { + } else if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN) { virPCIDeviceSetStubDriverType(actual, VIR_PCI_STUB_DRIVER_XEN); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("pci backend driver '%1$s' is not supported"), - virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend)); + _("pci backend driver type '%1$s' is not supported"), + virDeviceHostdevPCIDriverTypeToString(pcisrc->backend)); return -1; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 553b01b8c0..479a69ed0b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -126,6 +126,7 @@ virCPUModeTypeToString; # conf/device_conf.h virCCWDeviceAddressParseXML; +virDeviceHostdevPCIDriverTypeToString; virDeviceInfoPCIAddressExtensionIsPresent; virDeviceInfoPCIAddressExtensionIsWanted; virDeviceInfoPCIAddressIsPresent; @@ -467,7 +468,6 @@ virDomainHostdevInsert; virDomainHostdevMatch; virDomainHostdevModeTypeToString; virDomainHostdevRemove; -virDomainHostdevSubsysPCIBackendTypeToString; virDomainHostdevSubsysSCSIVHostModelTypeFromString; virDomainHostdevSubsysSCSIVHostModelTypeToString; virDomainHostdevSubsysTypeToString; diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c index 177e8b988e..28330c4d36 100644 --- a/src/libxl/libxl_capabilities.c +++ b/src/libxl/libxl_capabilities.c @@ -631,7 +631,7 @@ libxlMakeDomainDeviceHostdevCaps(virDomainCapsDeviceHostdev *dev) virDomainCapsEnumClear(&dev->pciBackend); VIR_DOMAIN_CAPS_ENUM_SET(dev->pciBackend, - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN); + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN); return 0; } diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 0c4beffd6a..904f40914c 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -160,8 +160,8 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDef *dev, if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) - pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN; + pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) + pcisrc->backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; } if (dev->type == VIR_DOMAIN_DEVICE_VIDEO) { @@ -997,7 +997,7 @@ libxlNetworkPrepareDevices(virDomainDef *def) if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN; + pcisrc->backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; if (virDomainHostdevInsert(def, hostdev) < 0) return -1; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index c98d2d737a..d04ec7f6ea 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3398,12 +3398,12 @@ libxlDomainAttachNetDevice(libxlDriverPrivate *driver, virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci; /* For those just allocated from a network pool whose backend is - * still VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT, we need to set + * still VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT, we need to set * backend correctly. */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN; + pcisrc->backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_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/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 83119e871a..a5e2681ea1 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -6352,8 +6352,8 @@ virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCaps *qemuCaps, if (supportsPassthroughVFIO && virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend, - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT, - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO); + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT, + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO); } } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d40d3a4e13..fcb4e31502 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4732,16 +4732,16 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, /* caller has to assign proper passthrough backend type */ switch (pcisrc->backend) { - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO: break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN: - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST: virReportError(VIR_ERR_INTERNAL_ERROR, _("invalid PCI passthrough type '%1$s'"), - virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend)); + virDeviceHostdevPCIDriverTypeToString(pcisrc->backend)); return NULL; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 995aa3f79c..d57932b681 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -10568,7 +10568,7 @@ qemuDomainGetHostdevPath(virDomainHostdevDef *dev, case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS: switch (dev->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&pcisrc->addr))) return -1; @@ -11332,14 +11332,15 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev, virQEMUCaps *qemuCaps) { bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); - virDomainHostdevSubsysPCIBackendType *backend = &hostdev->source.subsys.u.pci.backend; + virDeviceHostdevPCIDriverType *driverType + = &hostdev->source.subsys.u.pci.backend; /* assign defaults for hostdev passthrough */ - switch (*backend) { - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: + switch (*driverType) { + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT: if (supportsPassthroughVFIO) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { - *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + *driverType = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("VFIO PCI device assignment is not supported by this version of QEMU")); @@ -11352,7 +11353,7 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev, } break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO: if (!supportsPassthroughVFIO) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("host doesn't support VFIO PCI passthrough")); @@ -11360,20 +11361,20 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev, } break; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("host doesn't support legacy PCI passthrough")); return false; - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN: + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("QEMU does not support device assignment mode '%1$s'"), - virDomainHostdevSubsysPCIBackendTypeToString(*backend)); + virDeviceHostdevPCIDriverTypeToString(*driverType)); return false; default: - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: - virReportEnumRangeError(virDomainHostdevSubsysPCIBackendType, *backend); + case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST: + virReportEnumRangeError(virDeviceHostdevPCIDriverType, *driverType); break; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 93df9e4c8e..83365f6685 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2464,7 +2464,7 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: backend = hostdev->source.subsys.u.pci.backend; - if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("VFIO PCI device assignment is not supported by this version of qemu")); diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 6fd0aedacf..515d68ec6b 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -869,7 +869,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr, if (!pci) goto done; - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) { diff --git a/src/security/security_dac.c b/src/security/security_dac.c index c07e488db7..ff28e17136 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1257,7 +1257,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) @@ -1418,7 +1418,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 84c5ce75ed..89ceaf48d7 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2201,7 +2201,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) @@ -2437,7 +2437,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index be13979cef..ac4225a783 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1092,9 +1092,11 @@ get_files(vahControl * ctl) case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: { virPCIDevice *pci = virPCIDeviceNew(&dev->source.subsys.u.pci.addr); - virDomainHostdevSubsysPCIBackendType backend = dev->source.subsys.u.pci.backend; - if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO || - backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { + virDeviceHostdevPCIDriverType driverType + = dev->source.subsys.u.pci.backend; + + if (driverType == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO || + driverType == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { needsVfio = true; } diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index c4a4508430..3d86bdb9c7 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -109,8 +109,8 @@ fillQemuCaps(virDomainCaps *domCaps, * successfully mocked as they are not exposed as internal APIs. Therefore, * instead of mocking set the expected values here by hand. */ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->hostdev.pciBackend, - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT, - VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO); + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT, + VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO); /* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which * may not exists everywhere. */ diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c index 04e6c00908..d9ff992e91 100644 --- a/tests/virhostdevtest.c +++ b/tests/virhostdevtest.c @@ -134,7 +134,7 @@ myInit(void) subsys->u.pci.addr.bus = 0; subsys->u.pci.addr.slot = i + 1; subsys->u.pci.addr.function = 0; - subsys->u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; + subsys->u.pci.backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; } for (i = 0; i < nhostdevs; i++) { diff --git a/tools/virsh-completer-nodedev.c b/tools/virsh-completer-nodedev.c index d743df460e..1518395a1e 100644 --- a/tools/virsh-completer-nodedev.c +++ b/tools/virsh-completer-nodedev.c @@ -110,6 +110,6 @@ virshNodeDevicePCIBackendCompleter(vshControl *ctl G_GNUC_UNUSED, { virCheckFlags(0, NULL); - return virshEnumComplete(VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST, - virDomainHostdevSubsysPCIBackendTypeToString); + return virshEnumComplete(VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST, + virDeviceHostdevPCIDriverTypeToString); } -- 2.41.0

The hostdev version of the <driver> subelement appears in four places: * The domain XML in the <hostdev> and <interface type='hostdev'> elements (that's 2) * The network XML inside <forward> when the network is a pool of SRIOV VFs * the <networkport> XML, which is used to communicate between the hypervisor driver and network driver. In order to make the pending addition of a new attribute to <driver> in all these cases simpler, this patch refactors the parsing of <driver> in all four places to use virXMLProp*() and virXMLFormatElement(). Making all of the different instances of the separate parse/format for <driver> look nearly identical will make it easier to see that the upcoming patch that converges all four to use a common parser/formatter is a functional NOP. Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/domain_conf.c | 28 ++++++++++++++++------------ src/conf/network_conf.c | 26 ++++++++++++-------------- src/conf/network_conf.h | 2 +- src/conf/virnetworkportdef.c | 28 ++++++++++++++++++---------- src/conf/virnetworkportdef.h | 2 +- 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 523481c92c..6dde17ded3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6267,13 +6267,14 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, if (virDomainHostdevSubsysPCIDefParseXML(sourcenode, ctxt, def, flags) < 0) return -1; - driver_node = virXPathNode("./driver", ctxt); - if (virXMLPropEnum(driver_node, "name", - virDeviceHostdevPCIDriverTypeFromString, - VIR_XML_PROP_NONZERO, - &pcisrc->backend) < 0) - return -1; - + if ((driver_node = virXPathNode("./driver", ctxt))) { + if (virXMLPropEnum(driver_node, "name", + virDeviceHostdevPCIDriverTypeFromString, + VIR_XML_PROP_NONZERO, + &pcisrc->backend) < 0) { + return -1; + } + } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: @@ -23327,14 +23328,11 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf, unsigned int flags, bool includeTypeInAddr) { + g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci; - if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) - virBufferAsprintf(&sourceAttrBuf, " writeFiltering='%s'", - virTristateBoolTypeToString(def->writeFiltering)); - if (pcisrc->backend != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { const char *backend = virDeviceHostdevPCIDriverTypeToString(pcisrc->backend); @@ -23346,9 +23344,15 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf, return -1; } - virBufferAsprintf(buf, "<driver name='%s'/>\n", backend); + virBufferAsprintf(&driverAttrBuf, " name='%s'", backend); } + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + + if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(&sourceAttrBuf, " writeFiltering='%s'", + virTristateBoolTypeToString(def->writeFiltering)); + virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, includeTypeInAddr); if (pcisrc->origstates && diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 1a6fd86180..b9601cb307 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1334,8 +1334,8 @@ virNetworkForwardDefParseXML(const char *networkName, g_autofree xmlNodePtr *forwardNatNodes = NULL; g_autofree char *forwardDev = NULL; g_autofree char *forwardManaged = NULL; - g_autofree char *forwardDriverName = NULL; g_autofree char *type = NULL; + xmlNodePtr driverNode = NULL; VIR_XPATH_NODE_AUTORESTORE(ctxt) ctxt->node = node; @@ -1356,18 +1356,13 @@ virNetworkForwardDefParseXML(const char *networkName, def->managed = true; } - forwardDriverName = virXPathString("string(./driver/@name)", ctxt); - if (forwardDriverName) { - int driverName - = virNetworkForwardDriverNameTypeFromString(forwardDriverName); - - if (driverName <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown forward <driver name='%1$s'/> in network %2$s"), - forwardDriverName, networkName); + if ((driverNode = virXPathNode("./driver", ctxt))) { + if (virXMLPropEnum(driverNode, "name", + virNetworkForwardDriverNameTypeFromString, + VIR_XML_PROP_NONZERO, + &def->driverName) < 0) { return -1; } - def->driverName = driverName; } /* bridge and hostdev modes can use a pool of physical interfaces */ @@ -2331,6 +2326,7 @@ virNetworkDefFormatBuf(virBuffer *buf, if (def->forward.type != VIR_NETWORK_FORWARD_NONE) { const char *dev = NULL; const char *mode = virNetworkForwardTypeToString(def->forward.type); + g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER; if (!def->forward.npfs) dev = virNetworkDefForwardIf(def, 0); @@ -2361,8 +2357,7 @@ virNetworkDefFormatBuf(virBuffer *buf, virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : ""); virBufferAdjustIndent(buf, 2); - if (def->forward.driverName - != VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT) { + if (def->forward.driverName) { const char *driverName = virNetworkForwardDriverNameTypeToString(def->forward.driverName); if (!driverName) { @@ -2371,8 +2366,11 @@ virNetworkDefFormatBuf(virBuffer *buf, def->forward.driverName); return -1; } - virBufferAsprintf(buf, "<driver name='%s'/>\n", driverName); + virBufferAsprintf(&driverAttrBuf, " name='%s'", driverName); } + + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + if (def->forward.type == VIR_NETWORK_FORWARD_NAT) { if (virNetworkForwardNatDefFormat(buf, &def->forward) < 0) return -1; diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 5a1bdb1284..497ae765f2 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -216,7 +216,7 @@ typedef struct _virNetworkForwardDef virNetworkForwardDef; struct _virNetworkForwardDef { int type; /* One of virNetworkForwardType constants */ bool managed; /* managed attribute for hostdev mode */ - int driverName; /* enum virNetworkForwardDriverNameType */ + virNetworkForwardDriverNameType driverName; /* If there are multiple forward devices (i.e. a pool of * interfaces), they will be listed here. diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c index fc06ef41d5..402c0051ec 100644 --- a/src/conf/virnetworkportdef.c +++ b/src/conf/virnetworkportdef.c @@ -87,10 +87,10 @@ virNetworkPortDefParseXML(xmlXPathContextPtr ctxt) xmlNodePtr addressNode; xmlNodePtr rxfiltersNode = NULL; xmlNodePtr plugNode = NULL; + xmlNodePtr driverNode = NULL; g_autofree char *mac = NULL; g_autofree char *macmgr = NULL; g_autofree char *mode = NULL; - g_autofree char *driver = NULL; def = g_new0(virNetworkPortDef, 1); @@ -223,14 +223,16 @@ virNetworkPortDefParseXML(xmlXPathContextPtr ctxt) VIR_XML_PROP_NONE, &def->plug.hostdevpci.managed) < 0) return NULL; - driver = virXPathString("string(./plug/driver/@name)", ctxt); - if (driver && - (def->plug.hostdevpci.driver = - virNetworkForwardDriverNameTypeFromString(driver)) <= 0) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing network port driver name")); - return NULL; + + if ((driverNode = virXPathNode("./plug/driver", ctxt))) { + if (virXMLPropEnum(driverNode, "name", + virNetworkForwardDriverNameTypeFromString, + VIR_XML_PROP_NONZERO, + &def->plug.hostdevpci.driver) < 0) { + return NULL; + } } + if (!(addressNode = virXPathNode("./plug/address", ctxt))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing network port PCI address")); @@ -319,6 +321,8 @@ virNetworkPortDefFormatBuf(virBuffer *buf, virTristateBoolTypeToString(def->trustGuestRxFilters)); if (def->plugtype != VIR_NETWORK_PORT_PLUG_TYPE_NONE) { + g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER; + virBufferAsprintf(buf, "<plug type='%s'", virNetworkPortPlugTypeToString(def->plugtype)); @@ -351,10 +355,14 @@ virNetworkPortDefFormatBuf(virBuffer *buf, } virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); - if (def->plug.hostdevpci.driver) - virBufferEscapeString(buf, "<driver name='%s'/>\n", + + if (def->plug.hostdevpci.driver) { + virBufferEscapeString(&driverAttrBuf, " name='%s'", virNetworkForwardDriverNameTypeToString( def->plug.hostdevpci.driver)); + } + + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); virPCIDeviceAddressFormat(buf, def->plug.hostdevpci.addr, false); virBufferAdjustIndent(buf, -2); diff --git a/src/conf/virnetworkportdef.h b/src/conf/virnetworkportdef.h index 48e73dbefd..bfe1dae9ea 100644 --- a/src/conf/virnetworkportdef.h +++ b/src/conf/virnetworkportdef.h @@ -69,7 +69,7 @@ struct _virNetworkPortDef { } direct; struct { virPCIDeviceAddress addr; /* PCI Address of device */ - int driver; /* virNetworkForwardDriverNameType */ + unsigned int driver; /* virNetworkForwardDriverNameType */ virTristateBool managed; } hostdevpci; } plug; -- 2.41.0

The new struct is virDeviceHostdevPCIDriverInfo, and the "backend" enum in the hostdevDef will be replaced with a virDeviceHostdevPCIDriverInfo named "driver'. Since the enum value in this new struct is called "type", it means that all references to "backend" will become "driver.type". This will allow easily adding other items for new attributes in the <driver> element / C struct, which will be useful once we are using this new struct in multiple places. Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/device_conf.h | 4 ++++ src/conf/domain_conf.c | 32 ++++++++++++++------------------ src/conf/domain_conf.h | 2 +- src/conf/virconftypes.h | 2 ++ src/hypervisor/virhostdev.c | 6 +++--- src/libxl/libxl_domain.c | 6 +++--- src/libxl/libxl_driver.c | 6 +++--- src/qemu/qemu_command.c | 4 ++-- src/qemu/qemu_domain.c | 4 ++-- src/qemu/qemu_validate.c | 6 +++--- src/security/security_apparmor.c | 2 +- src/security/security_dac.c | 4 ++-- src/security/security_selinux.c | 4 ++-- src/security/virt-aa-helper.c | 2 +- tests/virhostdevtest.c | 2 +- 15 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 7513beb5e1..3a7a6c3f99 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -43,6 +43,10 @@ typedef enum { VIR_ENUM_DECL(virDeviceHostdevPCIDriver); +struct _virDeviceHostdevPCIDriverInfo { + virDeviceHostdevPCIDriverType type; +}; + typedef enum { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE = 0, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6dde17ded3..e840244a7d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6271,7 +6271,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, if (virXMLPropEnum(driver_node, "name", virDeviceHostdevPCIDriverTypeFromString, VIR_XML_PROP_NONZERO, - &pcisrc->backend) < 0) { + &pcisrc->driver.type) < 0) { return -1; } } @@ -23333,18 +23333,18 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf, g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci; - if (pcisrc->backend != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { - const char *backend - = virDeviceHostdevPCIDriverTypeToString(pcisrc->backend); + if (pcisrc->driver.type != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { + const char *driverType + = virDeviceHostdevPCIDriverTypeToString(pcisrc->driver.type); - if (!backend) { + if (!driverType) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected pci hostdev driver name type %1$d"), - pcisrc->backend); + _("unexpected pci hostdev driver type %1$d"), + pcisrc->driver.type); return -1; } - virBufferAsprintf(&driverAttrBuf, " name='%s'", backend); + virBufferAsprintf(&driverAttrBuf, " name='%s'", driverType); } virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); @@ -29838,17 +29838,17 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDef *iface, actual->data.hostdev.def.source.subsys.u.pci.addr = port->plug.hostdevpci.addr; switch ((virNetworkForwardDriverNameType)port->plug.hostdevpci.driver) { case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT: - actual->data.hostdev.def.source.subsys.u.pci.backend = + actual->data.hostdev.def.source.subsys.u.pci.driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT; break; case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM: - actual->data.hostdev.def.source.subsys.u.pci.backend = + actual->data.hostdev.def.source.subsys.u.pci.driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM; break; case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO: - actual->data.hostdev.def.source.subsys.u.pci.backend = + actual->data.hostdev.def.source.subsys.u.pci.driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; break; @@ -29959,7 +29959,7 @@ virDomainNetDefActualToNetworkPort(virDomainDef *dom, } port->plug.hostdevpci.managed = virTristateBoolFromBool(actual->data.hostdev.def.managed); port->plug.hostdevpci.addr = actual->data.hostdev.def.source.subsys.u.pci.addr; - switch (actual->data.hostdev.def.source.subsys.u.pci.backend) { + switch (actual->data.hostdev.def.source.subsys.u.pci.driver.type) { case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT: port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT; break; @@ -29973,14 +29973,10 @@ virDomainNetDefActualToNetworkPort(virDomainDef *dom, break; case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Unexpected PCI backend 'xen'")); - break; - case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST: default: virReportEnumRangeError(virDeviceHostdevPCIDriverType, - actual->data.hostdev.def.source.subsys.u.pci.backend); + actual->data.hostdev.def.source.subsys.u.pci.driver.type); return NULL; } @@ -30924,7 +30920,7 @@ virHostdevIsVFIODevice(const virDomainHostdevDef *hostdev) { return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - hostdev->source.subsys.u.pci.backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; + hostdev->source.subsys.u.pci.driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d56ed32a69..cb37fc9888 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -235,7 +235,7 @@ struct _virDomainHostdevSubsysUSB { struct _virDomainHostdevSubsysPCI { virPCIDeviceAddress addr; /* host address */ - virDeviceHostdevPCIDriverType backend; + virDeviceHostdevPCIDriverInfo driver; virBitmap *origstates; }; diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index e07f967814..d151dd134a 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -66,6 +66,8 @@ typedef struct _virCapsHostSecModelLabel virCapsHostSecModelLabel; typedef struct _virCapsStoragePool virCapsStoragePool; +typedef struct _virDeviceHostdevPCIDriverInfo virDeviceHostdevPCIDriverInfo; + typedef struct _virDomainABIStability virDomainABIStability; typedef struct _virDomainActualNetDef virDomainActualNetDef; diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c index ce7189ffcd..a33b3b604f 100644 --- a/src/hypervisor/virhostdev.c +++ b/src/hypervisor/virhostdev.c @@ -243,14 +243,14 @@ virHostdevGetPCIHostDevice(const virDomainHostdevDef *hostdev, virPCIDeviceSetManaged(actual, hostdev->managed); - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { virPCIDeviceSetStubDriverType(actual, VIR_PCI_STUB_DRIVER_VFIO); - } else if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN) { + } else if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN) { virPCIDeviceSetStubDriverType(actual, VIR_PCI_STUB_DRIVER_XEN); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("pci backend driver type '%1$s' is not supported"), - virDeviceHostdevPCIDriverTypeToString(pcisrc->backend)); + virDeviceHostdevPCIDriverTypeToString(pcisrc->driver.type)); return -1; } diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 904f40914c..22482adfa6 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -160,8 +160,8 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDef *dev, if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) - pcisrc->backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) + pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; } if (dev->type == VIR_DOMAIN_DEVICE_VIDEO) { @@ -997,7 +997,7 @@ libxlNetworkPrepareDevices(virDomainDef *def) if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; if (virDomainHostdevInsert(def, hostdev) < 0) return -1; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index d04ec7f6ea..7f12b11b8d 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3397,13 +3397,13 @@ libxlDomainAttachNetDevice(libxlDriverPrivate *driver, virDomainHostdevDef *hostdev = virDomainNetGetActualHostdev(net); virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci; - /* For those just allocated from a network pool whose backend is + /* For those just allocated from a network pool whose driver type is * still VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT, we need to set - * backend correctly. + * driver type correctly. */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_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/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fcb4e31502..b23720922a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4731,7 +4731,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, const char *failover_pair_id = NULL; /* caller has to assign proper passthrough backend type */ - switch (pcisrc->backend) { + switch (pcisrc->driver.type) { case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO: break; @@ -4741,7 +4741,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST: virReportError(VIR_ERR_INTERNAL_ERROR, _("invalid PCI passthrough type '%1$s'"), - virDeviceHostdevPCIDriverTypeToString(pcisrc->backend)); + virDeviceHostdevPCIDriverTypeToString(pcisrc->driver.type)); return NULL; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d57932b681..b74e48d6f3 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -10568,7 +10568,7 @@ qemuDomainGetHostdevPath(virDomainHostdevDef *dev, case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS: switch (dev->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&pcisrc->addr))) return -1; @@ -11333,7 +11333,7 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev, { bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); virDeviceHostdevPCIDriverType *driverType - = &hostdev->source.subsys.u.pci.backend; + = &hostdev->source.subsys.u.pci.driver.type; /* assign defaults for hostdev passthrough */ switch (*driverType) { diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 83365f6685..d958d01638 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2437,7 +2437,7 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, const virDomainDef *def, virQEMUCaps *qemuCaps) { - int backend; + virDeviceHostdevPCIDriverType driverType; /* forbid capabilities mode hostdev in this kind of hypervisor */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) { @@ -2462,9 +2462,9 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - backend = hostdev->source.subsys.u.pci.backend; + driverType = hostdev->source.subsys.u.pci.driver.type; - if (backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (driverType == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("VFIO PCI device assignment is not supported by this version of qemu")); diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 515d68ec6b..9e1adcee69 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -869,7 +869,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr, if (!pci) goto done; - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driverType == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) { diff --git a/src/security/security_dac.c b/src/security/security_dac.c index ff28e17136..31997474a4 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1257,7 +1257,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) @@ -1418,7 +1418,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 89ceaf48d7..9a65c3a9f1 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2201,7 +2201,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) @@ -2437,7 +2437,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, if (!pci) return -1; - if (pcisrc->backend == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { + if (pcisrc->driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO) { g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); if (!vfioGroupDev) diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index ac4225a783..1964380e47 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1093,7 +1093,7 @@ get_files(vahControl * ctl) virPCIDevice *pci = virPCIDeviceNew(&dev->source.subsys.u.pci.addr); virDeviceHostdevPCIDriverType driverType - = dev->source.subsys.u.pci.backend; + = dev->source.subsys.u.pci.driverType; if (driverType == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO || driverType == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c index d9ff992e91..e375fb2833 100644 --- a/tests/virhostdevtest.c +++ b/tests/virhostdevtest.c @@ -134,7 +134,7 @@ myInit(void) subsys->u.pci.addr.bus = 0; subsys->u.pci.addr.slot = i + 1; subsys->u.pci.addr.function = 0; - subsys->u.pci.backend = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; + subsys->u.pci.driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; } for (i = 0; i < nhostdevs; i++) { -- 2.41.0

The next step in consolidating parsing/formatting of the <driver> element of these objects using a common struct and common code. This eliminates the virNetworkForwardDriverNameType enum which is nearly identical to virDeviceHostdevPCIDriverType (the only non-identical bit was just because they'd gotten out of sync over time) and replaces its uses with a virDeviceHostdevPCIDriverInfo (which is a struct that contains a virDeviceHostdevPCIDriverType). Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/domain_conf.c | 48 +++--------------------------------- src/conf/network_conf.c | 21 ++++++---------- src/conf/network_conf.h | 17 ++----------- src/conf/virnetworkportdef.c | 10 ++++---- src/conf/virnetworkportdef.h | 4 ++- src/network/bridge_driver.c | 2 +- 6 files changed, 22 insertions(+), 80 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e840244a7d..1d083c97ec 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29836,29 +29836,8 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDef *iface, } actual->data.hostdev.def.source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; actual->data.hostdev.def.source.subsys.u.pci.addr = port->plug.hostdevpci.addr; - switch ((virNetworkForwardDriverNameType)port->plug.hostdevpci.driver) { - case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT: - actual->data.hostdev.def.source.subsys.u.pci.driver.type = - VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT; - break; - - case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM: - actual->data.hostdev.def.source.subsys.u.pci.driver.type = - VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM; - break; - - case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO: - actual->data.hostdev.def.source.subsys.u.pci.driver.type = - VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; - break; - - case VIR_NETWORK_FORWARD_DRIVER_NAME_LAST: - default: - virReportEnumRangeError(virNetworkForwardDriverNameType, - port->plug.hostdevpci.driver); - goto error; - } - + actual->data.hostdev.def.source.subsys.u.pci.driver.type + = port->plug.hostdevpci.driver.type; break; case VIR_NETWORK_PORT_PLUG_TYPE_LAST: @@ -29959,27 +29938,8 @@ virDomainNetDefActualToNetworkPort(virDomainDef *dom, } port->plug.hostdevpci.managed = virTristateBoolFromBool(actual->data.hostdev.def.managed); port->plug.hostdevpci.addr = actual->data.hostdev.def.source.subsys.u.pci.addr; - switch (actual->data.hostdev.def.source.subsys.u.pci.driver.type) { - case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT: - port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT; - break; - - case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM: - port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_KVM; - break; - - case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO: - port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO; - break; - - case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN: - case VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_LAST: - default: - virReportEnumRangeError(virDeviceHostdevPCIDriverType, - actual->data.hostdev.def.source.subsys.u.pci.driver.type); - return NULL; - } - + port->plug.hostdevpci.driver.type + = actual->data.hostdev.def.source.subsys.u.pci.driver.type; break; case VIR_DOMAIN_NET_TYPE_CLIENT: diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index b9601cb307..e3ad4c7340 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -56,13 +56,6 @@ VIR_ENUM_IMPL(virNetworkForwardHostdevDevice, "none", "pci", "netdev", ); -VIR_ENUM_IMPL(virNetworkForwardDriverName, - VIR_NETWORK_FORWARD_DRIVER_NAME_LAST, - "default", - "kvm", - "vfio", -); - VIR_ENUM_IMPL(virNetworkTaint, VIR_NETWORK_TAINT_LAST, "hook-script", @@ -1358,9 +1351,9 @@ virNetworkForwardDefParseXML(const char *networkName, if ((driverNode = virXPathNode("./driver", ctxt))) { if (virXMLPropEnum(driverNode, "name", - virNetworkForwardDriverNameTypeFromString, + virDeviceHostdevPCIDriverTypeFromString, VIR_XML_PROP_NONZERO, - &def->driverName) < 0) { + &def->driver.type) < 0) { return -1; } } @@ -2351,19 +2344,19 @@ virNetworkDefFormatBuf(virBuffer *buf, || VIR_SOCKET_ADDR_VALID(&def->forward.addr.end) || def->forward.port.start || def->forward.port.end - || (def->forward.driverName - != VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT) + || (def->forward.driver.type + != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) || def->forward.natIPv6); virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : ""); virBufferAdjustIndent(buf, 2); - if (def->forward.driverName) { + if (def->forward.driver.type) { const char *driverName - = virNetworkForwardDriverNameTypeToString(def->forward.driverName); + = virDeviceHostdevPCIDriverTypeToString(def->forward.driver.type); if (!driverName) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected hostdev driver name type %1$d "), - def->forward.driverName); + def->forward.driver.type); return -1; } virBufferAsprintf(&driverAttrBuf, " name='%s'", driverName); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 497ae765f2..1d7fd3ab6a 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -24,6 +24,7 @@ #define DNS_RECORD_LENGTH_SRV (512 - 30) /* Limit minus overhead as mentioned in RFC-2782 */ #include "internal.h" +#include "virconftypes.h" #include "virsocketaddr.h" #include "virnetdevbandwidth.h" #include "virnetdevvportprofile.h" @@ -88,20 +89,6 @@ typedef enum { VIR_ENUM_DECL(virNetworkDHCPLeaseTimeUnit); -/* The backend driver used for devices from the pool. Currently used - * only for PCI devices (vfio vs. kvm), but could be used for other - * device types in the future. - */ -typedef enum { - VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT, /* kvm now, could change */ - VIR_NETWORK_FORWARD_DRIVER_NAME_KVM, /* force legacy kvm style */ - VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO, /* force vfio */ - - VIR_NETWORK_FORWARD_DRIVER_NAME_LAST -} virNetworkForwardDriverNameType; - -VIR_ENUM_DECL(virNetworkForwardDriverName); - typedef struct _virNetworkDHCPLeaseTimeDef virNetworkDHCPLeaseTimeDef; struct _virNetworkDHCPLeaseTimeDef { unsigned long long expiry; @@ -216,7 +203,7 @@ typedef struct _virNetworkForwardDef virNetworkForwardDef; struct _virNetworkForwardDef { int type; /* One of virNetworkForwardType constants */ bool managed; /* managed attribute for hostdev mode */ - virNetworkForwardDriverNameType driverName; + virDeviceHostdevPCIDriverInfo driver; /* If there are multiple forward devices (i.e. a pool of * interfaces), they will be listed here. diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c index 402c0051ec..77ef705e18 100644 --- a/src/conf/virnetworkportdef.c +++ b/src/conf/virnetworkportdef.c @@ -226,9 +226,9 @@ virNetworkPortDefParseXML(xmlXPathContextPtr ctxt) if ((driverNode = virXPathNode("./plug/driver", ctxt))) { if (virXMLPropEnum(driverNode, "name", - virNetworkForwardDriverNameTypeFromString, + virDeviceHostdevPCIDriverTypeFromString, VIR_XML_PROP_NONZERO, - &def->plug.hostdevpci.driver) < 0) { + &def->plug.hostdevpci.driver.type) < 0) { return NULL; } } @@ -356,10 +356,10 @@ virNetworkPortDefFormatBuf(virBuffer *buf, virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); - if (def->plug.hostdevpci.driver) { + if (def->plug.hostdevpci.driver.type) { virBufferEscapeString(&driverAttrBuf, " name='%s'", - virNetworkForwardDriverNameTypeToString( - def->plug.hostdevpci.driver)); + virDeviceHostdevPCIDriverTypeToString( + def->plug.hostdevpci.driver.type)); } virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); diff --git a/src/conf/virnetworkportdef.h b/src/conf/virnetworkportdef.h index bfe1dae9ea..9e51ab1a8b 100644 --- a/src/conf/virnetworkportdef.h +++ b/src/conf/virnetworkportdef.h @@ -22,6 +22,8 @@ #pragma once #include "internal.h" +#include "virconftypes.h" +#include "device_conf.h" #include "virnetdevvlan.h" #include "virnetdevvportprofile.h" #include "virnetdevbandwidth.h" @@ -69,7 +71,7 @@ struct _virNetworkPortDef { } direct; struct { virPCIDeviceAddress addr; /* PCI Address of device */ - unsigned int driver; /* virNetworkForwardDriverNameType */ + virDeviceHostdevPCIDriverInfo driver; virTristateBool managed; } hostdevpci; } plug; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 4be740de2c..a9188c2436 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -3930,7 +3930,7 @@ networkAllocatePort(virNetworkObj *obj, return -1; } port->plug.hostdevpci.addr = dev->device.pci; - port->plug.hostdevpci.driver = netdef->forward.driverName; + port->plug.hostdevpci.driver.type = netdef->forward.driver.type; port->plug.hostdevpci.managed = virTristateBoolFromBool(netdef->forward.managed); if (port->virtPortProfile) { -- 2.41.0

This is done so that we can re-use the same parser/formatter for <network> and <networkport> Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/device_conf.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/conf/device_conf.h | 7 +++++++ src/conf/domain_conf.c | 28 +++++----------------------- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 25a522671e..e022783816 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -55,6 +55,47 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, "unassigned", ); + +int +virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node, + virDeviceHostdevPCIDriverInfo *driver) +{ + if (virXMLPropEnum(node, "name", + virDeviceHostdevPCIDriverTypeFromString, + VIR_XML_PROP_NONZERO, + &driver->type) < 0) { + return -1; + } + + return 0; +} + + +int +virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, + const virDeviceHostdevPCIDriverInfo *driver) +{ + g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER; + + if (driver->type != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { + const char *driverType + = virDeviceHostdevPCIDriverTypeToString(driver->type); + + if (!driverType) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected pci hostdev driver type %1$d"), + driver->type); + return -1; + } + + virBufferAsprintf(&driverAttrBuf, " name='%s'", driverType); + } + + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + return 0; +} + + static int virZPCIDeviceAddressParseXML(xmlNodePtr node, virPCIDeviceAddress *addr) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 3a7a6c3f99..9f4b9f5375 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -25,6 +25,7 @@ #include <libxml/xpath.h> #include "internal.h" +#include "virconftypes.h" #include "virbuffer.h" #include "virccw.h" #include "virpci.h" @@ -185,6 +186,12 @@ struct _virDomainDeviceInfo { bool isolationGroupLocked; }; +int virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node, + virDeviceHostdevPCIDriverInfo *driver); + +int virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, + const virDeviceHostdevPCIDriverInfo *driver); + void virDomainDeviceInfoClear(virDomainDeviceInfo *info); void virDomainDeviceInfoFree(virDomainDeviceInfo *info); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1d083c97ec..ea1348da5f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6267,13 +6267,9 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, if (virDomainHostdevSubsysPCIDefParseXML(sourcenode, ctxt, def, flags) < 0) return -1; - if ((driver_node = virXPathNode("./driver", ctxt))) { - if (virXMLPropEnum(driver_node, "name", - virDeviceHostdevPCIDriverTypeFromString, - VIR_XML_PROP_NONZERO, - &pcisrc->driver.type) < 0) { - return -1; - } + if ((driver_node = virXPathNode("./driver", ctxt)) && + virDeviceHostdevPCIDriverInfoParseXML(driver_node, &pcisrc->driver) < 0) { + return -1; } break; @@ -23328,26 +23324,12 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf, unsigned int flags, bool includeTypeInAddr) { - g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci; - if (pcisrc->driver.type != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { - const char *driverType - = virDeviceHostdevPCIDriverTypeToString(pcisrc->driver.type); - - if (!driverType) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected pci hostdev driver type %1$d"), - pcisrc->driver.type); - return -1; - } - - virBufferAsprintf(&driverAttrBuf, " name='%s'", driverType); - } - - virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + if (virDeviceHostdevPCIDriverInfoFormat(buf, &pcisrc->driver) < 0) + return -1; if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) virBufferAsprintf(&sourceAttrBuf, " writeFiltering='%s'", -- 2.41.0

Now if a new attribute is added to <driver>, we only need to update the formatting/parsing in one place. Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/network_conf.c | 23 ++++------------------- src/conf/virnetworkportdef.c | 20 ++++++-------------- 2 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index e3ad4c7340..43e7c78e95 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1349,13 +1349,9 @@ virNetworkForwardDefParseXML(const char *networkName, def->managed = true; } - if ((driverNode = virXPathNode("./driver", ctxt))) { - if (virXMLPropEnum(driverNode, "name", - virDeviceHostdevPCIDriverTypeFromString, - VIR_XML_PROP_NONZERO, - &def->driver.type) < 0) { + if ((driverNode = virXPathNode("./driver", ctxt)) && + virDeviceHostdevPCIDriverInfoParseXML(driverNode, &def->driver) < 0) { return -1; - } } /* bridge and hostdev modes can use a pool of physical interfaces */ @@ -2350,19 +2346,8 @@ virNetworkDefFormatBuf(virBuffer *buf, virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : ""); virBufferAdjustIndent(buf, 2); - if (def->forward.driver.type) { - const char *driverName - = virDeviceHostdevPCIDriverTypeToString(def->forward.driver.type); - if (!driverName) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected hostdev driver name type %1$d "), - def->forward.driver.type); - return -1; - } - virBufferAsprintf(&driverAttrBuf, " name='%s'", driverName); - } - - virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + if (virDeviceHostdevPCIDriverInfoFormat(buf, &def->forward.driver) < 0) + return -1; if (def->forward.type == VIR_NETWORK_FORWARD_NAT) { if (virNetworkForwardNatDefFormat(buf, &def->forward) < 0) diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c index 77ef705e18..67911e498e 100644 --- a/src/conf/virnetworkportdef.c +++ b/src/conf/virnetworkportdef.c @@ -224,13 +224,10 @@ virNetworkPortDefParseXML(xmlXPathContextPtr ctxt) &def->plug.hostdevpci.managed) < 0) return NULL; - if ((driverNode = virXPathNode("./plug/driver", ctxt))) { - if (virXMLPropEnum(driverNode, "name", - virDeviceHostdevPCIDriverTypeFromString, - VIR_XML_PROP_NONZERO, - &def->plug.hostdevpci.driver.type) < 0) { - return NULL; - } + if ((driverNode = virXPathNode("./plug/driver", ctxt)) && + virDeviceHostdevPCIDriverInfoParseXML(driverNode, + &def->plug.hostdevpci.driver) < 0) { + return NULL; } if (!(addressNode = virXPathNode("./plug/address", ctxt))) { @@ -356,13 +353,8 @@ virNetworkPortDefFormatBuf(virBuffer *buf, virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); - if (def->plug.hostdevpci.driver.type) { - virBufferEscapeString(&driverAttrBuf, " name='%s'", - virDeviceHostdevPCIDriverTypeToString( - def->plug.hostdevpci.driver.type)); - } - - virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + if (virDeviceHostdevPCIDriverInfoFormat(buf, &def->plug.hostdevpci.driver) < 0) + return -1; virPCIDeviceAddressFormat(buf, def->plug.hostdevpci.addr, false); virBufferAdjustIndent(buf, -2); -- 2.41.0

The long-deprecated use of <driver name='vfio|xen|kvm'/> in domain xml for <hostdev> devices was only ever necessary during the period when libvirt supported both VFIO and "legacy KVM" styles of hostdev device assignment in the QEMU driver. This became unnecessary many years ago (circa RHEL6!) when legacy KVM device assignment was removed from the kernel, and support for that style of device assignment was completely disabled in the libvirt source in 2019 (commit v5.6.0-316-g2e7225ea8c). Nevertheless, there were instances of <driver name='vfio'/> in the unit test data that were then (unnecessarily) propagated to several more tests over the years. This patch cleans out those unnecessary explicit settings of driver name='vfio' in all QEMU unit test data, proving that the attribute is no longer (externally) needed while also making it simpler to properly test when a later patch "re-animates" the driver name attribute for a slightly different (but related) use. Signed-off-by: Laine Stump <laine@redhat.com> --- tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml | 4 ---- tests/qemuxml2argvdata/hostdev-pci-multifunction.xml | 7 ------- tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml | 1 - .../hostdev-vfio-zpci-autogenerate-fids.xml | 2 -- .../hostdev-vfio-zpci-autogenerate-uids.xml | 2 -- tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml | 2 -- .../qemuxml2argvdata/hostdev-vfio-zpci-ccw-memballoon.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio-zpci-duplicate.xml | 2 -- .../hostdev-vfio-zpci-invalid-uid-valid-fid.xml | 1 - .../hostdev-vfio-zpci-multidomain-many.xml | 8 -------- tests/qemuxml2argvdata/hostdev-vfio-zpci-set-zero.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio-zpci-uid-set-zero.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio-zpci.xml | 1 - tests/qemuxml2argvdata/hostdev-vfio.xml | 1 - tests/qemuxml2argvdata/net-hostdev-vfio-multidomain.xml | 1 - tests/qemuxml2argvdata/net-hostdev-vfio.xml | 1 - tests/qemuxml2argvdata/pseries-hostdevs-1.xml | 3 --- tests/qemuxml2argvdata/pseries-hostdevs-2.xml | 2 -- tests/qemuxml2argvdata/pseries-hostdevs-3.xml | 2 -- .../hostdev-pci-address-unassigned.x86_64-latest.xml | 4 ---- .../hostdev-pci-multifunction.x86_64-latest.xml | 7 ------- .../hostdev-vfio-zpci-autogenerate-fids.s390x-latest.xml | 2 -- .../hostdev-vfio-zpci-autogenerate-uids.s390x-latest.xml | 2 -- .../hostdev-vfio-zpci-autogenerate.s390x-latest.xml | 1 - .../hostdev-vfio-zpci-boundaries.s390x-latest.xml | 2 -- .../hostdev-vfio-zpci-ccw-memballoon.s390x-latest.xml | 1 - .../hostdev-vfio-zpci-multidomain-many.s390x-latest.xml | 8 -------- .../qemuxml2xmloutdata/hostdev-vfio-zpci.s390x-latest.xml | 1 - tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml | 1 - .../qemuxml2xmloutdata/net-hostdev-vfio.x86_64-latest.xml | 1 - .../pseries-hostdevs-1.ppc64-latest.xml | 3 --- .../pseries-hostdevs-2.ppc64-latest.xml | 2 -- .../pseries-hostdevs-3.ppc64-latest.xml | 2 -- 35 files changed, 82 deletions(-) diff --git a/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml b/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml index 9a2685ca0e..864ef303c0 100644 --- a/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml +++ b/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml @@ -14,26 +14,22 @@ <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x1'/> </source> <address type='unassigned'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml b/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml index 06c889c64d..ba0a593628 100644 --- a/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml +++ b/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml @@ -14,43 +14,36 @@ <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x1'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml b/tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml index b720883913..7afe18b24e 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml @@ -23,7 +23,6 @@ <controller type='ide' index='0'/> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0021' bus='222' slot='31' function='1'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-fids.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-fids.xml index 49c26e2434..e72c524a98 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-fids.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-fids.xml @@ -8,7 +8,6 @@ <devices> <emulator>/usr/bin/qemu-system-s390x</emulator> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -17,7 +16,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-uids.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-uids.xml index e74e0116c7..1ed75aae48 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-uids.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate-uids.xml @@ -8,7 +8,6 @@ <devices> <emulator>/usr/bin/qemu-system-s390x</emulator> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -17,7 +16,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml index 36161006ab..b4b1ce315f 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml @@ -8,7 +8,6 @@ <devices> <emulator>/usr/bin/qemu-system-s390x</emulator> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml index 1e6060345b..fe005af488 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml @@ -9,7 +9,6 @@ <emulator>/usr/bin/qemu-system-s390x</emulator> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0xffff' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -18,7 +17,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-ccw-memballoon.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-ccw-memballoon.xml index ef5e97fc9c..bb6861f103 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-ccw-memballoon.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-ccw-memballoon.xml @@ -8,7 +8,6 @@ <devices> <emulator>/usr/bin/qemu-system-s390x</emulator> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-duplicate.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-duplicate.xml index 6062ae4940..53cf48ea6a 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-duplicate.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-duplicate.xml @@ -9,7 +9,6 @@ <emulator>/usr/bin/qemu-system-s390x</emulator> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -18,7 +17,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-invalid-uid-valid-fid.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-invalid-uid-valid-fid.xml index 6e7101489e..1026661730 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-invalid-uid-valid-fid.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-invalid-uid-valid-fid.xml @@ -9,7 +9,6 @@ <emulator>/usr/bin/qemu-system-s390x</emulator> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml index da8305dd6d..36c11a8311 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml @@ -9,7 +9,6 @@ <emulator>/usr/bin/qemu-system-s390x</emulator> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -18,7 +17,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0002' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -27,20 +25,17 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0003' bus='0x00' slot='0x00' function='0x0'/> </source> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0004' bus='0x00' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -49,7 +44,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0006' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -58,7 +52,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0007' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -67,7 +60,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0008' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-set-zero.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-set-zero.xml index fd3d1193f1..eefe05de39 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-set-zero.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-set-zero.xml @@ -9,7 +9,6 @@ <emulator>/usr/bin/qemu-system-s390x</emulator> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-uid-set-zero.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-uid-set-zero.xml index 6bfbfe611b..fb0e680b55 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-uid-set-zero.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-uid-set-zero.xml @@ -8,7 +8,6 @@ <devices> <emulator>/usr/bin/qemu-system-s390x</emulator> <hostdev mode='subsystem' type='pci'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml index a9a5afd6dd..8b3cc45ddf 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml @@ -21,7 +21,6 @@ </disk> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='00' slot='00' function='0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml index 002b99c52d..5f439eff73 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml @@ -9,7 +9,6 @@ <emulator>/usr/bin/qemu-system-s390x</emulator> <controller type='pci' index='0' model='pci-root'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/hostdev-vfio.xml b/tests/qemuxml2argvdata/hostdev-vfio.xml index 1b438a2eef..a03870f6e0 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio.xml @@ -25,7 +25,6 @@ <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> diff --git a/tests/qemuxml2argvdata/net-hostdev-vfio-multidomain.xml b/tests/qemuxml2argvdata/net-hostdev-vfio-multidomain.xml index ae8c4e7e80..cdadf4f2cb 100644 --- a/tests/qemuxml2argvdata/net-hostdev-vfio-multidomain.xml +++ b/tests/qemuxml2argvdata/net-hostdev-vfio-multidomain.xml @@ -24,7 +24,6 @@ <controller type='pci' index='0' model='pci-root'/> <interface type='hostdev' managed='yes'> <mac address='00:11:22:33:44:55'/> - <driver name='vfio'/> <source> <address type='pci' domain='0x0021' bus='0xde' slot='0x1f' function='0x1'/> </source> diff --git a/tests/qemuxml2argvdata/net-hostdev-vfio.xml b/tests/qemuxml2argvdata/net-hostdev-vfio.xml index e6e6b6e5d3..9cdb8a602d 100644 --- a/tests/qemuxml2argvdata/net-hostdev-vfio.xml +++ b/tests/qemuxml2argvdata/net-hostdev-vfio.xml @@ -24,7 +24,6 @@ <controller type='pci' index='0' model='pci-root'/> <interface type='hostdev' managed='yes'> <mac address='00:11:22:33:44:55'/> - <driver name='vfio'/> <source> <address type='pci' domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> diff --git a/tests/qemuxml2argvdata/pseries-hostdevs-1.xml b/tests/qemuxml2argvdata/pseries-hostdevs-1.xml index 04f3ec4759..5d09413a98 100644 --- a/tests/qemuxml2argvdata/pseries-hostdevs-1.xml +++ b/tests/qemuxml2argvdata/pseries-hostdevs-1.xml @@ -11,7 +11,6 @@ <!-- This hostdev will cause a new PHB to be created because its isolation group is 1 (IOMMU group 0) --> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> @@ -19,7 +18,6 @@ <!-- This hostdev can't share the PHB that was just created, because its isolation group is 2 (IOMMU group 1) --> <interface type='hostdev' managed='yes'> - <driver name='vfio'/> <source> <address type='pci' domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> @@ -28,7 +26,6 @@ <!-- This hostdev will be placed on the first PHB, since its isolation group is 1 (IOMMU group 0) just like the first hostdev --> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x1'/> </source> diff --git a/tests/qemuxml2argvdata/pseries-hostdevs-2.xml b/tests/qemuxml2argvdata/pseries-hostdevs-2.xml index 6568475c72..00d4228499 100644 --- a/tests/qemuxml2argvdata/pseries-hostdevs-2.xml +++ b/tests/qemuxml2argvdata/pseries-hostdevs-2.xml @@ -17,7 +17,6 @@ despite being in the separate isolation group 1 (IOMMU group 0), because the address has been requested explicitly by the user --> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> @@ -26,7 +25,6 @@ <!-- This hostdev can use neither the PHB that was just created, nor the default one, because it's in isolation group 2 (IOMMU group 1) --> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> diff --git a/tests/qemuxml2argvdata/pseries-hostdevs-3.xml b/tests/qemuxml2argvdata/pseries-hostdevs-3.xml index 4f51f48c90..64ba95ca30 100644 --- a/tests/qemuxml2argvdata/pseries-hostdevs-3.xml +++ b/tests/qemuxml2argvdata/pseries-hostdevs-3.xml @@ -11,7 +11,6 @@ <!-- This hostdev will cause a new PHB to be created because its isolation group is 1 (IOMMU group 0). It will be PHB 2 due to the address --> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> @@ -20,7 +19,6 @@ <!-- This hostdev will be placed on the same PHB, since its isolation group is also 1 (IOMMU group 0) --> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x1'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.x86_64-latest.xml index 480d2f8363..9da9a8a07e 100644 --- a/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.x86_64-latest.xml @@ -28,28 +28,24 @@ <input type='keyboard' bus='ps2'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x1'/> </source> <address type='unassigned'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.x86_64-latest.xml index a29a27e85b..9530c28e14 100644 --- a/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.x86_64-latest.xml @@ -28,49 +28,42 @@ <input type='keyboard' bus='ps2'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x1'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-fids.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-fids.s390x-latest.xml index dd1dea4e99..f23ad5b90c 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-fids.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-fids.s390x-latest.xml @@ -20,7 +20,6 @@ <controller type='pci' index='0' model='pci-root'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -29,7 +28,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-uids.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-uids.s390x-latest.xml index 1a52487692..9bf2ce32be 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-uids.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate-uids.s390x-latest.xml @@ -20,7 +20,6 @@ <controller type='pci' index='0' model='pci-root'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -29,7 +28,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.s390x-latest.xml index 670f8c68b4..94f3c04b9a 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.s390x-latest.xml @@ -20,7 +20,6 @@ <controller type='pci' index='0' model='pci-root'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.s390x-latest.xml index df55f79501..8b0044af1c 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.s390x-latest.xml @@ -25,7 +25,6 @@ </controller> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0xffff' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -34,7 +33,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-ccw-memballoon.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-ccw-memballoon.s390x-latest.xml index 7df6491b68..e0ff360553 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-ccw-memballoon.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-ccw-memballoon.s390x-latest.xml @@ -18,7 +18,6 @@ <controller type='pci' index='0' model='pci-root'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.s390x-latest.xml index e64d7de561..70d592f2df 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.s390x-latest.xml @@ -20,7 +20,6 @@ <controller type='pci' index='0' model='pci-root'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -29,7 +28,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0002' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -38,7 +36,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0003' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -47,7 +44,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0004' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -56,7 +52,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -65,7 +60,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0006' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -74,7 +68,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0007' bus='0x00' slot='0x00' function='0x0'/> </source> @@ -83,7 +76,6 @@ </address> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0008' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.s390x-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.s390x-latest.xml index 5e14a63810..c8a1407427 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.s390x-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.s390x-latest.xml @@ -20,7 +20,6 @@ <controller type='pci' index='0' model='pci-root'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml index b660d245a1..3915b515f2 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml @@ -34,7 +34,6 @@ <input type='keyboard' bus='ps2'/> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> diff --git a/tests/qemuxml2xmloutdata/net-hostdev-vfio.x86_64-latest.xml b/tests/qemuxml2xmloutdata/net-hostdev-vfio.x86_64-latest.xml index 167e1b1fea..1eee425593 100644 --- a/tests/qemuxml2xmloutdata/net-hostdev-vfio.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/net-hostdev-vfio.x86_64-latest.xml @@ -32,7 +32,6 @@ <controller type='pci' index='0' model='pci-root'/> <interface type='hostdev' managed='yes'> <mac address='00:11:22:33:44:55'/> - <driver name='vfio'/> <source> <address type='pci' domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> diff --git a/tests/qemuxml2xmloutdata/pseries-hostdevs-1.ppc64-latest.xml b/tests/qemuxml2xmloutdata/pseries-hostdevs-1.ppc64-latest.xml index db369a1fc7..d0ad114d34 100644 --- a/tests/qemuxml2xmloutdata/pseries-hostdevs-1.ppc64-latest.xml +++ b/tests/qemuxml2xmloutdata/pseries-hostdevs-1.ppc64-latest.xml @@ -32,7 +32,6 @@ </controller> <interface type='hostdev' managed='yes'> <mac address='52:54:00:6d:90:02'/> - <driver name='vfio'/> <source> <address type='pci' domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> @@ -40,14 +39,12 @@ </interface> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x1'/> </source> diff --git a/tests/qemuxml2xmloutdata/pseries-hostdevs-2.ppc64-latest.xml b/tests/qemuxml2xmloutdata/pseries-hostdevs-2.ppc64-latest.xml index 09b657698d..4ffcae80b8 100644 --- a/tests/qemuxml2xmloutdata/pseries-hostdevs-2.ppc64-latest.xml +++ b/tests/qemuxml2xmloutdata/pseries-hostdevs-2.ppc64-latest.xml @@ -35,14 +35,12 @@ </controller> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x01' slot='0x02' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/> </source> diff --git a/tests/qemuxml2xmloutdata/pseries-hostdevs-3.ppc64-latest.xml b/tests/qemuxml2xmloutdata/pseries-hostdevs-3.ppc64-latest.xml index 58ffb09c3b..e06901a9a4 100644 --- a/tests/qemuxml2xmloutdata/pseries-hostdevs-3.ppc64-latest.xml +++ b/tests/qemuxml2xmloutdata/pseries-hostdevs-3.ppc64-latest.xml @@ -32,14 +32,12 @@ </controller> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0001' bus='0x01' slot='0x00' function='0x1'/> </source> -- 2.41.0

Xen only supports a single type of PCI hostdev assignment, so it is superfluous to have <driver name='xen'/> peppered throughout the config. It *is* necessary to have the driver type explicitly set in the hosdev object before calling into the hypervisor-agnostic "hostdev manager" though (otherwise the hostdev manager doesn't know whether it should do Xen-specific setup, or VFIO-specific setup). Historically, the Xen driver has checked for "default" driver type (i.e. not set in the XML), and set it to "xen', during the XML postparse, thus guaranteeing that it will be set by the time the object is sent to the hostdev manager at runtime, but also setting it so early that a simple round-trip of parse-format results in the XML always containing an explicit <driver name='xen'/>, even if that wasn't specified in the original XML. The QEMU driver *doesn't* set driver.type during postparse though; instead, it waits until domain startup time (or device attach time for hotplug), and sets the driver.type then. The result is that a parse-format round trip of the XML in the QEMU driver *doesn't* add in the <driver name='vfio'/>. This patch modifies the Xen code to behave similarly to the QEMU code - the PostParse just checks for a driver.type that isn't supported by the Xen driver, and any explicit setting to "xen" is deferred until domain runtime rather than during the postparse. This delayed setting of driver.type of course results in slightly different xml2xml parse-format results, so the unit test data is modified accordingly. Signed-off-by: Laine Stump <laine@redhat.com> --- src/libxl/libxl_domain.c | 65 +++++++++++++++---- src/libxl/libxl_driver.c | 25 ++++--- tests/libxlxml2domconfigdata/moredevs-hvm.xml | 1 - tests/xlconfigdata/test-fullvirt-pci.xml | 2 - tests/xmconfigdata/test-pci-dev-syntax.xml | 2 - tests/xmconfigdata/test-pci-devs.xml | 2 - 6 files changed, 69 insertions(+), 28 deletions(-) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 22482adfa6..ecdf57e655 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.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) - pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + pcisrc->driver.type != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT && + pcisrc->driver.type != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN) { + + /* Xen only supports "Xen" style of hostdev, of course! */ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("XEN does not support device assignment mode '%1$s'"), + virDeviceHostdevPCIDriverTypeToString(pcisrc->driver.type)); + 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.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; if (virDomainHostdevInsert(def, hostdev) < 0) return -1; @@ -1007,6 +1005,46 @@ 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.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) { + + + pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + + /* Q: Why do we set an explicit driverType here even + * though Xen (currently) only supports one driverType for + * PCI hostdev assignment? + * + * A: Setting the driver type *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 driverType be explicitly set (otherwise it wouldn't + * know whether to bind to the Xen driver or VFIO driver, + * for example). + */ + } + } + + return 0; +} + + static void libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void *for_callback) { @@ -1174,6 +1212,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 7f12b11b8d..1636233346 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.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_DEFAULT) + pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + + if (pcisrc->driver.type != VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("XEN does not support device assignment mode '%1$s'"), + virDeviceHostdevPCIDriverTypeToString(pcisrc->driver.type)); + 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_TYPE_DEFAULT, we need to set - * driver type correctly. - */ - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - pcisrc->driver.type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_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 @@ </interface> <interface type='hostdev' managed='yes'> <mac address='00:16:3e:2e:e7:fc'/> - <driver name='xen'/> <source> <address type='pci' domain='0x0000' bus='0x0a' slot='0x10' function='0x0'/> </source> 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 @@ <model type='cirrus' vram='8192' heads='1' primary='yes'/> </video> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='xen'/> <source> <address domain='0x0000' bus='0x01' slot='0x1a' function='0x1'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='xen'/> <source writeFiltering='no'> <address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> </source> 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 @@ <model type='cirrus' vram='8192' heads='1' primary='yes'/> </video> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='xen'/> <source> <address domain='0x0001' bus='0x0c' slot='0x1b' function='0x2'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='xen'/> <source> <address domain='0x0000' bus='0x01' slot='0x13' function='0x0'/> </source> 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 @@ <model type='cirrus' vram='8192' heads='1' primary='yes'/> </video> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='xen'/> <source> <address domain='0x0001' bus='0x0c' slot='0x1b' function='0x2'/> </source> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> - <driver name='xen'/> <source> <address domain='0x0000' bus='0x01' slot='0x13' function='0x0'/> </source> -- 2.41.0

virHostdevIsVFIODevice() and virDomainDefHasVFIOHostdev() are only ever called from the QEMU driver, and in the case of the QEMU driver, any PCI hostdev by definition uses VFIO, so really all these callers only need to know if the device is a PCI hostdev. (It turned out that the less specific virHostdevIsPCIDevice() already existed in hypervisor/virhostdev.c, so I had to remove one of them; since conf is a lower level directory than hypervisor, and the function is called from conf, keeping the copy in hypervisor would have required moving its caller (virDomainDefHasPCIHostdev()) into hypervisor as well, so I just removed the copy in hypervisor.) Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/domain_conf.c | 13 ++++++------- src/conf/domain_conf.h | 4 ++-- src/hypervisor/virhostdev.c | 8 -------- src/hypervisor/virhostdev.h | 2 -- src/libvirt_private.syms | 5 ++--- src/qemu/qemu_domain.c | 6 +++--- src/qemu/qemu_hostdev.c | 2 +- src/qemu/qemu_hotplug.c | 2 +- 8 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ea1348da5f..eb2df9f30a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -30576,12 +30576,12 @@ virDomainDefHasNVMeDisk(const virDomainDef *def) bool -virDomainDefHasVFIOHostdev(const virDomainDef *def) +virDomainDefHasPCIHostdev(const virDomainDef *def) { size_t i; for (i = 0; i < def->nhostdevs; i++) { - if (virHostdevIsVFIODevice(def->hostdevs[i])) + if (virHostdevIsPCIDevice(def->hostdevs[i])) return true; } @@ -30852,17 +30852,16 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev) /** - * virHostdevIsVFIODevice: + * virHostdevIsPCIDevice: * @hostdev: host device to check * - * Returns true if @hostdev is a PCI device with VFIO backend, false otherwise. + * Returns true if @hostdev is a PCI device, false otherwise. */ bool -virHostdevIsVFIODevice(const virDomainHostdevDef *hostdev) +virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) { return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - hostdev->source.subsys.u.pci.driver.type == VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cb37fc9888..f692fdaafd 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -4442,7 +4442,7 @@ bool virDomainDefHasNVMeDisk(const virDomainDef *def); bool -virDomainDefHasVFIOHostdev(const virDomainDef *def); +virDomainDefHasPCIHostdev(const virDomainDef *def); bool virDomainDefHasMdevHostdev(const virDomainDef *def); @@ -4500,7 +4500,7 @@ bool virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev) ATTRIBUTE_NONNULL(1); bool -virHostdevIsVFIODevice(const virDomainHostdevDef *hostdev) +virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) ATTRIBUTE_NONNULL(1); int diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c index a33b3b604f..e0ad1371c2 100644 --- a/src/hypervisor/virhostdev.c +++ b/src/hypervisor/virhostdev.c @@ -344,14 +344,6 @@ virHostdevNetDevice(virDomainHostdevDef *hostdev, } -bool -virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) -{ - return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; -} - - static bool virHostdevIsPCINetDevice(const virDomainHostdevDef *hostdev) { diff --git a/src/hypervisor/virhostdev.h b/src/hypervisor/virhostdev.h index 642d753ffb..22ec3068db 100644 --- a/src/hypervisor/virhostdev.h +++ b/src/hypervisor/virhostdev.h @@ -232,5 +232,3 @@ virHostdevUpdateActiveNVMeDevices(virHostdevManager *hostdev_mgr, const char *dom_name, virDomainDiskDef **disks, size_t ndisks); - -bool virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 479a69ed0b..a943a79e01 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -340,11 +340,11 @@ virDomainDefHasMemoryHotplug; virDomainDefHasNVMeDisk; virDomainDefHasOldStyleROUEFI; virDomainDefHasOldStyleUEFI; +virDomainDefHasPCIHostdev; virDomainDefHasSpiceGraphics; virDomainDefHasUSB; virDomainDefHasVcpusOffline; virDomainDefHasVDPANet; -virDomainDefHasVFIOHostdev; virDomainDefLifecycleActionAllowed; virDomainDefMaybeAddController; virDomainDefMaybeAddInput; @@ -777,8 +777,8 @@ virDomainEventWatchdogNewFromObj; virDomainQemuMonitorEventNew; virDomainQemuMonitorEventStateRegisterID; virHostdevIsMdevDevice; +virHostdevIsPCIDevice; virHostdevIsSCSIDevice; -virHostdevIsVFIODevice; # conf/domain_nwfilter.h @@ -1641,7 +1641,6 @@ virCloseCallbacksDomainRunForConn; # hypervisor/virhostdev.h virHostdevFindUSBDevice; -virHostdevIsPCIDevice; virHostdevManagerGetDefault; virHostdevPCINodeDeviceDetach; virHostdevPCINodeDeviceReAttach; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b74e48d6f3..2e6da1d2da 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -9380,7 +9380,7 @@ getPPC64MemLockLimitBytes(virDomainDef *def) for (i = 0; i < def->nhostdevs; i++) { virDomainHostdevDef *dev = def->hostdevs[i]; - if (virHostdevIsVFIODevice(dev)) { + if (virHostdevIsPCIDevice(dev)) { pciAddr = &dev->source.subsys.u.pci.addr; if (virPCIDeviceAddressIsValid(pciAddr, false)) { @@ -9485,7 +9485,7 @@ qemuDomainGetNumVFIOHostdevs(const virDomainDef *def) int n = 0; for (i = 0; i < def->nhostdevs; i++) { - if (virHostdevIsVFIODevice(def->hostdevs[i]) || + if (virHostdevIsPCIDevice(def->hostdevs[i]) || virHostdevIsMdevDevice(def->hostdevs[i])) n++; } @@ -10526,7 +10526,7 @@ qemuDomainSupportsVideoVga(const virDomainVideoDef *video, bool qemuDomainNeedsVFIO(const virDomainDef *def) { - return virDomainDefHasVFIOHostdev(def) || + return virDomainDefHasPCIHostdev(def) || virDomainDefHasMdevHostdev(def) || virDomainDefHasNVMeDisk(def); } diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 4992c23ee0..15b543dbff 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -133,7 +133,7 @@ qemuHostdevUpdateActiveDomainDevices(virQEMUDriver *driver, bool qemuHostdevNeedsVFIO(const virDomainHostdevDef *hostdev) { - return virHostdevIsVFIODevice(hostdev) || + return virHostdevIsPCIDevice(hostdev) || virHostdevIsMdevDevice(hostdev); } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 1f7f5bdd26..6b2cdd2c55 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4678,7 +4678,7 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver, virDomainAuditHostdev(vm, hostdev, "detach", true); - if (!virHostdevIsVFIODevice(hostdev) && + if (!virHostdevIsPCIDevice(hostdev) && qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0) VIR_WARN("Failed to restore host device labelling"); -- 2.41.0

This patch makes it possible to manually specify which VFIO variant driver to use for PCI hostdev device assignment, so that, e.g. you could force use of the generic vfio-pci driver with <driver name='vfio-pci'/> when libvirt would have normally found a "better match" for a device in the active kernel's modules.alias file. (The main use of this manual override would be to work around a bug in a new VFIO variant driver by temporarily not using that driver). This sounds like a simple addition to XML parsing/formatting, but of course it's messier than that, since the attribute we want to use was previously used in config for a now non-existent purpose (choosing a type of device assignment that was removed from the kernel nearly a decade ago), and continues to be used *internal to the C code*. Background: Beginning when VFIO device assignment support was added to <hostdev> or <interface type='hostdev'/>) in libvirt's QEMU driver, it was possible to specify which device assignment backend to use with "<driver name='vfio|kvm'/>". This was only useful for a couple of years in the early 2010's when VFIO device assignment was newly introduced, but "legacy KVM" device assignment was still possible (in reality "<driver name='blah'/>" was only intended to be used (1) in the *very* early days of VFIO when "kvm" was still the default, (2) when the host kernel was too old to have VFIO support (meaning it was e.g. pre-RHEL7) or (3) some bug was encountered with the then-new VFIO code that could have been avoided by switching back to the older style of device assignment (I don't recall anyone ever needing to set it for this reason, but that is one of the main reasons we added the knob). Later, when the libxl (Xen) driver in libvirt began supporting "device passthrough" with <hostdev>, they added <driver name='xen'/> to indicate that mode of operation. But in practice this was also never necessary in any config, since Xen only supports one type of device assignment, and so the attribute was anyway set in the C object by the libxl driver code prior to calling any hypervisor-common code (i.e. the stuff in hypervisor/hostdev.c and util/virpci.c) that needs to know which type of device assignment is being used - setting it in the XML config was superfluous (kind of like me saying "I am now describing this patch in a human language", ref: Perd Hapley on "Parks and Recreation"). So the setting was available in the XML, but never needed to be set by the user. Because it was automatically set in the C code though, sometimes libvirt-generated XML would contain the option even though the user hadn't included it in the original input XML (e.g. the libxl driver sets it in the PostParse, so all saved configs with a PCI <hostdev> device will have <driver name='xen'/>; also status XML from the QEMU and libxl drivers will contain <driver name='vfio|xen'/> - in both cases completely unnecessary and redundant information). When adding support for specifying a variant driver for VFIO device assignment, from the beginning I have wanted to use <driver name='blah'/> to force a specific variant driver (e.g. <driver name='mlx5_vfio_pci'/>), with the assumption that the name attribute could be easily repurposed because it had been *completely* unused for so long. What I discovered though, was that 1) the field in the C object corresponding to driver name was an enum value rather than a string (so parser and formatter need to be changed, not just the driver code looking at a string in the C object), and 2) even though the XML attribute was effectively unused (except in some output), the field in the C object was *always* being set internally as a way for the hypervisor driver code to inform the hypervisor-common hostdev manager (in src/hypervisor) which method of device assignment to use. So re-use wasn't as simple as I'd wished. However. What I have hit upon that permits us to use <driver name='mlx5_vfio_pci'/> is to do the following: 1) rename the existing driver name attribute to driver *type* - this will now be the enum that is set internally by the hypervisor driver prior to calling the hostdev manager (and also is what will show up in status XML; the libxl driver was modified in a previous patch so that the setting isn't done until domain runtime (rather than during PostParse), so it will no longer show up in regurgitated libxml config) 2) add a new attribute with the now-newly-unused name "name" - this will be a string that can be used to communicate a specific host kernel driver to the hostdev manager. 3) In the parsing code for <driver>, if <driver name='vfio|xen|kvm'/> is encountered, set the driver *type* to the appropriate enum instead, and clear our the name string. (since the four places that use the hostdev <driver> element now all call a common parser function, this check is only needed in a single place) I could alternately just leave "name" as-is, and create a new attribute with a never-before-used name within driver. I suppose instead of "type" and "name", we could instead have "name and "model" (where "model" would be the string that could be set to "mlx5_vfio_pci"). I just prefer type/name to name/model, and think it's been long enough since <driver name='blah'/> has had a useful purpose (and the fixup for backward compatibility is limited to a few lines in one function) that this change is safe. (another alternate would be to add an extra parameter to the C API that calls into the hostdev manager rather than keeping/adding the publicly visible "type" attribute, but it seems at least possible that sometime in the future another alternate "type" of device assignment could be introduced for either Xen or QEMU, and we would then need to add back the XML attribute anyway) I'd be fine with doing it one of the other ways, but decided to post this way first, since it's the one that I find the most aesthetically pleasing :-) Note that a few test cases have been modified - places where an existing "name='vfio'" were changed to "type='vfio'" were in in status XML or only the *output* XML for a test (except the case of the virnetworkportxml2xmltest, which doesn't have a separate directory for the XML result; fortunately the converged parsing of <driver> between domain/network/networkport means that the test cases for network and domain XML are already testing the same code that would convert "name" to "type" in thte networkport XML) Signed-off-by: Laine Stump <laine@redhat.com> --- src/conf/device_conf.c | 29 +++++++++++++++++-- src/conf/device_conf.h | 4 +++ src/conf/domain_conf.c | 1 + src/conf/network_conf.c | 2 ++ src/conf/schemas/basictypes.rng | 21 +++++++++----- src/conf/virnetworkportdef.c | 1 + tests/networkxml2xmlin/hostdev-pf-old.xml | 8 +++++ tests/networkxml2xmlin/hostdev-pf.xml | 2 +- tests/networkxml2xmlout/hostdev-pf-old.xml | 8 +++++ tests/networkxml2xmlout/hostdev-pf.xml | 2 +- tests/networkxml2xmltest.c | 6 ++++ .../qemuhotplug-hostdev-pci.xml | 1 - .../qemuhotplug-base-live+hostdev-pci.xml | 2 +- ...uhotplug-pseries-base-live+hostdev-pci.xml | 2 +- tests/qemustatusxml2xmldata/modern-in.xml | 2 +- .../hostdev-vfio.x86_64-latest.args | 5 +++- tests/qemuxml2argvdata/hostdev-vfio.xml | 18 ++++++++++++ .../hostdev-vfio.x86_64-latest.xml | 23 ++++++++++++++- .../plug-hostdev-pci-unmanaged.xml | 2 +- .../plug-hostdev-pci.xml | 2 +- 20 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 tests/networkxml2xmlin/hostdev-pf-old.xml create mode 100644 tests/networkxml2xmlout/hostdev-pf-old.xml diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index e022783816..2ad7232678 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -60,13 +60,29 @@ int virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node, virDeviceHostdevPCIDriverInfo *driver) { - if (virXMLPropEnum(node, "name", + if (virXMLPropEnum(node, "type", virDeviceHostdevPCIDriverTypeFromString, VIR_XML_PROP_NONZERO, &driver->type) < 0) { return -1; } + driver->name = virXMLPropString(node, "name"); + + /* translate special case of <driver name='vfio|xen|kvm'/> to + * <driver type='vfio|xen|kvm'/> for backward compatibility + */ + if (STREQ_NULLABLE(driver->name, "vfio")) { + driver->type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_VFIO; + VIR_FREE(driver->name); + } else if (STREQ_NULLABLE(driver->name, "xen")) { + driver->type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_XEN; + VIR_FREE(driver->name); + } else if (STREQ_NULLABLE(driver->name, "kvm")) { + driver->type = VIR_DEVICE_HOSTDEV_PCI_DRIVER_TYPE_KVM; + VIR_FREE(driver->name); + } + return 0; } @@ -88,14 +104,23 @@ virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, return -1; } - virBufferAsprintf(&driverAttrBuf, " name='%s'", driverType); + virBufferAsprintf(&driverAttrBuf, " type='%s'", driverType); } + virBufferEscapeString(&driverAttrBuf, " name='%s'", driver->name); + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); return 0; } +void +virDeviceHostdevPCIDriverInfoClear(virDeviceHostdevPCIDriverInfo *driver) +{ + VIR_FREE(driver->name); +} + + static int virZPCIDeviceAddressParseXML(xmlNodePtr node, virPCIDeviceAddress *addr) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 9f4b9f5375..cccc60cb29 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -46,6 +46,7 @@ VIR_ENUM_DECL(virDeviceHostdevPCIDriver); struct _virDeviceHostdevPCIDriverInfo { virDeviceHostdevPCIDriverType type; + char *name; }; typedef enum { @@ -192,6 +193,9 @@ int virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node, int virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, const virDeviceHostdevPCIDriverInfo *driver); +void virDeviceHostdevPCIDriverInfoPostParse(virDeviceHostdevPCIDriverInfo *driver); +void virDeviceHostdevPCIDriverInfoClear(virDeviceHostdevPCIDriverInfo *driver); + void virDomainDeviceInfoClear(virDomainDeviceInfo *info); void virDomainDeviceInfoFree(virDomainDeviceInfo *info); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index eb2df9f30a..3c39257af0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2635,6 +2635,7 @@ virDomainHostdevDefClear(virDomainHostdevDef *def) VIR_FREE(def->source.subsys.u.scsi_host.wwpn); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + virDeviceHostdevPCIDriverInfoClear(&def->source.subsys.u.pci.driver); g_clear_pointer(&def->source.subsys.u.pci.origstates, virBitmapFree); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 43e7c78e95..4a2d887c77 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -229,6 +229,8 @@ virNetworkForwardDefClear(virNetworkForwardDef *def) { size_t i; + virDeviceHostdevPCIDriverInfoClear(&def->driver); + for (i = 0; i < def->npfs && def->pfs; i++) virNetworkForwardPfDefClear(&def->pfs[i]); VIR_FREE(def->pfs); diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng index 8d5f4475ca..46e8a493f7 100644 --- a/src/conf/schemas/basictypes.rng +++ b/src/conf/schemas/basictypes.rng @@ -658,13 +658,20 @@ <define name="hostdevDriver"> <element name="driver"> - <attribute name="name"> - <choice> - <value>kvm</value> - <value>vfio</value> - <value>xen</value> - </choice> - </attribute> + <optional> + <attribute name="type"> + <choice> + <value>kvm</value> + <value>vfio</value> + <value>xen</value> + </choice> + </attribute> + </optional> + <optional> + <attribute name="name"> + <ref name="genericName"/> + </attribute> + </optional> <empty/> </element> </define> diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c index 67911e498e..db15729044 100644 --- a/src/conf/virnetworkportdef.c +++ b/src/conf/virnetworkportdef.c @@ -64,6 +64,7 @@ virNetworkPortDefFree(virNetworkPortDef *def) break; case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI: + virDeviceHostdevPCIDriverInfoClear(&def->plug.hostdevpci.driver); break; case VIR_NETWORK_PORT_PLUG_TYPE_LAST: diff --git a/tests/networkxml2xmlin/hostdev-pf-old.xml b/tests/networkxml2xmlin/hostdev-pf-old.xml new file mode 100644 index 0000000000..5b8f59858c --- /dev/null +++ b/tests/networkxml2xmlin/hostdev-pf-old.xml @@ -0,0 +1,8 @@ +<network> + <name>hostdev</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward mode='hostdev' managed='yes'> + <driver name='vfio'/> + <pf dev='eth2'/> + </forward> +</network> diff --git a/tests/networkxml2xmlin/hostdev-pf.xml b/tests/networkxml2xmlin/hostdev-pf.xml index 5b8f59858c..72a3049800 100644 --- a/tests/networkxml2xmlin/hostdev-pf.xml +++ b/tests/networkxml2xmlin/hostdev-pf.xml @@ -2,7 +2,7 @@ <name>hostdev</name> <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> <forward mode='hostdev' managed='yes'> - <driver name='vfio'/> + <driver type='vfio'/> <pf dev='eth2'/> </forward> </network> diff --git a/tests/networkxml2xmlout/hostdev-pf-old.xml b/tests/networkxml2xmlout/hostdev-pf-old.xml new file mode 100644 index 0000000000..72a3049800 --- /dev/null +++ b/tests/networkxml2xmlout/hostdev-pf-old.xml @@ -0,0 +1,8 @@ +<network> + <name>hostdev</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward mode='hostdev' managed='yes'> + <driver type='vfio'/> + <pf dev='eth2'/> + </forward> +</network> diff --git a/tests/networkxml2xmlout/hostdev-pf.xml b/tests/networkxml2xmlout/hostdev-pf.xml index 5b8f59858c..72a3049800 100644 --- a/tests/networkxml2xmlout/hostdev-pf.xml +++ b/tests/networkxml2xmlout/hostdev-pf.xml @@ -2,7 +2,7 @@ <name>hostdev</name> <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> <forward mode='hostdev' managed='yes'> - <driver name='vfio'/> + <driver type='vfio'/> <pf dev='eth2'/> </forward> </network> diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c index b0814c7529..928f28b579 100644 --- a/tests/networkxml2xmltest.c +++ b/tests/networkxml2xmltest.c @@ -146,6 +146,12 @@ mymain(void) DO_TEST_FLAGS("passthrough-pf", VIR_NETWORK_XML_INACTIVE); DO_TEST("hostdev"); DO_TEST_FLAGS("hostdev-pf", VIR_NETWORK_XML_INACTIVE); + + /* libvirt pre-9.9.0 used "name='vfio'" which should be + * automatically translated to "type='vfio'" by new parser + */ + DO_TEST_FLAGS("hostdev-pf-old", VIR_NETWORK_XML_INACTIVE); + DO_TEST("passthrough-address-crash"); DO_TEST("nat-network-explicit-flood"); DO_TEST("host-bridge-no-flood"); diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-hostdev-pci.xml b/tests/qemuhotplugtestdevices/qemuhotplug-hostdev-pci.xml index 6f7c99c943..0d6dec9d26 100644 --- a/tests/qemuhotplugtestdevices/qemuhotplug-hostdev-pci.xml +++ b/tests/qemuhotplugtestdevices/qemuhotplug-hostdev-pci.xml @@ -1,5 +1,4 @@ <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> </source> diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+hostdev-pci.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+hostdev-pci.xml index e49e21c53e..b14f184044 100644 --- a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+hostdev-pci.xml +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+hostdev-pci.xml @@ -49,7 +49,7 @@ </input> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> + <driver type='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> </source> diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+hostdev-pci.xml b/tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+hostdev-pci.xml index 13d10e57aa..02b66a3590 100644 --- a/tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+hostdev-pci.xml +++ b/tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+hostdev-pci.xml @@ -41,7 +41,7 @@ </input> <audio id='1' type='none'/> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> + <driver type='vfio'/> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> </source> diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxml2xmldata/modern-in.xml index 67e0aa4952..299046331e 100644 --- a/tests/qemustatusxml2xmldata/modern-in.xml +++ b/tests/qemustatusxml2xmldata/modern-in.xml @@ -502,7 +502,7 @@ <address type='drive' controller='0' bus='0' target='2' unit='4'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> - <driver name='vfio'/> + <driver type='vfio'/> <source> <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/> <origstates> diff --git a/tests/qemuxml2argvdata/hostdev-vfio.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-vfio.x86_64-latest.args index c1f9258844..8529cde269 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio.x86_64-latest.args +++ b/tests/qemuxml2argvdata/hostdev-vfio.x86_64-latest.args @@ -32,6 +32,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.config \ -device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -device '{"driver":"vfio-pci","host":"0000:06:12.1","id":"hostdev0","bus":"pci.0","addr":"0x2"}' \ --device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \ +-device '{"driver":"vfio-pci","host":"0000:06:12.2","id":"hostdev1","bus":"pci.0","addr":"0x3"}' \ +-device '{"driver":"vfio-pci","host":"0000:06:12.3","id":"hostdev2","bus":"pci.0","addr":"0x4"}' \ +-device '{"driver":"vfio-pci","host":"0000:06:12.4","id":"hostdev3","bus":"pci.0","addr":"0x5"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x6"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/hostdev-vfio.xml b/tests/qemuxml2argvdata/hostdev-vfio.xml index a03870f6e0..609714ab06 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio.xml @@ -29,6 +29,24 @@ <address domain='0x0000' bus='0x06' slot='0x12' function='0x1'/> </source> </hostdev> + <hostdev mode='subsystem' type='pci' managed='yes'> + <driver type='vfio'/> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='pci' managed='yes'> + <driver name='vfio'/> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x3'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='pci' managed='yes'> + <driver name='vfio-pci-igb'/> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x4'/> + </source> + </hostdev> <memballoon model='virtio'/> </devices> </domain> diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml index 3915b515f2..bae07de8d2 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml @@ -39,8 +39,29 @@ </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </hostdev> - <memballoon model='virtio'> + <hostdev mode='subsystem' type='pci' managed='yes'> + <driver type='vfio'/> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x2'/> + </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </hostdev> + <hostdev mode='subsystem' type='pci' managed='yes'> + <driver type='vfio'/> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x3'/> + </source> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </hostdev> + <hostdev mode='subsystem' type='pci' managed='yes'> + <driver name='vfio-pci-igb'/> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x4'/> + </source> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </hostdev> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </memballoon> </devices> </domain> diff --git a/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml b/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml index da5f568031..5d9f7cae73 100644 --- a/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml +++ b/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml @@ -6,7 +6,7 @@ </owner> <mac address='52:54:00:7b:35:93'/> <plug type='hostdev-pci' managed='no'> - <driver name='vfio'/> + <driver type='vfio'/> <address domain='0x0001' bus='0x02' slot='0x03' function='0x4'/> </plug> </networkport> diff --git a/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml b/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml index cc4419f3fd..d216fc916e 100644 --- a/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml +++ b/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml @@ -6,7 +6,7 @@ </owner> <mac address='52:54:00:7b:35:93'/> <plug type='hostdev-pci' managed='yes'> - <driver name='vfio'/> + <driver type='vfio'/> <address domain='0x0001' bus='0x02' slot='0x03' function='0x4'/> </plug> </networkport> -- 2.41.0

Add a surprisingly missing simple function to the arsenal. Signed-off-by: Laine Stump <laine@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virstring.c | 17 +++++++++++++++++ src/util/virstring.h | 1 + 3 files changed, 19 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a943a79e01..3e8eded81e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3409,6 +3409,7 @@ virSkipSpaces; virSkipSpacesAndBackslash; virSkipSpacesBackwards; virSkipToDigit; +virSkipToSpace; virStrcpy; virStringBufferIsPrintable; virStringFilterChars; diff --git a/src/util/virstring.c b/src/util/virstring.c index 6b728ff047..4a732de5dc 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -441,6 +441,23 @@ virSkipToDigit(const char **str) } +/** + * virSkipToSApace: + * @str: pointer to the char pointer used + * + * Skip over any character that is not whitespace + */ +void +virSkipToSpace(const char **str) +{ + const char *cur = *str; + + while (*cur && !g_ascii_isspace(*cur)) + cur++; + *str = cur; +} + + /** * virTrimSpaces: * @str: string to modify to remove all trailing spaces diff --git a/src/util/virstring.h b/src/util/virstring.h index 16dcce98f4..9fd8be44cf 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -74,6 +74,7 @@ int virDoubleToStr(char **strp, double number) void virSkipSpaces(const char **str) ATTRIBUTE_NONNULL(1); void virSkipSpacesAndBackslash(const char **str) ATTRIBUTE_NONNULL(1); void virSkipToDigit(const char **str) ATTRIBUTE_NONNULL(1); +void virSkipToSpace(const char **str) ATTRIBUTE_NONNULL(1); void virTrimSpaces(char *str, char **endp) ATTRIBUTE_NONNULL(1); void virSkipSpacesBackwards(const char *str, char **endp) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -- 2.41.0

This function reads the modalias file for the given device from sysfs, then looks through /lib/modules/${kernel_release}/modules.alias for the vfio_pci alias that matches with the least number of wildcard ('*') fields. This can be used to find an appropriate "VFIO variant" driver for a device (it will be the PCI driver implemented by the discovered module) - these drivers are compatible with (and provide the entire API of) the standard vfio-pci driver, but have additional device-specific APIs that can be useful for, e.g., saving/restoring state for migration. Signed-off-by: Laine Stump <laine@redhat.com> --- src/util/virpci.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++ src/util/virpci.h | 2 + 2 files changed, 226 insertions(+) diff --git a/src/util/virpci.c b/src/util/virpci.c index 513ae948c0..70fcedc4a5 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -30,6 +30,10 @@ #include <sys/stat.h> #include <unistd.h> +#ifndef WIN32 +# include <sys/utsname.h> +#endif + #include "virlog.h" #include "virerror.h" #include "virfile.h" @@ -1539,6 +1543,226 @@ virPCIDeviceReattach(virPCIDevice *dev, return 0; } + +#ifndef WIN32 +typedef struct { + /* this is the decomposed version of a string like: + * + * vNNNNNNNNdNNNNNNNNsvNNNNNNNNsdNNNNNNNNbcNNscNNiNN + * + * (followed by a space or newline). The "NNNN" are always of the + * length in the example unless replaced with a wildcard ("*"), + * but we make no assumptions about length. + * + * Rather than name each field, we just put them + * all in an array of 6 elements, so that we + * can write a simple loop to compare them + */ + char *fields[7]; /* v, d, sv, sd, bc, sc, i */ +} virPCIDeviceAliasInfo; + + +/* NULL in last position makes parsing loop simpler */ +static const char *fieldnames[] = { "v", "d", "sv", "sd", "bc", "sc", "i", NULL }; + + +static void +virPCIDeviceAliasInfoFree(virPCIDeviceAliasInfo *info) +{ + if (info) { + size_t i; + + for (i = 0; i < G_N_ELEMENTS(info->fields); i++) + g_free(info->fields[i]); + + g_free(info); + } +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceAliasInfo, virPCIDeviceAliasInfoFree); + + +static virPCIDeviceAliasInfo * +virPCIDeviceAliasInfoNew(const char *str) +{ + const char *field = str; + + size_t i; + g_autoptr(virPCIDeviceAliasInfo) ret = g_new0(virPCIDeviceAliasInfo, 1); + + if (!str) + return g_steal_pointer(&ret); + + /* initialize from str */ + for (i = 0; i < G_N_ELEMENTS(ret->fields); i++) { + int len = strlen(fieldnames[i]); + const char *next; + + if (strncmp(field, fieldnames[i], len)) + return NULL; + + field += len; + if (fieldnames[i + 1]) { + if (!(next = strstr(field, fieldnames[i + 1]))) + return NULL; + } else { + next = field; + virSkipToSpace(&next); + } + + ret->fields[i] = g_strndup(field, next - field); + field = next; + } + + return g_steal_pointer(&ret); +} + + +static void +virPCIDeviceAliasInfoPrint(virPCIDeviceAliasInfo *info) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS(info->fields); i++) + VIR_DEBUG("%s: '%s'", fieldnames[i], info->fields[i]); +} + + +static bool +virPCIDeviceAliasInfoMatch(virPCIDeviceAliasInfo *orig, + virPCIDeviceAliasInfo *match, + int *wildCardCt) +{ + size_t i; + + *wildCardCt = 0; + + for (i = 0; i < G_N_ELEMENTS(orig->fields); i++) { + if (STREQ(match->fields[i], "*")) + (*wildCardCt)++; + else if (STRNEQ(orig->fields[i], match->fields[i])) + return false; + } + return true; +} + + +/* virPCIDeviceFindBestVFIOVariant: + * + * Find the "best" match of all vfio_pci aliases for @dev in the host + * modules.alias file. This uses the algorithm of finding every + * modules.alias line that begins with "vfio_pci:", then picking the + * one that matches the device's own modalias value (from the file of + * that name in the device's sysfs directory) with the fewest + * "wildcards" (* character, meaning "match any value for this + * attribute"). + */ +int +virPCIDeviceFindBestVFIOVariant(virPCIDevice *dev, + char **moduleName) +{ + g_autofree char *devModAliasPath = NULL; + g_autofree char *devModAliasContent = NULL; + const char *devModAlias; + g_autoptr(virPCIDeviceAliasInfo) devModAliasInfo = NULL; + struct utsname unameInfo; + g_autofree char *modulesAliasPath = NULL; + g_autofree char *modulesAliasContent = NULL; + const char *line; + int currentBestWildcardCt = INT_MAX; + + *moduleName = NULL; + + /* get the modalias values for the device from sysfs */ + devModAliasPath = virPCIFile(dev->name, "modalias"); + if (virFileReadAll(devModAliasPath, 100, &devModAliasContent) < 0) + return 0; + + VIR_DEBUG("modalias path: '%s' contents: '%s'", + devModAliasPath, devModAliasContent); + + /* "pci:vNNNNNNNNdNNNNNNNNsvNNNNNNNNsdNNNNNNNNbcNNscNNiNN\n" */ + if ((devModAlias = STRSKIP(devModAliasContent, "pci:")) == NULL || + !(devModAliasInfo = virPCIDeviceAliasInfoNew(devModAlias))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device modalias file %1$s content has improper format"), + devModAliasPath); + return -1; + } + + virPCIDeviceAliasInfoPrint(devModAliasInfo); + + uname(&unameInfo); + modulesAliasPath = g_strdup_printf("/lib/modules/%s/modules.alias", + unameInfo.release); + if (virFileReadAll(modulesAliasPath, + 4 * 1024 * 1024, &modulesAliasContent) < 0) { + return -1; + } + + /* Look for all lines that are aliases for vfio_pci drivers. + * (The first line is always a comment, so we can be sure "alias" + * is preceded by a newline) + */ + line = modulesAliasContent; + + while ((line = strstr(line, "\nalias vfio_pci:"))) { + g_autoptr(virPCIDeviceAliasInfo) fileModAliasInfo = NULL; + int wildCardCt; + + /* "alias vfio_pci:vNNNNNNNNdNNNNNNNNsvNNNNNNNNsdNNNNNNNNbcNNscNNiNN XXXX\n" */ + line += strlen("\nalias vfio_pci:"); + if (!(fileModAliasInfo = virPCIDeviceAliasInfoNew(line))) + continue; + + virPCIDeviceAliasInfoPrint(fileModAliasInfo); + + if (virPCIDeviceAliasInfoMatch(devModAliasInfo, + fileModAliasInfo, &wildCardCt)) { + + const char *aliasStart = strchr(line, ' '); + const char *aliasEnd = NULL; + g_autofree char *aliasName = NULL; + + if (!aliasStart) { + VIR_WARN("malformed modules.alias vfio_pci: line"); + continue; + } + + aliasStart++; + line = aliasEnd = strchrnul(aliasStart, '\n'); + aliasName = g_strndup(aliasStart, aliasEnd - aliasStart); + + VIR_DEBUG("matching alias '%s' found, %d wildcards", + aliasName, wildCardCt); + + if (wildCardCt < currentBestWildcardCt) { + + /* this is a better match than previous */ + currentBestWildcardCt = wildCardCt; + g_free(*moduleName); + *moduleName = g_steal_pointer(&aliasName); + } + } + } + return 0; +} + + +#else /* WIN32 */ + + +int +virPCIDeviceFindBestVFIOVariant(virPCIDevice *dev G_GNUC_UNUSED, + char **moduleName G_GNUC_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("VFIO device assignment is not available on this platform")); + return -1; +} +#endif /* WIN32 */ + + static char * virPCIDeviceReadID(virPCIDevice *dev, const char *id_name) { diff --git a/src/util/virpci.h b/src/util/virpci.h index faca6cf6f9..ca94145207 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -286,6 +286,8 @@ int virPCIDeviceGetCurrentDriverPathAndName(virPCIDevice *dev, int virPCIDeviceGetCurrentDriverNameAndType(virPCIDevice *dev, char **drvName, virPCIStubDriver *drvType); +int virPCIDeviceFindBestVFIOVariant(virPCIDevice *dev, + char **driverName); int virPCIDeviceIsPCIExpress(virPCIDevice *dev); int virPCIDeviceHasPCIExpressLink(virPCIDevice *dev); -- 2.41.0

Rather than always binding to the vfio-pci driver, use virPCIDeviceFindBestVFIOVariant() to see if the running kernel has a VFIO variant driver available that is a better match for the device, and if one is found, use that instead. If a specific driver is named, that will still be used; this makes it possible to force binding of vfio-pci if there is an issue with the auto-selected variant driver. Signed-off-by: Laine Stump <laine@redhat.com> --- src/util/virpci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/util/virpci.c b/src/util/virpci.c index 70fcedc4a5..ff5349b70d 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -1426,6 +1426,7 @@ static int virPCIDeviceBindToStub(virPCIDevice *dev) { g_autofree char *stubDriverPath = NULL; + g_autofree char *autodetectModuleName = NULL; g_autofree char *driverLink = NULL; @@ -1436,6 +1437,20 @@ virPCIDeviceBindToStub(virPCIDevice *dev) return -1; } + if (dev->stubDriverType == VIR_PCI_STUB_DRIVER_VFIO + && !dev->stubDriverName) { + /* automatically use a VFIO variant driver if available for + * this device. + */ + + if (virPCIDeviceFindBestVFIOVariant(dev, &autodetectModuleName) < 0) + return -1; + + g_free(dev->stubDriverName); + dev->stubDriverName = g_steal_pointer(&autodetectModuleName); + } + + /* if a driver name hasn't been decided by now, use default for this type */ if (!dev->stubDriverName) { const char *stubDriverName = NULL; -- 2.41.0
participants (2)
-
Jason Gunthorpe
-
Laine Stump