Signed-off-by: Olivia Yin <Hong-Hua.Yin(a)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