Add new functions to generate zPCI command string and append it to
QEMU command line. And the related tests are added.
Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com>
Reviewed-by: Stefan Zimmermann <stzi@linux.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.vnet.ibm.com>
---
src/qemu/qemu_command.c | 115 +++++++++++++++++++++
src/qemu/qemu_command.h | 4 +
tests/qemuxml2argvdata/disk-virtio-s390-zpci.args | 27 +++++
.../hostdev-vfio-zpci-autogenerate.args | 26 +++++
.../hostdev-vfio-zpci-autogenerate.xml | 18 ++++
.../hostdev-vfio-zpci-boundaries.args | 30 ++++++
.../hostdev-vfio-zpci-boundaries.xml | 26 +++++
.../hostdev-vfio-zpci-multidomain-many.args | 40 +++++++
.../hostdev-vfio-zpci-multidomain-many.xml | 67 ++++++++++++
tests/qemuxml2argvdata/hostdev-vfio-zpci.args | 26 +++++
tests/qemuxml2argvtest.c | 14 +++
11 files changed, 393 insertions(+)
create mode 100644 tests/qemuxml2argvdata/disk-virtio-s390-zpci.args
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml
create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci.args
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cea31e6a24..30c57a942c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2136,6 +2136,68 @@ qemuBuildDriveDevStr(const virDomainDef *def,
return NULL;
}
+char *
+qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "zpci");
+ virBufferAsprintf(&buf, ",uid=%u", dev->addr.pci.zpci->zpci_uid);
+ virBufferAsprintf(&buf, ",fid=%u", dev->addr.pci.zpci->zpci_fid);
+ virBufferAsprintf(&buf, ",target=%s", dev->alias);
+ virBufferAsprintf(&buf, ",id=zpci%u", dev->addr.pci.zpci->zpci_uid);
+
+ if (virBufferCheckError(&buf) < 0) {
+ virBufferFreeAndReset(&buf);
+ return NULL;
+ }
+
+ return virBufferContentAndReset(&buf);
+}
+
+bool
+qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info)
+{
+ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
+ ((info->pciAddressExtFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ||
+ info->addr.pci.zpci))
+ return true;
+
+ return false;
+}
+
+static int
+qemuAppendZPCIDevStr(virCommandPtr cmd,
+ virDomainDeviceInfoPtr dev)
+{
+ char *devstr = NULL;
+
+ virCommandAddArg(cmd, "-device");
+ if (!(devstr = qemuBuildZPCIDevStr(dev)))
+ return -1;
+
+ virCommandAddArg(cmd, devstr);
+
+ VIR_FREE(devstr);
+ return 0;
+}
+
+static int
+qemuBuildExtensionCommandLine(virCommandPtr cmd,
+ virQEMUCapsPtr qemuCaps,
+ virDomainDeviceInfoPtr dev)
+{
+ if (qemuCheckDeviceIsZPCI(dev)) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("This QEMU doesn't support zpci devices"));
+ return -1;
+ }
+ return qemuAppendZPCIDevStr(cmd, dev);
+ }
+
+ return 0;
+}
static int
qemuBuildFloppyCommandLineOptions(virCommandPtr cmd,
@@ -2256,6 +2318,9 @@ qemuBuildDiskCommandLine(virCommandPtr cmd,
bootindex) < 0)
return -1;
} else {
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &disk->info) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-device");
if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
@@ -2455,6 +2520,9 @@ qemuBuildFSDevCommandLine(virCommandPtr cmd,
virCommandAddArg(cmd, optstr);
VIR_FREE(optstr);
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &fs->info) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-device");
if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps)))
return -1;
@@ -2939,6 +3007,11 @@ qemuBuildControllerDevCommandLine(virCommandPtr cmd,
goto cleanup;
if (devstr) {
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps,
+ &cont->info) < 0) {
+ VIR_FREE(devstr);
+ goto cleanup;
+ }
virCommandAddArg(cmd, "-device");
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
@@ -3742,6 +3815,9 @@ qemuBuildWatchdogCommandLine(virCommandPtr cmd,
if (!def->watchdog)
return 0;
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &def->watchdog->info) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-device");
optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps);
@@ -3826,6 +3902,9 @@ qemuBuildMemballoonCommandLine(virCommandPtr cmd,
if (qemuBuildVirtioOptionsStr(&buf, def->memballoon->virtio, qemuCaps) < 0)
goto error;
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &def->memballoon->info) < 0)
+ goto error;
+
virCommandAddArg(cmd, "-device");
virCommandAddArgBuffer(cmd, &buf);
return 0;
@@ -4048,6 +4127,9 @@ qemuBuildInputCommandLine(virCommandPtr cmd,
virDomainInputDefPtr input = def->inputs[i];
char *devstr = NULL;
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &input->info) < 0)
+ return -1;
+
if (qemuBuildInputDevStr(&devstr, def, input, qemuCaps) < 0)
return -1;
@@ -4189,6 +4271,9 @@ qemuBuildSoundCommandLine(virCommandPtr cmd,
if (sound->model == VIR_DOMAIN_SOUND_MODEL_PCSPK) {
virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL);
} else {
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &sound->info) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-device");
if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps)))
return -1;
@@ -4425,6 +4510,9 @@ qemuBuildVideoCommandLine(virCommandPtr cmd,
if (video->primary) {
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY)) {
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps,
+ &def->videos[i]->info) < 0)
+ return -1;
virCommandAddArg(cmd, "-device");
if (!(str = qemuBuildDeviceVideoStr(def, video, qemuCaps)))
@@ -4437,6 +4525,10 @@ qemuBuildVideoCommandLine(virCommandPtr cmd,
return -1;
}
} else {
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps,
+ &def->videos[i]->info) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-device");
if (!(str = qemuBuildDeviceVideoStr(def, video, qemuCaps)))
@@ -5304,6 +5396,10 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
VIR_COMMAND_PASS_FD_CLOSE_PARENT);
}
}
+
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, hostdev->info) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-device");
devstr = qemuBuildPCIHostdevDevStr(def, hostdev, bootIndex,
configfd_name, qemuCaps);
@@ -5767,6 +5863,9 @@ qemuBuildRNGCommandLine(virLogManagerPtr logManager,
virCommandAddArgBuffer(cmd, &buf);
/* add the device */
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &rng->info) < 0)
+ return -1;
+
if (!(tmp = qemuBuildRNGDevStr(def, rng, qemuCaps)))
return -1;
virCommandAddArgList(cmd, "-device", tmp, NULL);
@@ -8303,6 +8402,9 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
virCommandAddArg(cmd, "-netdev");
virCommandAddArg(cmd, netdev);
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &net->info) < 0)
+ goto cleanup;
+
if (!(nic = qemuBuildNicDevStr(def, net, bootindex,
queues, qemuCaps))) {
goto cleanup;
@@ -8584,6 +8686,9 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
* New way: -netdev type=tap,id=netdev1 -device e1000,id=netdev1
*/
if (qemuDomainSupportsNicdev(def, net)) {
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &net->info) < 0)
+ goto cleanup;
+
if (!(nic = qemuBuildNicDevStr(def, net, bootindex,
vhostfdSize, qemuCaps)))
goto cleanup;
@@ -9008,6 +9113,9 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
switch ((virDomainShmemModel)shmem->model) {
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM:
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &shmem->info) < 0)
+ return -1;
+
devstr = qemuBuildShmemDevLegacyStr(def, shmem, qemuCaps);
break;
@@ -9026,6 +9134,9 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
ATTRIBUTE_FALLTHROUGH;
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_DOORBELL:
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &shmem->info) < 0)
+ return -1;
+
devstr = qemuBuildShmemDevStr(def, shmem, qemuCaps);
break;
@@ -10181,6 +10292,10 @@ qemuBuildVsockCommandLine(virCommandPtr cmd,
virCommandPassFD(cmd, priv->vhostfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
priv->vhostfd = -1;
+
+ if (qemuBuildExtensionCommandLine(cmd, qemuCaps, &vsock->info) < 0)
+ goto cleanup;
+
virCommandAddArgList(cmd, "-device", devstr, NULL);
ret = 0;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 4f1b360130..78746577c1 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -174,6 +174,10 @@ char *qemuBuildRedirdevDevStr(const virDomainDef *def,
virDomainRedirdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
+char *qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev);
+
+bool qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info);
+
int qemuNetworkPrepareDevices(virDomainDefPtr def);
int qemuGetDriveSourceString(virStorageSourcePtr src,
diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args
new file mode 100644
index 0000000000..d6a46f8b15
--- /dev/null
+++ b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args
@@ -0,0 +1,27 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot c \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \
+-device zpci,uid=25,fid=31,target=virtio-disk0,id=zpci25 \
+-device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk0,\
+id=virtio-disk0 \
+-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0000
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args
new file mode 100644
index 0000000000..db47d13a31
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args
@@ -0,0 +1,26 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot c \
+-device zpci,uid=1,fid=0,target=hostdev0,id=zpci1 \
+-device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x1 \
+-device zpci,uid=2,fid=1,target=balloon0,id=zpci2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml
new file mode 100644
index 0000000000..41c43cee23
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml
@@ -0,0 +1,18 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <os>
+ <type arch='s390x' machine='s390-ccw'>hvm</type>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-s390x</emulator>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args
new file mode 100644
index 0000000000..97cf46c02d
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot c \
+-device zpci,uid=3,fid=2,target=pci.1,id=zpci3 \
+-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x1 \
+-device zpci,uid=65535,fid=4294967295,target=hostdev0,id=zpci65535 \
+-device vfio-pci,host=ffff:00:00.0,id=hostdev0,bus=pci.1,addr=0x1f \
+-device zpci,uid=1,fid=0,target=hostdev1,id=zpci1 \
+-device vfio-pci,host=00:00.0,id=hostdev1,bus=pci.0,addr=0x2 \
+-device zpci,uid=2,fid=1,target=balloon0,id=zpci2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml
new file mode 100644
index 0000000000..2c54016348
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml
@@ -0,0 +1,26 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <os>
+ <type arch='s390x' machine='s390-ccw'>hvm</type>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-s390x</emulator>
+ <controller type='pci' index='0' model='pci-root'/>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0xffff' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x1f' function='0x0' fid='0xffffffff' uid='0xffff'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' fid='0x00000000' uid='0x0001'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args
new file mode 100644
index 0000000000..c4490df7d0
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot c \
+-device zpci,uid=35,fid=63,target=hostdev0,id=zpci35 \
+-device vfio-pci,host=0001:00:00.0,id=hostdev0,bus=pci.0,addr=0x3 \
+-device zpci,uid=53,fid=104,target=hostdev1,id=zpci53 \
+-device vfio-pci,host=0002:00:00.0,id=hostdev1,bus=pci.0,addr=0x1 \
+-device zpci,uid=1,fid=0,target=hostdev2,id=zpci1 \
+-device vfio-pci,host=0003:00:00.0,id=hostdev2,bus=pci.0,addr=0x2 \
+-device zpci,uid=2,fid=1,target=hostdev3,id=zpci2 \
+-device vfio-pci,host=0004:00:00.0,id=hostdev3,bus=pci.0,addr=0x5 \
+-device zpci,uid=83,fid=2,target=hostdev4,id=zpci83 \
+-device vfio-pci,host=0005:00:00.0,id=hostdev4,bus=pci.0,addr=0x7 \
+-device zpci,uid=3,fid=114,target=hostdev5,id=zpci3 \
+-device vfio-pci,host=0006:00:00.0,id=hostdev5,bus=pci.0,addr=0x9 \
+-device zpci,uid=23,fid=3,target=hostdev6,id=zpci23 \
+-device vfio-pci,host=0007:00:00.0,id=hostdev6,bus=pci.0,addr=0x4 \
+-device zpci,uid=4,fid=40,target=hostdev7,id=zpci4 \
+-device vfio-pci,host=0008:00:00.0,id=hostdev7,bus=pci.0,addr=0x6 \
+-device zpci,uid=5,fid=4,target=balloon0,id=zpci5 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml
new file mode 100644
index 0000000000..2063f57f33
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml
@@ -0,0 +1,67 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <os>
+ <type arch='s390x' machine='s390-ccw'>hvm</type>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-s390x</emulator>
+ <controller type='pci' index='0' model='pci-root'/>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0001' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' uid='0x0023' fid='0x0000003f'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0002' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' uid='0x0035' fid='0x00000068'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0003' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0004' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0005' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0' uid='0x0053'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0006' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0' fid='0x00000072'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0007' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' uid='0x0017'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci'>
+ <driver name='vfio'/>
+ <source>
+ <address domain='0x0008' bus='0x00' slot='0x00' function='0x0'/>
+ </source>
+ <address type='pci' fid='0x00000028'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args
new file mode 100644
index 0000000000..cc2d872bc2
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args
@@ -0,0 +1,26 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-s390x \
+-name QEMUGuest1 \
+-S \
+-machine s390-ccw,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot c \
+-device zpci,uid=25,fid=31,target=hostdev0,id=zpci25 \
+-device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x8 \
+-device zpci,uid=1,fid=0,target=balloon0,id=zpci1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x1
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 3be5af03aa..307b0f5d9d 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1014,6 +1014,8 @@ mymain(void)
QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
DO_TEST("disk-virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI,
QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
+ DO_TEST("disk-virtio-s390-zpci", QEMU_CAPS_DEVICE_ZPCI,
+ QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
DO_TEST("disk-order",
QEMU_CAPS_DRIVE_BOOT, QEMU_CAPS_VIRTIO_BLK_SCSI);
DO_TEST("disk-virtio-drive-queues",
@@ -1574,6 +1576,18 @@ mymain(void)
QEMU_CAPS_DEVICE_VFIO_PCI);
DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address",
QEMU_CAPS_DEVICE_VFIO_PCI);
+ DO_TEST("hostdev-vfio-zpci",
+ QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
+ DO_TEST("hostdev-vfio-zpci-multidomain-many",
+ QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
+ QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI);
+ DO_TEST("hostdev-vfio-zpci-autogenerate",
+ QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
+ DO_TEST("hostdev-vfio-zpci-boundaries",
+ QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
+ QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI);
+ DO_TEST_FAILURE("hostdev-vfio-zpci",
+ QEMU_CAPS_DEVICE_VFIO_PCI);
DO_TEST("pci-rom", NONE);
DO_TEST("pci-rom-disabled", NONE);
DO_TEST("pci-rom-disabled-invalid", NONE);
--
Yi Min
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Tue, 2018-07-10 at 16:02 +0800, Yi Min Zhao wrote:
[...]
> +bool
> +qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info)
> +{
> + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
> + ((info->pciAddressExtFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ||
> + info->addr.pci.zpci))
> + return true;
Missing curly braces.
Also, do you really need to check both the flags and the presence
of the zPCI address bits? It looks like either one or the other
should be enough or, if that's not the case, it should be made so
because having to check for two separate conditions makes me feel
like it would introduce bugs in the long run.
[...]
> +char *qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev);
> +
> +bool qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info);
Is this really necessary? Can't these two functions be static?
[...]
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -1014,6 +1014,8 @@ mymain(void)
> QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
> DO_TEST("disk-virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI,
> QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
> + DO_TEST("disk-virtio-s390-zpci", QEMU_CAPS_DEVICE_ZPCI,
> + QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
> DO_TEST("disk-order",
> QEMU_CAPS_DRIVE_BOOT, QEMU_CAPS_VIRTIO_BLK_SCSI);
> DO_TEST("disk-virtio-drive-queues",
> @@ -1574,6 +1576,18 @@ mymain(void)
> QEMU_CAPS_DEVICE_VFIO_PCI);
> DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address",
> QEMU_CAPS_DEVICE_VFIO_PCI);
> + DO_TEST("hostdev-vfio-zpci",
> + QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
> + DO_TEST("hostdev-vfio-zpci-multidomain-many",
> + QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
Capabilities with X_QEMU prefix are no longer used, so you should
not list them here.
> + QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI);
> + DO_TEST("hostdev-vfio-zpci-autogenerate",
> + QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
> + DO_TEST("hostdev-vfio-zpci-boundaries",
> + QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
> + QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI);
> + DO_TEST_FAILURE("hostdev-vfio-zpci",
> + QEMU_CAPS_DEVICE_VFIO_PCI);
Please add these to qemuxml2xmltest at the same time.
--
Andrea Bolognani / Red Hat / Virtualization
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
在 2018/7/24 下午11:09, Andrea Bolognani 写道:
> On Tue, 2018-07-10 at 16:02 +0800, Yi Min Zhao wrote:
> [...]
>> +bool
>> +qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info)
>> +{
>> + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
>> + ((info->pciAddressExtFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ||
>> + info->addr.pci.zpci))
>> + return true;
> Missing curly braces.
>
> Also, do you really need to check both the flags and the presence
> of the zPCI address bits? It looks like either one or the other
> should be enough or, if that's not the case, it should be made so
> because having to check for two separate conditions makes me feel
> like it would introduce bugs in the long run.
This is actually a problem. I add info->addr.pci.zpci check in order to
check
if the user specifies zpci address in xml even though it has no zpci
support.
The callers of this function checks zpci capability. If no zpci cap but
the user
specfies zpci address, report an error.
I will change the logic and remove the check on info->addr.pci.zpci.
>
> [...]
>> +char *qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev);
>> +
>> +bool qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info);
> Is this really necessary? Can't these two functions be static?
They are also used in qemu_hotplug.c file.
>
> [...]
>> --- a/tests/qemuxml2argvtest.c
>> +++ b/tests/qemuxml2argvtest.c
>> @@ -1014,6 +1014,8 @@ mymain(void)
>> QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
>> DO_TEST("disk-virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI,
>> QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
>> + DO_TEST("disk-virtio-s390-zpci", QEMU_CAPS_DEVICE_ZPCI,
>> + QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
>> DO_TEST("disk-order",
>> QEMU_CAPS_DRIVE_BOOT, QEMU_CAPS_VIRTIO_BLK_SCSI);
>> DO_TEST("disk-virtio-drive-queues",
>> @@ -1574,6 +1576,18 @@ mymain(void)
>> QEMU_CAPS_DEVICE_VFIO_PCI);
>> DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address",
>> QEMU_CAPS_DEVICE_VFIO_PCI);
>> + DO_TEST("hostdev-vfio-zpci",
>> + QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
>> + DO_TEST("hostdev-vfio-zpci-multidomain-many",
>> + QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
> Capabilities with X_QEMU prefix are no longer used, so you should
> not list them here.
Sure.
>
>> + QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI);
>> + DO_TEST("hostdev-vfio-zpci-autogenerate",
>> + QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
>> + DO_TEST("hostdev-vfio-zpci-boundaries",
>> + QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
>> + QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI);
>> + DO_TEST_FAILURE("hostdev-vfio-zpci",
>> + QEMU_CAPS_DEVICE_VFIO_PCI);
> Please add these to qemuxml2xmltest at the same time.
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Fri, 2018-07-27 at 15:53 +0800, Yi Min Zhao wrote:
> 在 2018/7/24 下午11:09, Andrea Bolognani 写道:
> > Also, do you really need to check both the flags and the presence
> > of the zPCI address bits? It looks like either one or the other
> > should be enough or, if that's not the case, it should be made so
> > because having to check for two separate conditions makes me feel
> > like it would introduce bugs in the long run.
>
> This is actually a problem. I add info->addr.pci.zpci check in order to
> check
> if the user specifies zpci address in xml even though it has no zpci
> support.
> The callers of this function checks zpci capability. If no zpci cap but
> the user
> specfies zpci address, report an error.
>
> I will change the logic and remove the check on info->addr.pci.zpci.
Yeah, you definitely want to report an error if the QEMU binary
doesn't support zPCI or the user is attempting to do something
silly like add zPCI-related information to devices attached to
an x86_64 guest...
> > > +char *qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev);
> > > +
> > > +bool qemuCheckDeviceIsZPCI(virDomainDeviceInfoPtr info);
> >
> > Is this really necessary? Can't these two functions be static?
>
> They are also used in qemu_hotplug.c file.
Right, I overlooked that :)
That said, they aren't used in the hotplug code until the next
patch, so it would IMHO make sense to define them as static in
this patch and export them in the next one, at the same time as
you actually start using them outside of the file.
[...]
> > > + DO_TEST("hostdev-vfio-zpci",
> > > + QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI);
> > > + DO_TEST("hostdev-vfio-zpci-multidomain-many",
> > > + QEMU_CAPS_DEVICE_VFIO_PCI, X_QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
> >
> > Capabilities with X_QEMU prefix are no longer used, so you should
> > not list them here.
>
> Sure.
I forgot to mention, please have a single capability per line and
make sure the set of capabilities used in xml2xml and xml2argv is
exactly the same.
--
Andrea Bolognani / Red Hat / Virtualization
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2026 Red Hat, Inc.