qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH for-2.10 4/5] q35: init vIOMMU during machine init


From: Peter Xu
Subject: [Qemu-devel] [PATCH for-2.10 4/5] q35: init vIOMMU during machine init
Date: Fri, 31 Mar 2017 15:36:32 +0800

Now x86 vIOMMUs are init along with all the rest of "-devices". That may
not be sufficient since some devices' realization will depend on the
vIOMMU object. Let's move the vIOMMU init back to machine init, so
that'll be far earlier than all the rest of devices.

Signed-off-by: Peter Xu <address@hidden>
---
 hw/pci-host/q35.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 344f77b..c5becea 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -28,6 +28,8 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
 #include "hw/hw.h"
 #include "hw/pci-host/q35.h"
 #include "qapi/error.h"
@@ -460,6 +462,26 @@ static void mch_reset(DeviceState *qdev)
     mch_update(mch);
 }
 
+static int x86_iommu_detecter(void *opaque, QemuOpts *opts, Error **errp)
+{
+    const char *driver = qemu_opt_get(opts, "driver");
+
+    if (!driver) {
+        /*
+         * We don't need to set any error here. It'll be invoked later
+         * when init all the devices. Here we can just concentrate on
+         * the IOMMU device.
+         */
+        return -1;
+    }
+
+    if (!strcmp(driver, "intel-iommu") || !strcmp(driver, "amd-iommu")) {
+        return 0;
+    }
+
+    return -1;
+}
+
 static void mch_realize(PCIDevice *d, Error **errp)
 {
     int i;
@@ -518,6 +540,29 @@ static void mch_realize(PCIDevice *d, Error **errp)
                  mch->pci_address_space, &mch->pam_regions[i+1],
                  PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
     }
+
+    /*
+     * Initialize vIOMMUs during machine init. Now we have vIOMMUs
+     * configured with "-device", let's try to pick them out in the
+     * device list, and init them before the rest of the devices (some
+     * device will depend on the vIOMMU during its realization).
+     *
+     * TODO: support multiple vIOMMUs. This loop prepares for that.
+     */
+    while (1) {
+        QemuOpts *iommu_opts;
+
+        iommu_opts = qemu_opts_extract(qemu_find_opts("device"),
+                                       x86_iommu_detecter, NULL, errp);
+        if (!iommu_opts) {
+            break;
+        }
+
+        /* Found one IOMMU device, init it */
+        if (device_init_func(NULL, iommu_opts, errp)) {
+            return;
+        }
+    }
 }
 
 uint64_t mch_mcfg_base(void)
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]