[libvirt PATCH 07/11] conf: Introduce domain iommufd element

Pavel Hrdina via Devel posted 11 patches 4 days, 6 hours ago
[libvirt PATCH 07/11] conf: Introduce domain iommufd element
Posted by Pavel Hrdina via Devel 4 days, 6 hours ago
From: Pavel Hrdina <phrdina@redhat.com>

In addition to configuring IOMMUFD for each host device add
configuration for the whole VM. This will be extended to add support for
passing FD to libvirt from management applications.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
 docs/formatdomain.rst                  | 21 ++++++++++++
 src/conf/domain_conf.c                 | 46 ++++++++++++++++++++++++++
 src/conf/domain_conf.h                 |  2 ++
 src/conf/schemas/domaincommon.rng      | 12 +++++++
 tests/genericxml2xmlindata/iommufd.xml | 18 ++++++++++
 tests/genericxml2xmltest.c             |  2 ++
 6 files changed, 101 insertions(+)
 create mode 100644 tests/genericxml2xmlindata/iommufd.xml

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 9f245293e6..f6096b2b9b 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1382,6 +1382,27 @@ Block I/O Tuning
    ``write_iops_sec``
       Write I/O operations per second limit. :since:`Since 1.2.2`
 
+Host Device IOMMUFD
+-------------------
+
+::
+
+   <domain>
+     ...
+     <iommufd enabled='yes'/>
+     ...
+   </domain>
+
+``iommufd``
+   :since:`Since 12.2.0 (QEMU/KVM only)` The optional ``iommufd`` element with
+   mandatory ``enabled`` attribute can be used to enable IOMMUFD backned for
+   VFIO host devices. This provides an interface to propagate DMA mappings to
+   kernel for assigned devices. Libvirt will open the /dev/iommu and VFIO device
+   cdev and pass associated file descriptors to QEMU.
+
+   This controls IOMMUFD usage for all host devices, each device can change this
+   global default by setting ``iommufd`` attribute for ``driver`` element.
+
 Resource partitioning
 ---------------------
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 562803ea87..950c755ad9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19883,6 +19883,31 @@ virDomainDefControllersParse(virDomainDef *def,
     return 0;
 }
 
+static int
+virDomainDefIommufdParse(virDomainDef *def,
+                         xmlXPathContextPtr ctxt)
+{
+    int n;
+    g_autofree xmlNodePtr *nodes = NULL;
+
+    if ((n = virXPathNodeSet("./iommufd", ctxt, &nodes)) < 0)
+        return -1;
+
+    if (n > 1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("only one 'iommufd' element is supported"));
+        return -1;
+    }
+
+    if (n == 0)
+        return 0;
+
+    if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0)
+        return -1;
+
+    return 0;
+}
+
 static virDomainDef *
 virDomainDefParseXML(xmlXPathContextPtr ctxt,
                      virDomainXMLOption *xmlopt,
@@ -19961,6 +19986,9 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
         !virDomainIOThreadIDArrayHasPin(def))
         def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
 
+    if (virDomainDefIommufdParse(def, ctxt) < 0)
+        return NULL;
+
     if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0)
         return NULL;
 
@@ -28172,6 +28200,22 @@ virDomainHubDefFormat(virBuffer *buf,
 }
 
 
+static void
+virDomainDefIommufdFormat(virBuffer *buf,
+                          virDomainDef *def)
+{
+    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+
+    if (def->iommufd == VIR_TRISTATE_BOOL_ABSENT)
+        return;
+
+    virBufferAsprintf(&attrBuf, " enabled='%s'",
+                      virTristateBoolTypeToString(def->iommufd));
+
+    virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
+}
+
+
 static void
 virDomainResourceDefFormat(virBuffer *buf,
                            virDomainResourceDef *def)
@@ -29721,6 +29765,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
     if (virDomainNumatuneFormatXML(buf, def->numa) < 0)
         return -1;
 
+    virDomainDefIommufdFormat(buf, def);
+
     virDomainResourceDefFormat(buf, def->resource);
 
     for (i = 0; i < def->nsysinfo; i++) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3b4980394e..f7e2eb6f5e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3244,6 +3244,8 @@ struct _virDomainDef {
     virTristateSwitch apic_eoi;
     virDomainFeatureTCG *tcg_features;
 
+    virTristateBool iommufd;
+
     bool tseg_specified;
     unsigned long long tseg_size;
 
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 376218118d..0436ec8edc 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1025,6 +1025,10 @@
         <ref name="numatune"/>
       </optional>
 
+      <optional>
+        <ref name="iommufd"/>
+      </optional>
+
       <optional>
         <ref name="respartition"/>
       </optional>
@@ -1368,6 +1372,14 @@
     </element>
   </define>
 
+  <define name="iommufd">
+    <element name="iommufd">
+      <attribute name="enabled">
+        <ref name="virYesNo"/>
+      </attribute>
+    </element>
+  </define>
+
   <define name="respartition">
     <element name="resource">
       <optional>
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
new file mode 100644
index 0000000000..63ea839383
--- /dev/null
+++ b/tests/genericxml2xmlindata/iommufd.xml
@@ -0,0 +1,18 @@
+<domain type='kvm'>
+  <name>foo</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufd enabled='yes'/>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+  </devices>
+</domain>
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
index 6757fc44de..6be694cac5 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -263,6 +263,8 @@ mymain(void)
 
     DO_TEST("iothreadids");
 
+    DO_TEST("iommufd");
+
     virObjectUnref(caps);
     virObjectUnref(xmlopt);
 
-- 
2.53.0
Re: [libvirt PATCH 07/11] conf: Introduce domain iommufd element
Posted by Peter Krempa via Devel 3 days, 14 hours ago
On Thu, Mar 19, 2026 at 17:36:53 +0100, Pavel Hrdina via Devel wrote:
> From: Pavel Hrdina <phrdina@redhat.com>
> 
> In addition to configuring IOMMUFD for each host device add
> configuration for the whole VM. This will be extended to add support for
> passing FD to libvirt from management applications.
> 
> Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
> ---
>  docs/formatdomain.rst                  | 21 ++++++++++++
>  src/conf/domain_conf.c                 | 46 ++++++++++++++++++++++++++
>  src/conf/domain_conf.h                 |  2 ++
>  src/conf/schemas/domaincommon.rng      | 12 +++++++
>  tests/genericxml2xmlindata/iommufd.xml | 18 ++++++++++
>  tests/genericxml2xmltest.c             |  2 ++
>  6 files changed, 101 insertions(+)
>  create mode 100644 tests/genericxml2xmlindata/iommufd.xml
> 
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index 9f245293e6..f6096b2b9b 100644
> --- a/docs/formatdomain.rst
> +++ b/docs/formatdomain.rst
> @@ -1382,6 +1382,27 @@ Block I/O Tuning
>     ``write_iops_sec``
>        Write I/O operations per second limit. :since:`Since 1.2.2`
>  
> +Host Device IOMMUFD
> +-------------------
> +
> +::
> +
> +   <domain>
> +     ...
> +     <iommufd enabled='yes'/>
> +     ...
> +   </domain>
> +
> +``iommufd``
> +   :since:`Since 12.2.0 (QEMU/KVM only)` The optional ``iommufd`` element with
> +   mandatory ``enabled`` attribute can be used to enable IOMMUFD backned for

backend

> +   VFIO host devices. This provides an interface to propagate DMA mappings to
> +   kernel for assigned devices. Libvirt will open the /dev/iommu and VFIO device
> +   cdev and pass associated file descriptors to QEMU.
> +
> +   This controls IOMMUFD usage for all host devices, each device can change this
> +   global default by setting ``iommufd`` attribute for ``driver`` element.
> +
>  Resource partitioning
>  ---------------------

Reviewed-by: Peter Krempa <pkrempa@redhat.com>