From b4833b2c2f7be8a68eb6495ed57ed61918e3ecd8 Mon Sep 17 00:00:00 2001 From: Yi Min Zhao Date: Thu, 8 Nov 2018 19:00:26 +0800 Subject: [PATCH] conf: Introduce parser, formatter for uid and fid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch introduces new XML parser/formatter functions. Uid is 16-bit and non-zero. Fid is 32-bit. They are the two attributes of zpci which is introduced as PCI address element. Zpci element is parsed and formatted along with PCI address. And add the related test cases. Signed-off-by: Yi Min Zhao Reviewed-by: Boris Fiuczynski Reviewed-by: Stefan Zimmermann Reviewed-by: Bjoern Walk Reviewed-by: Ján Tomko Reviewed-by: Andrea Bolognani --- docs/schemas/basictypes.rng | 27 ++++++++++ docs/schemas/domaincommon.rng | 1 + src/conf/device_conf.c | 53 +++++++++++++++++++ src/conf/domain_addr.c | 3 ++ src/conf/domain_conf.c | 12 ++++- src/libvirt_private.syms | 2 + src/util/virpci.c | 26 +++++++++ src/util/virpci.h | 6 +++ .../disk-virtio-s390-zpci.args | 25 +++++++++ .../disk-virtio-s390-zpci.xml | 19 +++++++ tests/qemuxml2argvdata/hostdev-vfio-zpci.args | 23 ++++++++ tests/qemuxml2argvdata/hostdev-vfio-zpci.xml | 21 ++++++++ tests/qemuxml2argvtest.c | 7 +++ .../disk-virtio-s390-zpci.xml | 31 +++++++++++ .../qemuxml2xmloutdata/hostdev-vfio-zpci.xml | 32 +++++++++++ tests/qemuxml2xmltest.c | 6 +++ 16 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/disk-virtio-s390-zpci.args create mode 100644 tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci.args create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci.xml create mode 100644 tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng index 14a3670e5c..71a6db3bb4 100644 --- a/docs/schemas/basictypes.rng +++ b/docs/schemas/basictypes.rng @@ -65,6 +65,17 @@ + + + + (0x)?[0-9a-fA-F]{1,8} + + + 0 + 4294967295 + + + @@ -111,6 +122,22 @@ + + + + + + + + + + + + + + + + diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index cad189513a..fa934dfba0 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5231,6 +5231,7 @@ pci + diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 98a419f40f..f9f6b6e38f 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -47,6 +47,45 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "dimm", ); +static int +virZPCIDeviceAddressParseXML(xmlNodePtr node, + virPCIDeviceAddressPtr addr) +{ + virZPCIDeviceAddress def = { 0 }; + char *uid; + char *fid; + int ret = -1; + + uid = virXMLPropString(node, "uid"); + fid = virXMLPropString(node, "fid"); + + if (uid && + virStrToLong_uip(uid, NULL, 0, &def.uid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse
'uid' attribute")); + goto cleanup; + } + + if (fid && + virStrToLong_uip(fid, NULL, 0, &def.fid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse
'fid' attribute")); + goto cleanup; + } + + if (!virZPCIDeviceAddressIsEmpty(&def) && + !virZPCIDeviceAddressIsValid(&def)) + goto cleanup; + + addr->zpci = def; + ret = 0; + + cleanup: + VIR_FREE(uid); + VIR_FREE(fid); + return ret; +} + int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst, virDomainDeviceInfoPtr src) @@ -181,6 +220,8 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, virPCIDeviceAddressPtr addr) { char *domain, *slot, *bus, *function, *multi; + xmlNodePtr cur; + xmlNodePtr zpci = NULL; int ret = -1; memset(addr, 0, sizeof(*addr)); @@ -230,6 +271,18 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, if (!virPCIDeviceAddressIsEmpty(addr) && !virPCIDeviceAddressIsValid(addr, true)) goto cleanup; + cur = node->children; + while (cur) { + if (cur->type == XML_ELEMENT_NODE && + virXMLNodeNameEqual(cur, "zpci")) { + zpci = cur; + } + cur = cur->next; + } + + if (zpci && virZPCIDeviceAddressParseXML(zpci, addr) < 0) + goto cleanup; + ret = 0; cleanup: diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 0c00302c13..380091f049 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1040,6 +1040,9 @@ virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, dev->isolationGroup, false) < 0) return -1; + addr.extFlags = dev->addr.pci.extFlags; + addr.zpci = dev->addr.pci.zpci; + if (!addrs->dryRun) { dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; dev->addr.pci = addr; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 959e1e4ec3..793bbe1fbd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6423,6 +6423,7 @@ virDomainDeviceInfoFormat(virBufferPtr buf, unsigned int flags) { virBuffer attrBuf = VIR_BUFFER_INITIALIZER; + virBuffer childBuf = VIR_BUFFER_INITIALIZER; if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) && info->bootIndex) { virBufferAsprintf(buf, "bootIndex); @@ -6485,6 +6486,14 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAsprintf(&attrBuf, " multifunction='%s'", virTristateSwitchTypeToString(info->addr.pci.multi)); } + + if (!virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci)) { + virBufferSetChildIndent(&childBuf, buf); + virBufferAsprintf(&childBuf, + "\n", + info->addr.pci.zpci.uid, + info->addr.pci.zpci.fid); + } break; case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: @@ -6552,9 +6561,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf, break; } - virXMLFormatElement(buf, "address", &attrBuf, NULL); + virXMLFormatElement(buf, "address", &attrBuf, &childBuf); virBufferFreeAndReset(&attrBuf); + virBufferFreeAndReset(&childBuf); } static int diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1f8c3d04c1..5588fa2e42 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2569,6 +2569,8 @@ virPCIHeaderTypeToString; virPCIIsVirtualFunction; virPCIStubDriverTypeFromString; virPCIStubDriverTypeToString; +virZPCIDeviceAddressIsEmpty; +virZPCIDeviceAddressIsValid; # util/virperf.h diff --git a/src/util/virpci.c b/src/util/virpci.c index 0f680efbe6..efa2d1662a 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -2563,6 +2563,32 @@ virPCIDeviceAddressParse(char *address, #ifdef __linux__ +bool +virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci) +{ + /* We don't need to check fid because fid covers + * all range of uint32 type. + */ + if (zpci->uid > VIR_DOMAIN_DEVICE_ZPCI_MAX_UID || + zpci->uid == 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address uid='0x%.4x', " + "must be > 0x0000 and <= 0x%.4x"), + zpci->uid, + VIR_DOMAIN_DEVICE_ZPCI_MAX_UID); + return false; + } + + return true; +} + +bool +virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr) +{ + return !(addr->uid || addr->fid); +} + + /* * returns true if equal */ diff --git a/src/util/virpci.h b/src/util/virpci.h index 0e40d86b97..a2e795eff9 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -37,6 +37,9 @@ typedef virPCIDeviceAddress *virPCIDeviceAddressPtr; typedef struct _virPCIDeviceList virPCIDeviceList; typedef virPCIDeviceList *virPCIDeviceListPtr; +# define VIR_DOMAIN_DEVICE_ZPCI_MAX_UID UINT16_MAX +# define VIR_DOMAIN_DEVICE_ZPCI_MAX_FID UINT32_MAX + typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress; typedef virZPCIDeviceAddress *virZPCIDeviceAddressPtr; struct _virZPCIDeviceAddress { @@ -239,6 +242,9 @@ char *virPCIDeviceAddressAsString(virPCIDeviceAddressPtr addr) int virPCIDeviceAddressParse(char *address, virPCIDeviceAddressPtr bdf); +bool virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci); +bool virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr); + int virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path, int pfNetDevIdx, char **pfname, diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args new file mode 100644 index 0000000000..8ac435cb3e --- /dev/null +++ b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args @@ -0,0 +1,25 @@ +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-virtio,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 \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk0,\ +id=virtio-disk0,bootindex=1 \ +-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0000 diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml new file mode 100644 index 0000000000..8bf4a23670 --- /dev/null +++ b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml @@ -0,0 +1,19 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 1 + + hvm + + + /usr/bin/qemu-system-s390x + + + +
+ +
+
+
+
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args new file mode 100644 index 0000000000..d6b1520c47 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args @@ -0,0 +1,23 @@ +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-virtio,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 \ +-device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x8 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml new file mode 100644 index 0000000000..002b99c52d --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml @@ -0,0 +1,21 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + + hvm + + + /usr/bin/qemu-system-s390x + + + + +
+ +
+ +
+ + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 39a7f1f53c..7b9e6bf2be 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1076,6 +1076,10 @@ 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_VIRTIO_BLK_SCSI); DO_TEST("disk-virtio-queues", QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES); @@ -1679,6 +1683,9 @@ mymain(void) DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-vfio-zpci", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_DEVICE_ZPCI); DO_TEST("pci-rom", NONE); DO_TEST("pci-rom-disabled", NONE); DO_TEST("pci-rom-disabled-invalid", NONE); diff --git a/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml b/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml new file mode 100644 index 0000000000..37684c82b1 --- /dev/null +++ b/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml @@ -0,0 +1,31 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-s390x + + + + +
+ +
+
+ + +
+ + + + diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml new file mode 100644 index 0000000000..fc8c38ab66 --- /dev/null +++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml @@ -0,0 +1,32 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-s390x + + + + +
+ +
+ +
+ + +
+ + + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 89640f641a..53de9726f4 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -376,6 +376,9 @@ mymain(void) QEMU_CAPS_VIRTIO_SCSI); DO_TEST("disk-virtio-scsi-ioeventfd", QEMU_CAPS_VIRTIO_SCSI); + DO_TEST("disk-virtio-s390-zpci", + QEMU_CAPS_DEVICE_ZPCI, + QEMU_CAPS_CCW); DO_TEST("disk-scsi-megasas", QEMU_CAPS_SCSI_MEGASAS); DO_TEST("disk-scsi-mptsas1068", @@ -458,6 +461,9 @@ mymain(void) DO_TEST("hostdev-usb-address", NONE); DO_TEST("hostdev-pci-address", NONE); DO_TEST("hostdev-vfio", NONE); + DO_TEST("hostdev-vfio-zpci", + QEMU_CAPS_DEVICE_ZPCI, + QEMU_CAPS_CCW); DO_TEST("hostdev-mdev-precreated", NONE); DO_TEST("hostdev-mdev-display", QEMU_CAPS_VFIO_PCI_DISPLAY); DO_TEST("pci-rom", NONE);