From nobody Mon Feb 9 10:27:18 2026 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1704445131172566.8709556693982; Fri, 5 Jan 2024 00:58:51 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id 18E8B19B1; Fri, 5 Jan 2024 03:58:50 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id B3F72199E; Fri, 5 Jan 2024 03:22:10 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 3512717FE; Fri, 5 Jan 2024 03:20:32 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 82F80182A for ; Fri, 5 Jan 2024 03:20:21 -0500 (EST) Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-522-4ocsK9-LOs2KbnDT7vSSkQ-1; Fri, 05 Jan 2024 03:20:19 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 33DD438425B2 for ; Fri, 5 Jan 2024 08:20:19 +0000 (UTC) Received: from vhost3.router.laine.org (unknown [10.22.16.86]) by smtp.corp.redhat.com (Postfix) with ESMTP id 189B52026D6F; Fri, 5 Jan 2024 08:20:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: 4ocsK9-LOs2KbnDT7vSSkQ-1 From: Laine Stump To: devel@lists.libvirt.org Subject: [PATCH v3 12/13] conf: support manually specifying VFIO variant driver in XML Date: Fri, 5 Jan 2024 03:20:15 -0500 Message-ID: <20240105082016.281442-13-laine@redhat.com> In-Reply-To: <20240105082016.281442-1-laine@redhat.com> References: <20240105082016.281442-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: PL4EG3PYJDV7LF56JEOOWSOEMX5GZ5GJ X-Message-ID-Hash: PL4EG3PYJDV7LF56JEOOWSOEMX5GZ5GJ X-MailFrom: laine@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Peter Krempa X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8"; x-default="true" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1704445133130100001 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 a VFIO "variant" driver, with e.g. or alternately to force use of the generic vfio-pci driver with when libvirt would have normally (after applying a subsequent patch) found a "better match" for a device in the active kernel's modules.alias file. (The main potential use of this manual override would probably be to work around a bug in a new VFIO variant driver by temporarily not using that driver). Signed-off-by: Laine Stump Reviewed-by: Peter Krempa --- Change from V2: use new instead of repurposing existing docs/formatdomain.rst | 54 +++++++++++++------ docs/formatnetwork.rst | 21 ++++---- src/conf/device_conf.c | 10 ++++ src/conf/device_conf.h | 4 ++ src/conf/domain_conf.c | 3 ++ src/conf/network_conf.c | 2 + src/conf/schemas/basictypes.rng | 21 +++++--- src/conf/virnetworkportdef.c | 1 + src/network/bridge_driver.c | 1 + tests/networkxml2xmlin/hostdev-pf-old.xml | 8 +++ tests/networkxml2xmlout/hostdev-pf-old.xml | 8 +++ tests/networkxml2xmltest.c | 6 +++ .../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 | 1 - .../plug-hostdev-pci.xml | 1 - 17 files changed, 148 insertions(+), 39 deletions(-) create mode 100644 tests/networkxml2xmlin/hostdev-pf-old.xml create mode 100644 tests/networkxml2xmlout/hostdev-pf-old.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c08033f940..36c74d9eae 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4500,24 +4500,46 @@ or: an error. See the `Device Addresses`_ section for more details on the a= ddress element. ``driver`` - PCI devices can have an optional ``driver`` subelement that specifies w= hich - backend driver to use for PCI device assignment. Use the ``name`` attri= bute - to select either "vfio" (for the new VFIO device assignment backend, wh= ich is - compatible with UEFI SecureBoot) or "kvm" (the legacy device assignment - handled directly by the KVM kernel module) :since:`Since 1.0.5 (QEMU an= d KVM - only, requires kernel 3.6 or newer)` . When specified, device assignmen= t will - fail if the requested method of device assignment isn't available on the - host. When not specified, the default is "vfio" on systems where the VF= IO - driver is available and loaded, and "kvm" on older systems, or those wh= ere - the VFIO driver hasn't been loaded :since:`Since 1.1.3` (prior to that = the - default was always "kvm"). + PCI hostdev devices can have an optional ``driver`` subelement that + specifies which host driver to bind to the device when preparing it + for assignment to a guest. :since:`Since 10.0.0 (useful for QEMU and + KVM only)`. This is done by setting the ```` element's ``model`` + attribute, for example:: + + ... + + + ... + + tells libvirt to bind the driver "vfio-pci-igb" to the device on + the host before handing it off to QEMU for assignment to the + guest. Normally libvirt will bind the device to the "best match" + VFIO-type driver that it finds in the kernel's modules.alias file + (based on matching the corresponding fields of the device's + modalias file in sysfs) or to the generic "vfio-pci" driver if no + better match is found (vfio-pci is always used prior to libvirt + 10.0.0), but in cases when the correct driver isn't listed in + modules.alias then the desired device-specific driver can be forced + by setting driver name, or if the device-specific driver that is + found is "problematic" in some way, the generic vfio-pci driver + similarly be forced. + + (Note: :since:`Since 1.0.5, the ``name`` attribute has been + described to be used to select the type of PCI device assignment + ("vfio", "kvm", or "xen"), but those values have been mostly + useless, since the type of device assignment is actually determined + by which hypservisor is in use. This means that you may + occasionally see ```` or ```` in a domain's status XML, or more rarely in config, + but those specific values are essentially ignored.) + ``readonly`` - Indicates that the device is readonly, only supported by SCSI host devi= ce - now. :since:`Since 1.0.6 (QEMU and KVM only)` + Indicates that the device is readonly, only supported by SCSI host + device now. :since:`Since 1.0.6 (QEMU and KVM only)` ``shareable`` - If present, this indicates the device is expected to be shared between - domains (assuming the hypervisor and OS support this). Only supported b= y SCSI - host device. :since:`Since 1.0.6` + If present, this indicates the device is expected to be shared + between domains (assuming the hypervisor and OS support this). Only + supported by SCSI host device. :since:`Since 1.0.6` =20 Note: Although ``shareable`` was introduced :since:`in 1.0.6` , it did = not work as as expected until :since:`1.2.2` . diff --git a/docs/formatnetwork.rst b/docs/formatnetwork.rst index 5d300a035e..d4181ac029 100644 --- a/docs/formatnetwork.rst +++ b/docs/formatnetwork.rst @@ -315,17 +315,14 @@ to the physical LAN (if at all). guest, use the traditional ```` device definition. :since:`= Since 0.10.0` =20 - To force use of a particular type of device assignment, a interface can have an optional ``driver`` sub-elem= ent with - a ``name`` attribute set to either "vfio" (VFIO is a new method of d= evice - assignment that is compatible with UEFI Secure Boot) or "kvm" (the l= egacy - device assignment handled directly by the KVM kernel module) :since:= `Since - 1.0.5 (QEMU and KVM only, requires kernel 3.6 or newer)` . When spec= ified, - device assignment will fail if the requested method of device assign= ment - isn't available on the host. When not specified, the default is "vfi= o" on - systems where the VFIO driver is available and loaded, and "kvm" on = older - systems, or those where the VFIO driver hasn't been loaded :since:`S= ince - 1.1.3` (prior to that the default was always "kvm"). + To force use of a particular device-specific VFIO driver when + assigning the devices to a guest, a + interface can have an optional ``driver`` sub-element with a + ``model`` attribute set to the name of the driver to use + :since:`Since 10.0.0 (QEMU only)`. When not specified, libvirt + will attempt to find a suitable VFIO variant driver for the + device, and if not found it will use the generic driver + "vfio-pci". =20 Note that this "intelligent passthrough" of network devices is very similar to the functionality of a standard ```` device, the @@ -337,7 +334,7 @@ to the physical LAN (if at all). to the guest domain), or if you are using a version of libvirt older= than 0.10.0, you should use a standard ```` device definition in= the domain's configuration to assign the device to the guest instead of - defining an ```` pointing to= a + defining an ```` pointing to a network with ````. =20 As mentioned above, a ```` element can have multiple ```` diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 68a8c7690a..f840efc1b5 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -67,6 +67,7 @@ virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node, return -1; } =20 + driver->model =3D virXMLPropString(node, "model"); return 0; } =20 @@ -90,11 +91,20 @@ virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " name=3D'%s'", driverName); } =20 + virBufferEscapeString(&driverAttrBuf, " model=3D'%s'", driver->model); + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); return 0; } =20 =20 +void +virDeviceHostdevPCIDriverInfoClear(virDeviceHostdevPCIDriverInfo *driver) +{ + VIR_FREE(driver->model); +} + + static int virZPCIDeviceAddressParseXML(xmlNodePtr node, virPCIDeviceAddress *addr) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 0b3f17a3aa..2d674ecd85 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -46,6 +46,7 @@ VIR_ENUM_DECL(virDeviceHostdevPCIDriverName); =20 struct _virDeviceHostdevPCIDriverInfo { virDeviceHostdevPCIDriverName name; + char *model; }; =20 typedef enum { @@ -192,6 +193,9 @@ int virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr no= de, int virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, const virDeviceHostdevPCIDriverInf= o *driver); =20 +void virDeviceHostdevPCIDriverInfoPostParse(virDeviceHostdevPCIDriverInfo = *driver); +void virDeviceHostdevPCIDriverInfoClear(virDeviceHostdevPCIDriverInfo *dri= ver); + void virDomainDeviceInfoClear(virDomainDeviceInfo *info); void virDomainDeviceInfoFree(virDomainDeviceInfo *info); =20 diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0f137543e0..02fd5815cc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2636,6 +2636,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.d= river); g_clear_pointer(&def->source.subsys.u.pci.origstates, virBitma= pFree); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: @@ -29898,6 +29899,7 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDe= f *iface, actual->data.hostdev.def.source.subsys.type =3D VIR_DOMAIN_HOSTDEV= _SUBSYS_TYPE_PCI; actual->data.hostdev.def.source.subsys.u.pci.addr =3D port->plug.h= ostdevpci.addr; actual->data.hostdev.def.source.subsys.u.pci.driver.name =3D port-= >plug.hostdevpci.driver.name; + actual->data.hostdev.def.source.subsys.u.pci.driver.model =3D g_st= rdup(port->plug.hostdevpci.driver.model); break; =20 case VIR_NETWORK_PORT_PLUG_TYPE_LAST: @@ -29999,6 +30001,7 @@ virDomainNetDefActualToNetworkPort(virDomainDef *do= m, port->plug.hostdevpci.managed =3D virTristateBoolFromBool(actual->= data.hostdev.def.managed); port->plug.hostdevpci.addr =3D actual->data.hostdev.def.source.sub= sys.u.pci.addr; port->plug.hostdevpci.driver.name =3D actual->data.hostdev.def.sou= rce.subsys.u.pci.driver.name; + port->plug.hostdevpci.driver.model =3D g_strdup(actual->data.hostd= ev.def.source.subsys.u.pci.driver.model); break; =20 case VIR_DOMAIN_NET_TYPE_CLIENT: diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 890c16b3b1..5c781d06af 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -229,6 +229,8 @@ virNetworkForwardDefClear(virNetworkForwardDef *def) { size_t i; =20 + virDeviceHostdevPCIDriverInfoClear(&def->driver); + for (i =3D 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..b65d210091 100644 --- a/src/conf/schemas/basictypes.rng +++ b/src/conf/schemas/basictypes.rng @@ -658,13 +658,20 @@ =20 - - - kvm - vfio - xen - - + + + + kvm + vfio + xen + + + + + + + + diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c index 49d00b2ea6..64db63ae66 100644 --- a/src/conf/virnetworkportdef.c +++ b/src/conf/virnetworkportdef.c @@ -64,6 +64,7 @@ virNetworkPortDefFree(virNetworkPortDef *def) break; =20 case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI: + virDeviceHostdevPCIDriverInfoClear(&def->plug.hostdevpci.driver); break; =20 case VIR_NETWORK_PORT_PLUG_TYPE_LAST: diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index d156333626..9921c7cd14 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -3931,6 +3931,7 @@ networkAllocatePort(virNetworkObj *obj, } port->plug.hostdevpci.addr =3D dev->device.pci; port->plug.hostdevpci.driver.name =3D netdef->forward.driver.name; + port->plug.hostdevpci.driver.model =3D g_strdup(netdef->forward.dr= iver.model); port->plug.hostdevpci.managed =3D virTristateBoolFromBool(netdef->= forward.managed); =20 if (port->virtPortProfile) { diff --git a/tests/networkxml2xmlin/hostdev-pf-old.xml b/tests/networkxml2x= mlin/hostdev-pf-old.xml new file mode 100644 index 0000000000..5b8f59858c --- /dev/null +++ b/tests/networkxml2xmlin/hostdev-pf-old.xml @@ -0,0 +1,8 @@ + + hostdev + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + diff --git a/tests/networkxml2xmlout/hostdev-pf-old.xml b/tests/networkxml2= xmlout/hostdev-pf-old.xml new file mode 100644 index 0000000000..5b8f59858c --- /dev/null +++ b/tests/networkxml2xmlout/hostdev-pf-old.xml @@ -0,0 +1,8 @@ + + hostdev + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + 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=3D'vfio'" which should be + * automatically translated to "type=3D'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/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=3D/var/lib/libvirt/qemu/domain--1-QEMUGue= st2/.config \ -device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-form= at","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","add= r":"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","add= r":"0x6"}' \ -sandbox on,obsolete=3Ddeny,elevateprivileges=3Ddeny,spawn=3Ddeny,resource= control=3Ddeny \ -msg timestamp=3Don diff --git a/tests/qemuxml2argvdata/hostdev-vfio.xml b/tests/qemuxml2argvda= ta/hostdev-vfio.xml index a03870f6e0..812bac2cfd 100644 --- a/tests/qemuxml2argvdata/hostdev-vfio.xml +++ b/tests/qemuxml2argvdata/hostdev-vfio.xml @@ -29,6 +29,24 @@
+ + + +
+ + + + + +
+ + + + + +
+ + diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml b/test= s/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml index 3915b515f2..2042ba6c16 100644 --- a/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/hostdev-vfio.x86_64-latest.xml @@ -39,8 +39,29 @@
- + + + +
+
+ + + + +
+ +
+ + + + +
+ +
+ + +
diff --git a/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml= b/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml index da5f568031..fa974affee 100644 --- a/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml +++ b/tests/virnetworkportxml2xmldata/plug-hostdev-pci-unmanaged.xml @@ -6,7 +6,6 @@ -
diff --git a/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml b/tests/v= irnetworkportxml2xmldata/plug-hostdev-pci.xml index cc4419f3fd..7354e1d48c 100644 --- a/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml +++ b/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml @@ -6,7 +6,6 @@ -
--=20 2.43.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org