From: Pavel Hrdina <[email protected]>

This will allow management applications running libvirt without
necessary permissions to pass FD for /dev/iommu with per-process
locked memory accounting enabled.

Kernel uses per-user locked memory accounting by default which may
cause error while starting multiple VMs with host devices using IOMMUFD.

Signed-off-by: Pavel Hrdina <[email protected]>
---
 docs/formatdomain.rst                  |  8 +++++++-
 src/conf/domain_conf.c                 |  7 +++++++
 src/conf/domain_conf.h                 |  1 +
 src/conf/domain_validate.c             | 16 ++++++++++++++++
 src/conf/schemas/domaincommon.rng      |  3 +++
 tests/genericxml2xmlindata/iommufd.xml |  2 +-
 6 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index f6096b2b9b..412b2b4ddd 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1389,7 +1389,7 @@ Host Device IOMMUFD
 
    <domain>
      ...
-     <iommufd enabled='yes'/>
+     <iommufd enabled='yes' fdgroup='iommu'/>
      ...
    </domain>
 
@@ -1403,6 +1403,12 @@ Host Device IOMMUFD
    This controls IOMMUFD usage for all host devices, each device can change 
this
    global default by setting ``iommufd`` attribute for ``driver`` element.
 
+   Optional ``fdgroup`` attribute can be used together with
+   ``virDomainFDAssociate()`` to pass /dev/iommu FD instead of letting
+   libvirt to open it. Caller is responsible for setting per-process locked
+   memory accounting otherwise starting multiple VMs with host devices using
+   IOMMUFD may fail.
+
 Resource partitioning
 ---------------------
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 950c755ad9..71488a0840 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4242,6 +4242,8 @@ void virDomainDefFree(virDomainDef *def)
     g_free(def->kvm_features);
     g_free(def->tcg_features);
 
+    g_free(def->iommufd_fdgroup);
+
     virBlkioDeviceArrayClear(def->blkio.devices,
                              def->blkio.ndevices);
     g_free(def->blkio.devices);
@@ -19905,6 +19907,8 @@ virDomainDefIommufdParse(virDomainDef *def,
     if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, 
&def->iommufd) < 0)
         return -1;
 
+    def->iommufd_fdgroup = virXMLPropString(nodes[0], "fdgroup");
+
     return 0;
 }
 
@@ -28212,6 +28216,9 @@ virDomainDefIommufdFormat(virBuffer *buf,
     virBufferAsprintf(&attrBuf, " enabled='%s'",
                       virTristateBoolTypeToString(def->iommufd));
 
+    if (def->iommufd_fdgroup)
+        virBufferAsprintf(&attrBuf, " fdgroup='%s'", def->iommufd_fdgroup);
+
     virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
 }
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f7e2eb6f5e..75acfc46bf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3245,6 +3245,7 @@ struct _virDomainDef {
     virDomainFeatureTCG *tcg_features;
 
     virTristateBool iommufd;
+    char *iommufd_fdgroup;
 
     bool tseg_specified;
     unsigned long long tseg_size;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 7e3da84767..a49156061f 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2003,6 +2003,19 @@ virDomainDefValidateThrottleGroups(const virDomainDef 
*def)
 }
 
 
+static int
+virDomainDefValidateIommufd(const virDomainDef *def)
+{
+    if (def->iommufd == VIR_TRISTATE_BOOL_NO && def->iommufd_fdgroup) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Setting 'fdgroup' when 'iommufd' is disabled is not 
supported."));
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 virDomainDefValidateInternal(const virDomainDef *def,
                              virDomainXMLOption *xmlopt)
@@ -2064,6 +2077,9 @@ virDomainDefValidateInternal(const virDomainDef *def,
     if (virDomainDefValidateThrottleGroups(def) < 0)
         return -1;
 
+    if (virDomainDefValidateIommufd(def) < 0)
+        return -1;
+
     return 0;
 }
 
diff --git a/src/conf/schemas/domaincommon.rng 
b/src/conf/schemas/domaincommon.rng
index 0436ec8edc..db1dcd3bb7 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1377,6 +1377,9 @@
       <attribute name="enabled">
         <ref name="virYesNo"/>
       </attribute>
+      <optional>
+        <attribute name="fdgroup"/>
+      </optional>
     </element>
   </define>
 
diff --git a/tests/genericxml2xmlindata/iommufd.xml 
b/tests/genericxml2xmlindata/iommufd.xml
index 63ea839383..10d59ca548 100644
--- a/tests/genericxml2xmlindata/iommufd.xml
+++ b/tests/genericxml2xmlindata/iommufd.xml
@@ -4,7 +4,7 @@
   <memory unit='KiB'>219136</memory>
   <currentMemory unit='KiB'>219136</currentMemory>
   <vcpu placement='static'>1</vcpu>
-  <iommufd enabled='yes'/>
+  <iommufd enabled='yes' fdgroup='iommu'/>
   <os>
     <type arch='i686' machine='pc'>hvm</type>
     <boot dev='hd'/>
-- 
2.53.0

Reply via email to