[libvirt] [RFC][PATCH]QEMU: Parse -device vfio-pci commandline

Olivia Yin Hong-Hua.Yin at freescale.com
Thu Jun 5 11:42:52 UTC 2014


Signed-off-by: Olivia Yin <Hong-Hua.Yin at freescale.com>
---
 src/qemu/qemu_command.c  | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/qemuargv2xmltest.c |  2 +-
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e6acced..4db4a1d 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10239,6 +10239,59 @@ qemuParseCommandLinePCI(const char *val)
     return NULL;
 }
 
+/*
+ * Tries to parse a QEMU vfio-pci device
+ */
+static virDomainHostdevDefPtr
+qemuParseCommandLineVFIOPCI(const char *val)
+{
+    int bus = 0, slot = 0, func = 0;
+    const char *start;
+    char *end;
+    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();
+
+    if (!def)
+       goto error;
+
+    if (!STRPREFIX(val, "host=")) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unknown PCI device syntax '%s'"), val);
+        goto error;
+    }
+
+    start = val + strlen("host=");
+    if (virStrToLong_i(start, &end, 16, &bus) < 0 || *end != ':') {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot extract PCI device bus '%s'"), val);
+        goto error;
+    }
+    start = end + 1;
+    if (virStrToLong_i(start, &end, 16, &slot) < 0 || *end != '.') {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot extract PCI device slot '%s'"), val);
+        goto error;
+    }
+    start = end + 1;
+    if (virStrToLong_i(start, &end, 16, &func) < 0 || *end != ',') {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot extract PCI device function '%s'"), val);
+        goto error;
+    }
+
+    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+    def->managed = true;
+    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+    def->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
+    def->source.subsys.u.pci.addr.bus = bus;
+    def->source.subsys.u.pci.addr.slot = slot;
+    def->source.subsys.u.pci.addr.function = func;
+    return def;
+
+ error:
+    virDomainHostdevDefFree(def);
+    return NULL;
+}
+
 
 /*
  * Tries to parse a QEMU USB device
@@ -11351,6 +11404,20 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
                 virDomainHostdevDefFree(hostdev);
                 goto error;
             }
+        } else if (STREQ(arg, "-device")) {
+            WANT_VALUE();
+            if (STRPREFIX(val, "vfio-pci,")) {
+                const char *start;
+                start = val;
+                virDomainHostdevDefPtr hostdev;
+                start += strlen("vfio-pci,");
+                if (!(hostdev = qemuParseCommandLineVFIOPCI(start)))
+                    goto error;
+                if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
+                    virDomainHostdevDefFree(hostdev);
+                    goto error;
+                }
+            }
         } else if (STREQ(arg, "-soundhw")) {
             const char *start;
             WANT_VALUE();
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 0fc9fcb..b4ba97a 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -251,8 +251,8 @@ mymain(void)
     DO_TEST("watchdog");
 
     DO_TEST("hostdev-usb-address");
-
     DO_TEST("hostdev-pci-address");
+    DO_TEST("hostdev-vfio");
 
     DO_TEST("smp");
 
-- 
1.8.5




More information about the libvir-list mailing list