Signed-off-by: Olivia Yin <Hong-Hua.Yin@xxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list