[libvirt] [PATCH v2 1/2] capabilities: Provide info about host IOMMU support

Filip Alac filipalac at gmail.com
Sun May 27 16:29:14 UTC 2018


Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=967231

Signed-off-by: Filip Alac <filipalac at gmail.com>
---
 docs/schemas/capability.rng  | 11 +++++++++++
 src/conf/capabilities.c      |  8 ++++++++
 src/conf/capabilities.h      |  5 +++++
 src/libvirt_private.syms     |  1 +
 src/qemu/qemu_capabilities.c |  3 +++
 src/util/virpci.c            | 19 +++++++++++++++++++
 src/util/virpci.h            |  2 ++
 7 files changed, 49 insertions(+)

diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng
index 66c5de62e5..a604cc54d0 100644
--- a/docs/schemas/capability.rng
+++ b/docs/schemas/capability.rng
@@ -39,6 +39,9 @@
       <optional>
         <ref name='power_management'/>
       </optional>
+      <optional>
+        <ref name='iommu_support'/>
+      </optional>
       <optional>
         <ref name='migration'/>
       </optional>
@@ -155,6 +158,14 @@
     </element>
   </define>
 
+  <define name='iommu_support'>
+    <optional>
+      <attribute name='support'>
+        <ref name='virYesNo'/>
+      </attribute>
+    </optional>
+  </define>
+
   <define name='migration'>
     <element name='migration_features'>
       <optional>
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index dd2fc77f91..eb387916f2 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -1020,6 +1020,8 @@ virCapabilitiesFormatXML(virCapsPtr caps)
         }
         virBufferAdjustIndent(&buf, -2);
         virBufferAddLit(&buf, "</power_management>\n");
+        virBufferAsprintf(&buf, "<iommu support='%s'/>\n",
+                          caps->host.iommu  ? "yes" : "no");
     } else {
         /* The host does not support any PM feature. */
         virBufferAddLit(&buf, "<power_management/>\n");
@@ -1743,3 +1745,9 @@ virCapabilitiesInitCaches(virCapsPtr caps)
     virBitmapFree(cpus);
     return ret;
 }
+
+int
+virCapabilitiesHostInitIOMMU(virCapsPtr caps)
+{
+    return caps->host.iommu = virPCIHasIOMMU();
+}
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index f0a06a24df..4d41363a30 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -183,6 +183,7 @@ struct _virCapsHost {
     int nPagesSize;             /* size of pagesSize array */
     unsigned int *pagesSize;    /* page sizes support on the system */
     unsigned char host_uuid[VIR_UUID_BUFLEN];
+    int iommu;
 };
 
 typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr,
@@ -327,4 +328,8 @@ void virCapsHostCacheBankFree(virCapsHostCacheBankPtr ptr);
 
 int virCapabilitiesInitCaches(virCapsPtr caps);
 
+int virCapabilitiesInitCaches(virCapsPtr caps);
+
+int virCapabilitiesHostInitIOMMU(virCapsPtr caps);
+
 #endif /* __VIR_CAPABILITIES_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a97b7fe223..258d02962c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -58,6 +58,7 @@ virCapabilitiesFreeMachines;
 virCapabilitiesFreeNUMAInfo;
 virCapabilitiesGetCpusForNodemask;
 virCapabilitiesGetNodeInfo;
+virCapabilitiesHostInitIOMMU;
 virCapabilitiesHostSecModelAddBaseLabel;
 virCapabilitiesInitCaches;
 virCapabilitiesInitNUMA;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 40f49a8d9e..d95fa113b6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -953,6 +953,9 @@ virQEMUCapsInit(virFileCachePtr cache)
     virCapabilitiesAddHostMigrateTransport(caps, "tcp");
     virCapabilitiesAddHostMigrateTransport(caps, "rdma");
 
+    /* Add IOMMU info */
+    virCapabilitiesHostInitIOMMU(caps);
+
     /* QEMU can support pretty much every arch that exists,
      * so just probe for them all - we gracefully fail
      * if a qemu-system-$ARCH binary can't be found
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 8d02366664..c88b13c97a 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -3288,3 +3288,22 @@ virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev)
     VIR_FREE(dev->link_sta);
     VIR_FREE(dev);
 }
+
+bool
+virPCIHasIOMMU(void)
+{
+    struct stat sb;
+
+    /* We can only check on newer kernels with iommu groups & vfio */
+    if (stat("/sys/kernel/iommu_groups", &sb) < 0)
+        return false;
+
+    if (!S_ISDIR(sb.st_mode))
+        return false;
+
+    /* Check if folder is empty */
+    if (sb.st_nlink <= 2)
+        return false;
+
+    return true;
+}
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 794b7e59db..93ea8cdf6b 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -253,4 +253,6 @@ void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);
 ssize_t virPCIGetMdevTypes(const char *sysfspath,
                            virMediatedDeviceType ***types);
 
+bool virPCIHasIOMMU(void);
+
 #endif /* __VIR_PCI_H__ */
-- 
2.17.0




More information about the libvir-list mailing list