Signed-off-by: Olivia Yin <Hong-Hua.Yin(a)freescale.com>
Modify qemuParseCommandLinePCI() to support parsing '-device
vfio-pci,host=bus:slot.func'.
Add test case 'hostdev-vfio' into qemuargv2xmltest to validate this function.
The case related to QEMU_CAPS_HOST_PCI_MULTIDOMAIN which uses
'-device vfio-pci,host=domain:bus:slot.func' is not supported yet.
---
src/qemu/qemu_command.c | 36 ++++++++++++++++++++++++++++++------
tests/qemuargv2xmltest.c | 2 +-
2 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3cf279e..ae7f94e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10193,7 +10193,7 @@ qemuParseCommandLineNet(virDomainXMLOptionPtr xmlopt,
* Tries to parse a QEMU PCI device
*/
static virDomainHostdevDefPtr
-qemuParseCommandLinePCI(const char *val)
+qemuParseCommandLinePCI(const char *val, bool vfio)
{
int bus = 0, slot = 0, func = 0;
const char *start;
@@ -10222,10 +10222,20 @@ qemuParseCommandLinePCI(const char *val)
goto error;
}
start = end + 1;
- if (virStrToLong_i(start, NULL, 16, &func) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot extract PCI device function '%s'"),
val);
- goto error;
+
+ if (!vfio) {
+ if (virStrToLong_i(start, NULL, 16, &func) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot extract PCI device function
'%s'"), val);
+ goto error;
+ }
+ } else {
+ if (virStrToLong_i(start, &end, 16, &func) < 0 || *end != ',')
{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot extract PCI device function
'%s'"), val);
+ goto error;
+ } else
+ def->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
}
def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
@@ -11347,12 +11357,26 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
} else if (STREQ(arg, "-pcidevice")) {
virDomainHostdevDefPtr hostdev;
WANT_VALUE();
- if (!(hostdev = qemuParseCommandLinePCI(val)))
+ if (!(hostdev = qemuParseCommandLinePCI(val,0)))
goto error;
if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0)
{
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 = qemuParseCommandLinePCI(start,1)))
+ 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