summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2015-10-07 17:46:18 +0100
committerDaniel P. Berrange <berrange@redhat.com>2015-10-13 10:54:09 +0100
commit9139b46a6be9d04e0b6cf882f6ab4d3a9efb4825 (patch)
tree1f3335b4d14c0fdd6e823889ee11fd626fc83ac1
parent179d92c8481b2229edbfb233614328e08ab79dfc (diff)
downloadlibvirt-9139b46a6be9d04e0b6cf882f6ab4d3a9efb4825.tar.gz
virt-host-validate: check for IOMMU support
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>
-rw-r--r--tools/virt-host-validate-common.c65
-rw-r--r--tools/virt-host-validate-common.h3
-rw-r--r--tools/virt-host-validate-qemu.c6
3 files changed, 74 insertions, 0 deletions
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index dd41fd44ca..dd1c414f96 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -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;
+}
diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h
index 1547e22897..d4c4759b0f 100644
--- a/tools/virt-host-validate-common.h
+++ b/tools/virt-host-validate-common.h
@@ -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__ */
diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c
index b0ae293be5..044df65b02 100644
--- a/tools/virt-host-validate-qemu.c
+++ b/tools/virt-host-validate-qemu.c
@@ -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;
}