[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/5] qemu: hostdev: Add checks if PCI passthrough is availabe in the host



Add code that will be used to check availability of PCI passhthrough
using VFIO and the legacy KVM passthrough. These will be later used to
determine the preferred passthrough option.
---
 src/qemu/qemu_hostdev.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_hostdev.h |  3 ++
 2 files changed, 79 insertions(+)

diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 21fe47f..1967a47 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -23,6 +23,11 @@

 #include <config.h>

+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
 #include "qemu_hostdev.h"
 #include "virlog.h"
 #include "virerror.h"
@@ -31,6 +36,7 @@
 #include "virusb.h"
 #include "virscsi.h"
 #include "virnetdev.h"
+#include "virfile.h"

 #define VIR_FROM_THIS VIR_FROM_QEMU

@@ -1287,3 +1293,73 @@ void qemuDomainReAttachHostDevices(virQEMUDriverPtr driver,
     qemuDomainReAttachHostScsiDevices(driver, def->name, def->hostdevs,
                                       def->nhostdevs);
 }
+
+
+bool
+qemuHostdevHostSupportsPassthroughVFIO(void)
+{
+    DIR *iommuDir = NULL;
+    struct dirent *iommuGroup = NULL;
+    bool ret = false;
+
+    /* condition 1 - /sys/kernel/iommu_groups/ contains entries */
+    if (!(iommuDir = opendir("/sys/kernel/iommu_groups/")))
+        goto cleanup;
+
+    while ((iommuGroup = readdir(iommuDir))) {
+        /* skip ./ ../ */
+        if (STRPREFIX(iommuGroup->d_name, "."))
+            continue;
+
+        /* assume we found a group */
+        break;
+    }
+
+    if (!iommuGroup)
+        goto cleanup;
+    /* okay, iommu is on and recognizes groups */
+
+    /* condition 2 - /dev/vfio/vfio exists */
+    if (!virFileExists("/dev/vfio/vfio"))
+        goto cleanup;
+
+    ret = true;
+
+cleanup:
+    if (iommuDir)
+        closedir(iommuDir);
+
+    return ret;
+}
+
+
+#if HAVE_LINUX_KVM_H
+# include <linux/kvm.h>
+bool
+qemuHostdevHostSupportsPassthroughLegacy(void)
+{
+    int kvmfd = -1;
+    bool ret = false;
+
+    if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
+        goto cleanup;
+
+# ifdef KVM_CAP_IOMMU
+    if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
+        goto cleanup;
+
+    ret = true;
+# endif
+
+cleanup:
+    VIR_FORCE_CLOSE(kvmfd);
+
+    return ret;
+}
+#else
+bool
+qemuHostdevHostSupportsPassthroughLegacy(void)
+{
+    return false;
+}
+#endif
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
index 327d4d5..7f33486 100644
--- a/src/qemu/qemu_hostdev.h
+++ b/src/qemu/qemu_hostdev.h
@@ -69,4 +69,7 @@ int qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
 int qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
                                       char *stateDir);

+bool qemuHostdevHostSupportsPassthroughVFIO(void);
+bool qemuHostdevHostSupportsPassthroughLegacy(void);
+
 #endif /* __QEMU_HOSTDEV_H__ */
-- 
1.8.3.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]