]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
virt-host-validate: check for IOMMU support
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 7 Oct 2015 16:46:18 +0000 (17:46 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 13 Oct 2015 09:54:09 +0000 (10:54 +0100)
This looks for existance of DMAR (Intel) and IVRS (AMD)
files under /sys/firmware/acpi/tables/, as a sign that
the platform has IOMMU present & enabled in the BIOS.

If these are present and /sys/kernel/iommu_groups does
not contain any entries this is taken as a sign that
the kernel has not enabled the IOMMU currently.

If no ACPI tables are found we can't distinguish between
disabled in BIOS and not present in the hardware, so we
have to give the user a generic hint.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
tools/virt-host-validate-common.c
tools/virt-host-validate-common.h
tools/virt-host-validate-qemu.c

index dd41fd44ca33e4255a0fba28ee905237de40a1a1..dd1c414f96531ded3692896cf125710b6250e925 100644 (file)
@@ -29,6 +29,7 @@
 #ifdef HAVE_MNTENT_H
 # include <mntent.h>
 #endif /* HAVE_MNTENT_H */
+#include <sys/stat.h>
 
 #include "virutil.h"
 #include "viralloc.h"
@@ -354,3 +355,67 @@ int virHostValidateCGroupController(const char *hvname,
         return -1;
     return 0;
 }
+
+int virHostValidateIOMMU(const char *hvname,
+                         virHostValidateLevel level)
+{
+    struct stat sb;
+    const char *bootarg = NULL;
+    bool isAMD = false, isIntel = false;
+
+    if (virHostValidateHasCPUFlag("vmx"))
+        isIntel = true;
+    else if (virHostValidateHasCPUFlag("svm"))
+        isAMD = true;
+    else
+        /* XXX PPC/ARM/etc support */
+        return 0;
+
+    virHostMsgCheck(hvname, "%s", _("for device assignment IOMMU support"));
+
+    if (isIntel) {
+        if (access("/sys/firmware/acpi/tables/DMAR", F_OK) == 0) {
+            virHostMsgPass();
+            bootarg = "intel_iommu=on";
+        } else {
+            virHostMsgFail(level,
+                           "No ACPI DMAR table found, IOMMU either "
+                           "disabled in BIOS or not supported by this "
+                           "hardware platform");
+            return -1;
+        }
+    } else if (isAMD) {
+        if (access("/sys/firmware/acpi/tables/IVRS", F_OK) == 0) {
+            virHostMsgPass();
+            bootarg = "iommu=pt iommu=1";
+        } else {
+            virHostMsgFail(level,
+                           "No ACPI IVRS table found, IOMMU either "
+                           "disabled in BIOS or not supported by this "
+                           "hardware platform");
+            return -1;
+        }
+    } else {
+        virHostMsgFail(level,
+                       "Unknown if this platform has IOMMU support");
+        return -1;
+    }
+
+
+    /* We can only check on newer kernels with iommu groups & vfio */
+    if (stat("/sys/kernel/iommu_groups", &sb) < 0)
+        return 0;
+
+    if (!S_ISDIR(sb.st_mode))
+        return 0;
+
+    virHostMsgCheck(hvname, "%s", _("if IOMMU is enabled by kernel"));
+    if (sb.st_nlink <= 2) {
+        virHostMsgFail(level,
+                       "IOMMU appears to be disabled in kernel. "
+                       "Add %s to kernel cmdline arguments", bootarg);
+        return -1;
+    }
+    virHostMsgPass();
+    return 0;
+}
index 1547e22897eb51eb2f8f1f695bd694da30071784..d4c4759b0f539cf6fd23affe128bd6b40aa2dd24 100644 (file)
@@ -70,4 +70,7 @@ extern int virHostValidateCGroupController(const char *hvname,
                                            virHostValidateLevel level,
                                            const char *config_name);
 
+extern int virHostValidateIOMMU(const char *hvname,
+                                virHostValidateLevel level);
+
 #endif /* __VIRT_HOST_VALIDATE_COMMON_H__ */
index b0ae293be598cc906c6054875876f4d15c615795..044df65b02cfd74a0c90c8ad508af6d7725afc9a 100644 (file)
@@ -20,6 +20,8 @@
  */
 
 #include <config.h>
+#include <unistd.h>
+
 #include "virt-host-validate-qemu.h"
 #include "virt-host-validate-common.h"
 
@@ -87,5 +89,9 @@ int virHostValidateQEMU(void)
                                         "BLK_CGROUP") < 0)
         ret = -1;
 
+    if (virHostValidateIOMMU("QEMU",
+                             VIR_HOST_VALIDATE_WARN) < 0)
+        ret = -1;
+
     return ret;
 }