[PATCH v3 00/29] ppc64 PowerNV machines support

Hi, This new version contains changes proposed by Jano. The most notable change is on patch 9, where pnv_pnv3/pnv_phb4 capabilities are now being probed and, if the QEMU version isn't high enough, they are cleared from qemuCaps. For convenience, the patches that are pending review/acks are patches 14, 17, 19, 20, 22, 23 and 24. v2 link: https://listman.redhat.com/archives/libvir-list/2022-January/msg01149.html Daniel Henrique Barboza (29): qemu_domain.c: add PowerNV machine helpers qemu_capabilities.c: use 'MachineIsPowerPC' in DeviceDiskCaps qemu_domain: turn qemuDomainMachineIsPSeries() static qemu_validate.c: use qemuDomainIsPowerPC() in qemuValidateDomainChrDef() qemu_domain.c: define ISA as default PowerNV serial qemu_validate.c: enhance 'machine type not supported' message qemu_domain.c: disable default devices for PowerNV machines tests: add basic PowerNV8 test qemu: introduce QEMU_CAPS_DEVICE_PNV_PHB3 conf, qemu: add 'pnv-phb3-root-port' PCI controller model name conf, qemu: add 'pnv-phb3' PCI controller model name domain_conf.c: fix identation in virDomainControllerDefParseXML() conf: parse and format <target chip-id='...'/> formatdomain.rst: add 'index' semantics for PowerNV domains conf: introduce virDomainControllerIsPowerNVPHB conf, qemu: add default 'chip-id' value for pnv-phb3 controllers conf, qemu: add default 'targetIndex' value for pnv-phb3 devs qemu_command.c: add command line for the pnv-phb3 device qemu_domain_address.c: change pnv-phb3 minimal downstream slot domain_conf: always format pnv-phb3-root-port address tests: add pnv-phb3-root-port test domain_validate.c: allow targetIndex 0 out of idx 0 for PowerNV PHBs domain_conf.c: reject duplicated pnv-phb3 devices qemu: introduce QEMU_CAPS_DEVICE_PNV_PHB4 conf, qemu: add 'pnv-phb4-root-port' PCI controller model name domain_conf.c: add phb4-root-port to IsPowerNVRootPort() conf, qemu: add 'pnv-phb4' controller model name domain_conf.c: add pnv-phb4 to ControllerIsPowerNVPHB() tests: add PowerNV9 tests docs/formatdomain.rst | 12 +- docs/schemas/domaincommon.rng | 10 ++ src/conf/domain_conf.c | 156 ++++++++++++++---- src/conf/domain_conf.h | 8 + src/conf/domain_validate.c | 5 +- src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 19 ++- src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_command.c | 21 ++- src/qemu/qemu_domain.c | 51 +++++- src/qemu/qemu_domain.h | 4 +- src/qemu/qemu_domain_address.c | 64 ++++++- src/qemu/qemu_validate.c | 62 ++++++- .../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 2 + .../qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 2 + .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 2 + .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 2 + .../powernv8-basic.ppc64-latest.args | 34 ++++ tests/qemuxml2argvdata/powernv8-basic.xml | 16 ++ tests/qemuxml2argvdata/powernv8-dupPHBs.err | 1 + .../powernv8-dupPHBs.ppc64-latest.err | 1 + tests/qemuxml2argvdata/powernv8-dupPHBs.xml | 27 +++ .../powernv8-root-port.ppc64-latest.args | 35 ++++ tests/qemuxml2argvdata/powernv8-root-port.xml | 17 ++ .../powernv8-two-sockets.ppc64-latest.args | 35 ++++ .../qemuxml2argvdata/powernv8-two-sockets.xml | 26 +++ .../powernv9-dupPHBs.ppc64-latest.err | 1 + tests/qemuxml2argvdata/powernv9-dupPHBs.xml | 27 +++ .../powernv9-root-port.ppc64-latest.args | 35 ++++ tests/qemuxml2argvdata/powernv9-root-port.xml | 17 ++ tests/qemuxml2argvtest.c | 7 + .../powernv8-basic.ppc64-latest.xml | 34 ++++ .../powernv8-root-port.ppc64-latest.xml | 39 +++++ .../powernv8-two-sockets.ppc64-latest.xml | 39 +++++ .../powernv9-root-port.ppc64-latest.xml | 39 +++++ .../qemuxml2xmloutdata/powernv9-root-port.xml | 36 ++++ tests/qemuxml2xmltest.c | 5 + 37 files changed, 848 insertions(+), 48 deletions(-) create mode 100644 tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-basic.xml create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.err create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.ppc64-latest.err create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.xml create mode 100644 tests/qemuxml2argvdata/powernv8-root-port.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-root-port.xml create mode 100644 tests/qemuxml2argvdata/powernv8-two-sockets.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-two-sockets.xml create mode 100644 tests/qemuxml2argvdata/powernv9-dupPHBs.ppc64-latest.err create mode 100644 tests/qemuxml2argvdata/powernv9-dupPHBs.xml create mode 100644 tests/qemuxml2argvdata/powernv9-root-port.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv9-root-port.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-root-port.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-two-sockets.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv9-root-port.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv9-root-port.xml -- 2.35.1

The PowerNV (Power Non-Virtualized) QEMU ppc64 machine is the emulation of a bare-metal IBM Power host. It follows the OPAL (OpenPower Abstration Layer) API/ABI, most specifically Skiboot [1]. For now, libvirt has support for the pSeries QEMU machine, which is the emulation of a logical partition (guest) that would run on top of a bare-metal system. This patch introduces the helpers that are going to be used to add a basic support for PowerNV domains in libvirt. Given that there are quite a few similarities in how pSeries and PowerNVv should be handled, we're also adding a 'qemuDomainIsPowerPC' helper that will be used in those instances. [1] https://open-power.github.io/skiboot/doc/overview.html Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain.c | 36 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 4 ++++ 2 files changed, 40 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index acc76c1cd6..bacde142f8 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8759,6 +8759,42 @@ qemuDomainIsPSeries(const virDomainDef *def) } +bool +qemuDomainIsPowerNV(const virDomainDef *def) +{ + if (STRPREFIX(def->os.machine, "powernv")) + return true; + + return false; +} + + +/* + * PowerNV and pSeries domains shares a lot of common traits. This + * helper avoids repeating "if (pseries || powernv)" everywhere this + * is applicable. + */ +bool +qemuDomainIsPowerPC(const virDomainDef *def) +{ + return qemuDomainIsPSeries(def) || qemuDomainIsPowerNV(def); +} + + +/* + * Similar to qemuDomainIsPowerPC(). Usable when the caller doesn't + * have access to a virDomainDef pointer. + */ +bool +qemuDomainMachineIsPowerPC(const char *machine, const virArch arch) +{ + if (STRPREFIX(machine, "powernv")) + return true; + + return qemuDomainMachineIsPSeries(machine, arch); +} + + bool qemuDomainIsMipsMalta(const virDomainDef *def) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index be56b5dbb3..f64608660c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -764,6 +764,8 @@ bool qemuDomainMachineIsARMVirt(const char *machine, const virArch arch); bool qemuDomainMachineIsPSeries(const char *machine, const virArch arch); +bool qemuDomainMachineIsPowerPC(const char *machine, + const virArch arch); bool qemuDomainMachineHasBuiltinIDE(const char *machine, const virArch arch); @@ -773,6 +775,8 @@ bool qemuDomainIsS390CCW(const virDomainDef *def); bool qemuDomainIsARMVirt(const virDomainDef *def); bool qemuDomainIsRISCVVirt(const virDomainDef *def); bool qemuDomainIsPSeries(const virDomainDef *def); +bool qemuDomainIsPowerNV(const virDomainDef *def); +bool qemuDomainIsPowerPC(const virDomainDef *def); bool qemuDomainIsMipsMalta(const virDomainDef *def); bool qemuDomainHasPCIRoot(const virDomainDef *def); bool qemuDomainHasPCIeRoot(const virDomainDef *def); -- 2.35.1

Both pSeries and PowerNV machines don't have floppy device support. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_capabilities.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 529e9ceaf5..28e7820d0e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -6190,8 +6190,8 @@ virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCaps *qemuCaps, VIR_DOMAIN_DISK_DEVICE_CDROM, VIR_DOMAIN_DISK_DEVICE_LUN); - /* PowerPC pseries based VMs do not support floppy device */ - if (!qemuDomainMachineIsPSeries(machine, qemuCaps->arch)) { + /* PowerPC domains do not support floppy device */ + if (!qemuDomainMachineIsPowerPC(machine, qemuCaps->arch)) { VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice, VIR_DOMAIN_DISK_DEVICE_FLOPPY); VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_FDC); } -- 2.35.1

The function is now unused outside of qemu_domain.c. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bacde142f8..0352cad985 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8657,7 +8657,7 @@ qemuDomainMachineIsRISCVVirt(const char *machine, /* You should normally avoid this function and use * qemuDomainIsPSeries() instead. */ -bool +static bool qemuDomainMachineIsPSeries(const char *machine, const virArch arch) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index f64608660c..be35e11625 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -762,8 +762,6 @@ virDomainChrDef *qemuFindAgentConfig(virDomainDef *def); * doesn't have "Machine" in the name instead. */ bool qemuDomainMachineIsARMVirt(const char *machine, const virArch arch); -bool qemuDomainMachineIsPSeries(const char *machine, - const virArch arch); bool qemuDomainMachineIsPowerPC(const char *machine, const virArch arch); bool qemuDomainMachineHasBuiltinIDE(const char *machine, -- 2.35.1

Both PowerNV and pSeries machines don't support parallel ports. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index f27e480696..f90348c324 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2012,7 +2012,7 @@ qemuValidateDomainChrDef(const virDomainChrDef *dev, return -1; if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL && - (ARCH_IS_S390(def->os.arch) || qemuDomainIsPSeries(def))) { + (ARCH_IS_S390(def->os.arch) || qemuDomainIsPowerPC(def))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("parallel ports are not supported")); return -1; -- 2.35.1

The PowerNV machines uses ISA as the default serial type. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0352cad985..c81c63369c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5187,6 +5187,8 @@ qemuDomainChrDefPostParse(virDomainChrDef *chr, chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM; } else if (ARCH_IS_S390(def->os.arch)) { chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP; + } else if (qemuDomainIsPowerNV(def)) { + chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA; } } -- 2.35.1

Add 'virt type' to allow for an easier time debugging. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_validate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index f90348c324..ad8f0f94ff 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1101,8 +1101,9 @@ qemuValidateDomainDef(const virDomainDef *def, if (!virQEMUCapsIsMachineSupported(qemuCaps, def->virtType, def->os.machine)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Emulator '%s' does not support machine type '%s'"), - def->emulator, def->os.machine); + _("Emulator '%s' does not support machine type '%s' for virt type '%s'"), + def->emulator, def->os.machine, + virDomainVirtTypeToString(def->virtType)); return -1; } -- 2.35.1

PowerNV domains will support pcie-root devices as PHBs, in a similar fashion as pSeries domains supports the spapr-pci-host-bridge as a pci-root model. Set 'addPCIRoot' to false since we'll not be using this buses in this machine. 'addDefaultMemballoon' is also set to false since the balloon driver wasn't really tested with the PowerNV kernel. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c81c63369c..4cf030c485 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3684,6 +3684,15 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver, * add the definition if not already present */ if (qemuDomainIsPSeries(def)) addPanicDevice = true; + + if (qemuDomainIsPowerNV(def)) { + addPCIRoot = false; + addDefaultUSB = false; + addDefaultUSBKBD = false; + addDefaultUSBMouse = false; + addDefaultMemballoon = false; + } + break; case VIR_ARCH_ALPHA: -- 2.35.1

We're now able to boot a simple PowerNV8 domain in libvirt. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- .../powernv8-basic.ppc64-latest.args | 33 +++++++++++++++++++ tests/qemuxml2argvdata/powernv8-basic.xml | 16 +++++++++ tests/qemuxml2argvtest.c | 2 ++ .../powernv8-basic.ppc64-latest.xml | 31 +++++++++++++++++ tests/qemuxml2xmltest.c | 2 ++ 5 files changed, 84 insertions(+) create mode 100644 tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-basic.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml diff --git a/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args b/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args new file mode 100644 index 0000000000..c9616ded13 --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args @@ -0,0 +1,33 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine powernv8,usb=off,dump-guest-core=off,memory-backend=pnv.ram \ +-accel tcg \ +-cpu POWER8 \ +-m 2048 \ +-object '{"qom-type":"memory-backend-ram","id":"pnv.ram","size":2147483648}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid b20fcfe3-4a0a-4039-8735-9e024256e0f7 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-usb \ +-chardev pty,id=charserial0 \ +-device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/powernv8-basic.xml b/tests/qemuxml2argvdata/powernv8-basic.xml new file mode 100644 index 0000000000..a92fc1282c --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-basic.xml @@ -0,0 +1,16 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + </os> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <console type='pty'> + <target type='serial' port='0'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ce475df466..a4dcac4d95 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2175,6 +2175,8 @@ mymain(void) DO_TEST_PARSE_ERROR_NOCAPS("seclabel-multiple"); DO_TEST_PARSE_ERROR_NOCAPS("seclabel-device-duplicates"); + DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); + DO_TEST("pseries-basic", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_DEVICE_SPAPR_VTY); diff --git a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml new file mode 100644 index 0000000000..cb9b3cf86f --- /dev/null +++ b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml @@ -0,0 +1,31 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER8</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <audio id='1' type='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 052950b86f..da55b3368f 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -662,6 +662,8 @@ mymain(void) QEMU_CAPS_OBJECT_RNG_EGD); DO_TEST_CAPS_LATEST("virtio-rng-builtin"); + DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); + DO_TEST("pseries-nvram", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_DEVICE_NVRAM); -- 2.35.1

QEMU_CAPS_DEVICE_PNV_PHB3 indicates binary support for the pnv-phb3 device, the pcie-root controller for PowerNV8 domains, and also the pnv-phb3-root-port device, its pcie-root-port device. This capability is present in QEMU since 5.0.0 but these devices are user-creatable only after QEMU 6.2.0. This means that probing it as default will be misleading for users. Instead, let's use virQEMUCapsInitQMPVersionCaps() to check for the adequate QEMU version and arch, clearing the capability if necessary. Suggested-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_capabilities.c | 11 +++++++++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 1 + 6 files changed, 18 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 28e7820d0e..dbd9065a99 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -665,6 +665,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-mem-pci.prealloc", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC */ "calc-dirty-rate", /* QEMU_CAPS_CALC_DIRTY_RATE */ "dirtyrate-param.mode", /* QEMU_CAPS_DIRTYRATE_MODE */ + + /* 425 */ + "pnv-phb3", /* QEMU_CAPS_DEVICE_PNV_PHB3 */ ); @@ -1401,6 +1404,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, { "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST }, { "virtio-mem-pci", QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI }, + { "pnv-phb3", QEMU_CAPS_DEVICE_PNV_PHB3 }, }; @@ -5243,6 +5247,13 @@ virQEMUCapsInitQMPVersionCaps(virQEMUCaps *qemuCaps) */ if (qemuCaps->version < 5002000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_ENABLE_FIPS); + + /* PowerNV pnv-phb devices weren't user creatable up to + * QEMU 6.2.0. The version value set here was taken from a + * binary post 6.2.0 release that has user creatable pnv-phb + * support. */ + if (qemuCaps->version <= 6002000 && ARCH_IS_PPC64(qemuCaps->arch)) + virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_PNV_PHB3); } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f6188b42de..47845fbc59 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -641,6 +641,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_CALC_DIRTY_RATE, /* accepts calc-dirty-rate */ QEMU_CAPS_DIRTYRATE_MODE , /* calc-dirty-rate accepts mode parameter */ + /* 425 */ + QEMU_CAPS_DEVICE_PNV_PHB3, /* devices pnv-phb3 and pnv-phb3-root-port */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml index 070d0f2982..adaa13f6e1 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -186,6 +186,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <flag name='pnv-phb3'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml index e050514fc1..4c3526f499 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml @@ -190,6 +190,7 @@ <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> <flag name='calc-dirty-rate'/> + <flag name='pnv-phb3'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml index 9fe9c27d14..7dfe86ba30 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml @@ -201,6 +201,7 @@ <flag name='sev-guest-kernel-hashes'/> <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> + <flag name='pnv-phb3'/> <version>6002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml index 5d7f283a73..57c5ead7a4 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml @@ -202,6 +202,7 @@ <flag name='device.json+hotplug'/> <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> + <flag name='pnv-phb3'/> <version>6002050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900243</microcodeVersion> -- 2.35.1

Apart from being usable only with pnv-phb3 PCIE host bridges (to be added soon), this device acts as a regular pcie-root-port but with a specific model name. No doc changes in formatdomain.rst were made because the PCI model name isn't something that users are supposed to be setting or changing. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_domain_address.c | 5 +++++ src/qemu/qemu_validate.c | 12 +++++++++++- 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 964b0c9e2f..ad9432ea3d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2602,6 +2602,7 @@ <!-- implementations of "pcie-root-port" --> <value>ioh3420</value> <value>pcie-root-port</value> + <value>pnv-phb3-root-port</value> <!-- implementations of "pcie-switch-upstream-port" --> <value>x3130-upstream</value> <!-- implementations of "pcie-switch-downstream-port" --> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 34fec887a3..b4f13c4b98 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -438,6 +438,7 @@ VIR_ENUM_IMPL(virDomainControllerPCIModelName, "pcie-root-port", "spapr-pci-host-bridge", "pcie-pci-bridge", + "pnv-phb3-root-port", ); VIR_ENUM_IMPL(virDomainControllerModelSCSI, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9fcf842ee7..60be338541 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -646,6 +646,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE, + VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST } virDomainControllerPCIModelName; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index dd0680f57f..56491e04fe 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2421,6 +2421,11 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDef *cont, *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE; break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + if (qemuDomainIsPowerNV(def)) { + *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT; + break; + } + /* Use generic PCIe Root Ports if available, falling back to * ioh3420 otherwise */ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCIE_ROOT_PORT)) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index ad8f0f94ff..37dcebaca3 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3433,6 +3433,8 @@ virValidateControllerPCIModelNameToQEMUCaps(int modelName) return QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE: return QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT: + return QEMU_CAPS_DEVICE_PNV_PHB3; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE: return 0; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST: @@ -3600,10 +3602,18 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420 && - pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT) { + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT && + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT) { virReportControllerInvalidValue(cont, model, modelName, "modelName"); return -1; } + + if (pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT && + !qemuDomainIsPowerNV(def)) { + virReportControllerInvalidValue(cont, model, modelName, "modelName"); + return -1; + } + break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: -- 2.35.1

Add support for the pcie-root implementation that PowerNV8 domains uses, pnv-phb3. It consists of a PCI model name that isn't supposed to be changed by users, so no doc changes in formatdomain.rst were made. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/schemas/domaincommon.rng | 2 ++ src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_domain_address.c | 3 +++ src/qemu/qemu_validate.c | 8 ++++++-- tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml | 4 +++- 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index ad9432ea3d..f472055700 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2597,6 +2597,8 @@ <value>pci-bridge</value> <!-- implementations of "dmi-to-pci-bridge" --> <value>i82801b11-bridge</value> + <!-- implementations of "pcie-root" --> + <value>pnv-phb3</value> <!-- implementations of "pcie-to-pci-bridge" --> <value>pcie-pci-bridge</value> <!-- implementations of "pcie-root-port" --> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b4f13c4b98..06d1294797 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -439,6 +439,7 @@ VIR_ENUM_IMPL(virDomainControllerPCIModelName, "spapr-pci-host-bridge", "pcie-pci-bridge", "pnv-phb3-root-port", + "pnv-phb3", ); VIR_ENUM_IMPL(virDomainControllerModelSCSI, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 60be338541..6848b3a81f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -647,6 +647,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT, + VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST } virDomainControllerPCIModelName; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 56491e04fe..fb0b74fa57 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2450,6 +2450,9 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDef *cont, *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE; break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (qemuDomainIsPowerNV(def)) + *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3; + break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: break; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 37dcebaca3..f15ac545b0 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3435,6 +3435,8 @@ virValidateControllerPCIModelNameToQEMUCaps(int modelName) return QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT: return QEMU_CAPS_DEVICE_PNV_PHB3; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3: + return QEMU_CAPS_DEVICE_PNV_PHB3; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE: return 0; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST: @@ -3563,7 +3565,8 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE && + !qemuDomainIsPowerNV(def)) { virReportControllerInvalidOption(cont, model, modelName, "modelName"); return -1; } @@ -3645,7 +3648,8 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE && + !qemuDomainIsPowerNV(def)) { virReportControllerInvalidValue(cont, model, modelName, "modelName"); return -1; } diff --git a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml index cb9b3cf86f..ebbc0653ca 100644 --- a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml +++ b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml @@ -17,7 +17,9 @@ <on_crash>destroy</on_crash> <devices> <emulator>/usr/bin/qemu-system-ppc64</emulator> - <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb3'/> + </controller> <serial type='pty'> <target type='isa-serial' port='0'> <model name='isa-serial'/> -- 2.35.1

The identation of VIR_DOMAIN_CONTROLLER_TYPE_PCI elements are in the same level as the parent 'if (def->type == ...TYPE_PCI)' clause, and the closing bracket of this 'if' looks like a misplaced bracket of the 'targetIndex' clause that comes right before it. Reviewed-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 06d1294797..955bb36d9f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -9571,40 +9571,40 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt, ntargetNodes = virXPathNodeSet("./target", ctxt, &targetNodes); if (ntargetNodes == 1) { if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { - if (virXMLPropInt(targetNodes[0], "chassisNr", 0, VIR_XML_PROP_NONE, - &def->opts.pciopts.chassisNr, - def->opts.pciopts.chassisNr) < 0) - return NULL; + if (virXMLPropInt(targetNodes[0], "chassisNr", 0, VIR_XML_PROP_NONE, + &def->opts.pciopts.chassisNr, + def->opts.pciopts.chassisNr) < 0) + return NULL; - if (virXMLPropInt(targetNodes[0], "chassis", 0, VIR_XML_PROP_NONE, - &def->opts.pciopts.chassis, - def->opts.pciopts.chassis) < 0) - return NULL; + if (virXMLPropInt(targetNodes[0], "chassis", 0, VIR_XML_PROP_NONE, + &def->opts.pciopts.chassis, + def->opts.pciopts.chassis) < 0) + return NULL; - if (virXMLPropInt(targetNodes[0], "port", 0, VIR_XML_PROP_NONE, - &def->opts.pciopts.port, - def->opts.pciopts.port) < 0) - return NULL; + if (virXMLPropInt(targetNodes[0], "port", 0, VIR_XML_PROP_NONE, + &def->opts.pciopts.port, + def->opts.pciopts.port) < 0) + return NULL; - if (virXMLPropInt(targetNodes[0], "busNr", 0, VIR_XML_PROP_NONE, - &def->opts.pciopts.busNr, - def->opts.pciopts.busNr) < 0) - return NULL; + if (virXMLPropInt(targetNodes[0], "busNr", 0, VIR_XML_PROP_NONE, + &def->opts.pciopts.busNr, + def->opts.pciopts.busNr) < 0) + return NULL; - if (virXMLPropTristateSwitch(targetNodes[0], "hotplug", - VIR_XML_PROP_NONE, - &def->opts.pciopts.hotplug) < 0) - return NULL; + if (virXMLPropTristateSwitch(targetNodes[0], "hotplug", + VIR_XML_PROP_NONE, + &def->opts.pciopts.hotplug) < 0) + return NULL; - if ((rc = virXMLPropInt(targetNodes[0], "index", 0, VIR_XML_PROP_NONE, - &def->opts.pciopts.targetIndex, - def->opts.pciopts.targetIndex)) < 0) - return NULL; + if ((rc = virXMLPropInt(targetNodes[0], "index", 0, VIR_XML_PROP_NONE, + &def->opts.pciopts.targetIndex, + def->opts.pciopts.targetIndex)) < 0) + return NULL; - if ((rc == 1) && def->opts.pciopts.targetIndex == -1) - virReportError(VIR_ERR_XML_ERROR, - _("Invalid target index '%i' in PCI controller"), - def->opts.pciopts.targetIndex); + if ((rc == 1) && def->opts.pciopts.targetIndex == -1) + virReportError(VIR_ERR_XML_ERROR, + _("Invalid target index '%i' in PCI controller"), + def->opts.pciopts.targetIndex); } } else if (ntargetNodes > 1) { virReportError(VIR_ERR_XML_ERROR, "%s", -- 2.35.1

The 'chip-id' attribute indicates which chip/socket that owns the PowerNV pcie-root controller. Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/formatdomain.rst | 6 ++++++ docs/schemas/domaincommon.rng | 5 +++++ src/conf/domain_conf.c | 15 +++++++++++++++ src/conf/domain_conf.h | 1 + 4 files changed, 27 insertions(+) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 9202cd3107..4693c22707 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -3897,6 +3897,12 @@ generated by libvirt. :since:`Since 1.2.19 (QEMU only).` ``index`` pci-root controllers for pSeries guests use this attribute to record the order they will show up in the guest. :since:`Since 3.6.0` +``chip-id`` + pcie-root controllers for ``powernv`` domains use this attribute to indicate + the chip that will own the controller. A chip is equivalent to a CPU socket. + E.g. a ``powernv`` domain with ``<topology> sockets=3`` will have 3 chips. + chip-id=0 refers to the first chip, chip-id=1 refers to the second chip and + so on. :since:`Since 8.1.0` For machine types which provide an implicit PCI bus, the pci-root controller with index=0 is auto-added and required to use PCI devices. pci-root has no diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f472055700..d85290a164 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2655,6 +2655,11 @@ <ref name="unsignedInt"/> </element> </optional> + <optional> + <attribute name="chip-id"> + <ref name="uint8"/> + </attribute> + </optional> </element> </optional> <!-- *-root controllers have an optional element "pcihole64"--> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 955bb36d9f..44327e2abb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2385,6 +2385,7 @@ virDomainControllerDefNew(virDomainControllerType type) def->opts.pciopts.busNr = -1; def->opts.pciopts.targetIndex = -1; def->opts.pciopts.numaNode = -1; + def->opts.pciopts.chipId = -1; break; case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: def->opts.xenbusopts.maxGrantFrames = -1; @@ -9605,6 +9606,16 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt, virReportError(VIR_ERR_XML_ERROR, _("Invalid target index '%i' in PCI controller"), def->opts.pciopts.targetIndex); + + if ((rc = virXMLPropInt(targetNodes[0], "chip-id", 0, VIR_XML_PROP_NONE, + &def->opts.pciopts.chipId, + def->opts.pciopts.chipId)) < 0) + return NULL; + + if ((rc == 1) && def->opts.pciopts.chipId == -1) + virReportError(VIR_ERR_XML_ERROR, + _("Invalid target chip-id '%i' in PCI controller"), + def->opts.pciopts.chipId); } } else if (ntargetNodes > 1) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -23843,6 +23854,7 @@ virDomainControllerDefFormat(virBuffer *buf, def->opts.pciopts.busNr != -1 || def->opts.pciopts.targetIndex != -1 || def->opts.pciopts.numaNode != -1 || + def->opts.pciopts.chipId != -1 || def->opts.pciopts.hotplug != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAddLit(&childBuf, "<target"); if (def->opts.pciopts.chassisNr != -1) @@ -23860,6 +23872,9 @@ virDomainControllerDefFormat(virBuffer *buf, if (def->opts.pciopts.targetIndex != -1) virBufferAsprintf(&childBuf, " index='%d'", def->opts.pciopts.targetIndex); + if (def->opts.pciopts.chipId != -1) + virBufferAsprintf(&childBuf, " chip-id='%d'", + def->opts.pciopts.chipId); if (def->opts.pciopts.hotplug != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&childBuf, " hotplug='%s'", virTristateSwitchTypeToString(def->opts.pciopts.hotplug)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6848b3a81f..7938c4aa19 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -751,6 +751,7 @@ struct _virDomainPCIControllerOpts { int port; int busNr; /* used by pci-expander-bus, -1 == unspecified */ int targetIndex; /* used by spapr-pci-host-bridge, -1 == unspecified */ + int chipId; /* used by powernv pcie-root controllers, -1 == unspecified */ /* numaNode is a *subelement* of target (to match existing * item in memory target config) -1 == unspecified */ -- 2.35.1

We're going to use the 'targetIndex' element for PowerNV PHBs. Clarify that the same attribute will have a different meaning in this context. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/formatdomain.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 4693c22707..e941e8e892 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -3895,8 +3895,10 @@ generated by libvirt. :since:`Since 1.2.19 (QEMU only).` the user of the libvirt API to attach host devices to the correct pci-expander-bus when assigning them to the domain). ``index`` - pci-root controllers for pSeries guests use this attribute to record the - order they will show up in the guest. :since:`Since 3.6.0` + pci-root controllers for ``pSeries`` guests use this attribute to record the + order they will show up in the guest (:since:`Since 3.6.0`). :since:`Since 8.1.0`, + ``powernv`` domains uses this attribute to indicate which slot inside the + chip the pcie-root controller will use. ``chip-id`` pcie-root controllers for ``powernv`` domains use this attribute to indicate the chip that will own the controller. A chip is equivalent to a CPU socket. -- 2.35.1

Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 19 +++++++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + 3 files changed, 21 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 44327e2abb..f72045eb39 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2447,6 +2447,25 @@ virDomainControllerIsPSeriesPHB(const virDomainControllerDef *cont) } +bool +virDomainControllerIsPowerNVPHB(const virDomainControllerDef *cont) +{ + virDomainControllerPCIModelName name; + + if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI || + cont->model != VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) { + return false; + } + + name = cont->opts.pciopts.modelName; + + if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3) + return false; + + return true; +} + + virDomainFSDef * virDomainFSDefNew(virDomainXMLOption *xmlopt) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7938c4aa19..404289aa26 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3338,6 +3338,7 @@ virDomainControllerDef *virDomainControllerDefNew(virDomainControllerType type); void virDomainControllerDefFree(virDomainControllerDef *def); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainControllerDef, virDomainControllerDefFree); bool virDomainControllerIsPSeriesPHB(const virDomainControllerDef *cont); +bool virDomainControllerIsPowerNVPHB(const virDomainControllerDef *cont); virDomainFSDef *virDomainFSDefNew(virDomainXMLOption *xmlopt); void virDomainFSDefFree(virDomainFSDef *def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6f0d72ca38..8bbecf2692 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -287,6 +287,7 @@ virDomainControllerFindByType; virDomainControllerFindUnusedIndex; virDomainControllerInsert; virDomainControllerInsertPreAlloced; +virDomainControllerIsPowerNVPHB; virDomainControllerIsPSeriesPHB; virDomainControllerModelIDETypeFromString; virDomainControllerModelIDETypeToString; -- 2.35.1

If ommited from the controller definition, chip-id defaults to zero. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain_address.c | 16 +++++++++++++++- src/qemu/qemu_validate.c | 5 +++++ .../powernv8-basic.ppc64-latest.xml | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index fb0b74fa57..b72a9b7bf4 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2844,10 +2844,24 @@ qemuDomainAssignPCIAddresses(virDomainDef *def, goto cleanup; } break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (!qemuDomainIsPowerNV(def)) + break; + + /* + * Default to chip-id = 0 since it's guaranteed that one socket + * will always be present. + * + * chipId validation requires CPU topology information that isn't + * available at this point and will be done later on. + */ + if (options->chipId == -1) + options->chipId = 0; + + break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: break; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index f15ac545b0..84a599d577 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3653,6 +3653,11 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, virReportControllerInvalidValue(cont, model, modelName, "modelName"); return -1; } + + if (pciopts->chipId != -1 && !virDomainControllerIsPowerNVPHB(cont)) { + virReportControllerInvalidOption(cont, model, modelName, "chip-id"); + return -1; + } break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: diff --git a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml index ebbc0653ca..28d86d7d9e 100644 --- a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml +++ b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml @@ -19,6 +19,7 @@ <emulator>/usr/bin/qemu-system-ppc64</emulator> <controller type='pci' index='0' model='pcie-root'> <model name='pnv-phb3'/> + <target chip-id='0'/> </controller> <serial type='pty'> <target type='isa-serial' port='0'> -- 2.35.1

As done with the 'chip-id' attribute, use zero as a default targetIndex value for pnv-phb3 devices in case it's absent from the controller definition. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain_address.c | 2 ++ src/qemu/qemu_validate.c | 19 ++++++++++++++++++- .../powernv8-basic.ppc64-latest.xml | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index b72a9b7bf4..d9dcea6581 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2858,6 +2858,8 @@ qemuDomainAssignPCIAddresses(virDomainDef *def, if (options->chipId == -1) options->chipId = 0; + if (options->targetIndex == -1) + options->targetIndex = 0; break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 84a599d577..ad1deb9b56 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3737,6 +3737,24 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, } break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + /* PHBs for PowerNV domains must have a targetIndex */ + if (pciopts->targetIndex == -1 && + virDomainControllerIsPowerNVPHB(cont)) { + virReportControllerMissingOption(cont, model, modelName, "targetIndex"); + return -1; + } + + /* + * targetIndex for pcie-root controllers only applies to + * PowerNV PHBs. + */ + if (pciopts->targetIndex != -1 && + !virDomainControllerIsPowerNVPHB(cont)) { + virReportControllerInvalidOption(cont, model, modelName, "targetIndex"); + return -1; + } + break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: @@ -3744,7 +3762,6 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->targetIndex != -1) { virReportControllerInvalidOption(cont, model, modelName, "targetIndex"); diff --git a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml index 28d86d7d9e..bd22d85f6a 100644 --- a/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml +++ b/tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml @@ -19,7 +19,7 @@ <emulator>/usr/bin/qemu-system-ppc64</emulator> <controller type='pci' index='0' model='pcie-root'> <model name='pnv-phb3'/> - <target chip-id='0'/> + <target index='0' chip-id='0'/> </controller> <serial type='pty'> <target type='isa-serial' port='0'> -- 2.35.1

The command line for the pnv-phb3 device is similar to the spapr-pci-host-bridge command line but adding the extra 'chip-id' attribute. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_command.c | 21 +++++++++++++++++-- .../powernv8-basic.ppc64-latest.args | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index c836799888..5710fba0d9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3135,6 +3135,22 @@ qemuBuildControllerPCIDevProps(virDomainControllerDef *def, break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (!virDomainControllerIsPowerNVPHB(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Unsupported PCI Express root controller")); + return -1; + } + + if (virJSONValueObjectAdd(&props, + "s:driver", modelName, + "i:index", pciopts->targetIndex, + "i:chip-id", pciopts->chipId, + "s:id", def->info.alias, + NULL) < 0) + return -1; + + break; + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Unsupported PCI Express root controller")); return -1; @@ -3322,8 +3338,9 @@ static bool qemuBuildSkipController(const virDomainControllerDef *controller, const virDomainDef *def) { - /* skip pcie-root */ - if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && + /* skip pcie-root for non PowerVM domains */ + if (!qemuDomainIsPowerNV(def) && + controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) return true; diff --git a/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args b/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args index c9616ded13..224e2adba8 100644 --- a/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args +++ b/tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args @@ -26,6 +26,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ +-device '{"driver":"pnv-phb3","index":0,"chip-id":0,"id":"pcie.0"}' \ -usb \ -chardev pty,id=charserial0 \ -device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ -- 2.35.1

The PowerNV PHB3 bus has minimal slot zero. In fact, at this moment, the root complex accepts only a single device, at slot 0x0, due to firmware limitations. The single device restriction is subject to change in upstream QEMU and it's not worth adding this limitation to Libvirt. However, the minimal slot presents a problem. When setting a pnv-phb3-root-port address with slot=0x0, Libvirt changes it to 0x1. This happens because the pnv-phb3 controller is a PCIE_ROOT model, and this model is being set with 'bus->minSlot=1' in domain_addr.c, virDomainPCIAddressBusSetModel(). This means that the root-port is launched with 'addr=0x1' in the QEMU command line and it's not usable by the domain. It is not worth to create a new controller model, replicating all the already existing logic for PCIE_ROOT controllers, just to have a similar PCIE_ROOT bus with minSlots=0. Changing the existing PCIE_ROOT min slot to 0 doesn't make sense either - we would change existing behavior of existing devices. This patch works around this situation by adding a verification in qemuDomainPCIAddressSetCreate() to change the minBus values of the pnv-phb3 devices right before virDomainDeviceInfoIterate(). This is enough to allow for a root port to be added in slot 0 of a pnv-phb3 bus while not being intrusive with existing devices. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_domain_address.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index d9dcea6581..d75b175f82 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1629,6 +1629,17 @@ qemuDomainCollectPCIAddressExtension(virDomainDef *def G_GNUC_UNUSED, return virDomainPCIAddressExtensionReserveAddr(addrs, addr); } +static void +qemuDomainTunePowerNVPhbBuses(virDomainPCIAddressSet *addrs) +{ + size_t i; + + for (i = 0; i < addrs->nbuses; i++) { + if (addrs->buses[i].model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) + addrs->buses[i].minSlot = 0; + } +} + static virDomainPCIAddressSet * qemuDomainPCIAddressSetCreate(virDomainDef *def, virQEMUCaps *qemuCaps, @@ -1721,6 +1732,9 @@ qemuDomainPCIAddressSetCreate(virDomainDef *def, virDomainControllerModelPCITypeToString(defaultModel), i); } + if (qemuDomainIsPowerNV(def)) + qemuDomainTunePowerNVPhbBuses(addrs); + if (virDomainDeviceInfoIterate(def, qemuDomainCollectPCIAddress, addrs) < 0) goto error; -- 2.35.1

pnv-phb3-root-ports can use an all zeroed address (0000:00:0.0) as a way of connecting to a PHB3 bus that has index 0. Today, these addresses aren't being displayed in the domain XML due to the use of virPCIDeviceAddressIsEmpty() inside virDomainDeviceInfoFormat(), where 0000:00:0.0 is considered an empty address and thus not displayed, regardless of the user manually adding <address type='pci' domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> in the domain XML. Changing virPCIDeviceAddressIsEmpty() to recognize the difference between an user adding a zeroed address by hand, versus all the other current cases in which this function is used (e.g. to check whether an address should be assigned or not), is not trivial and will change a lot of existing, working code, to accomodate a niche case of a new device we want to add. Instead, this patch adds a new VIR_DOMAIN_DEF_FORMAT_PCI_ADDR_ALWAYS flag to be used by virDomainDefFormatFlags that will allow for an <address> element to always be formatted regardless of virPCIDeviceAddressIsEmpty() mechanics/semantics. Then we use this flag when formatting pnv-phb3-root-port devices. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 25 ++++++++++++++++++++++++- src/conf/domain_conf.h | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f72045eb39..625949e44e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2466,6 +2466,25 @@ virDomainControllerIsPowerNVPHB(const virDomainControllerDef *cont) } +static bool +virDomainControllerIsPowerNVRootPort(const virDomainControllerDef *cont) +{ + virDomainControllerPCIModelName name; + + if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI || + cont->model != VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT) { + return false; + } + + name = cont->opts.pciopts.modelName; + + if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT) + return false; + + return true; +} + + virDomainFSDef * virDomainFSDefNew(virDomainXMLOption *xmlopt) { @@ -6509,7 +6528,8 @@ virDomainDeviceInfoFormat(virBuffer *buf, switch ((virDomainDeviceAddressType) info->type) { case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: - if (!virPCIDeviceAddressIsEmpty(&info->addr.pci)) { + if (!virPCIDeviceAddressIsEmpty(&info->addr.pci) || + flags & VIR_DOMAIN_DEF_FORMAT_PCI_ADDR_ALWAYS) { virBufferAsprintf(&attrBuf, " domain='0x%04x' bus='0x%02x' " "slot='0x%02x' function='0x%d'", info->addr.pci.domain, @@ -23911,6 +23931,9 @@ virDomainControllerDefFormat(virBuffer *buf, } } + if (virDomainControllerIsPowerNVRootPort(def)) + flags |= VIR_DOMAIN_DEF_FORMAT_PCI_ADDR_ALWAYS; + virDomainControllerDriverFormat(&childBuf, def); virDomainDeviceInfoFormat(&childBuf, &def->info, flags); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 404289aa26..835b8111e0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3508,6 +3508,8 @@ typedef enum { VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM = 1 << 6, VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT = 1 << 7, VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST = 1 << 8, + /* always format the PCI address */ + VIR_DOMAIN_DEF_FORMAT_PCI_ADDR_ALWAYS = 1 << 9, } virDomainDefFormatFlags; /* Use these flags to skip specific domain ABI consistency checks done -- 2.35.1

Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- .../powernv8-root-port.ppc64-latest.args | 35 +++++++++++++++++ tests/qemuxml2argvdata/powernv8-root-port.xml | 17 ++++++++ tests/qemuxml2argvtest.c | 1 + .../powernv8-root-port.ppc64-latest.xml | 39 +++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 5 files changed, 93 insertions(+) create mode 100644 tests/qemuxml2argvdata/powernv8-root-port.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-root-port.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-root-port.ppc64-latest.xml diff --git a/tests/qemuxml2argvdata/powernv8-root-port.ppc64-latest.args b/tests/qemuxml2argvdata/powernv8-root-port.ppc64-latest.args new file mode 100644 index 0000000000..b32e49c54e --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-root-port.ppc64-latest.args @@ -0,0 +1,35 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine powernv8,usb=off,dump-guest-core=off,memory-backend=pnv.ram \ +-accel tcg \ +-cpu POWER8 \ +-m 2048 \ +-object '{"qom-type":"memory-backend-ram","id":"pnv.ram","size":2147483648}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid b20fcfe3-4a0a-4039-8735-9e024256e0f7 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"pnv-phb3","index":0,"chip-id":0,"id":"pcie.0"}' \ +-device '{"driver":"pnv-phb3-root-port","port":0,"chassis":1,"id":"pci.1","bus":"pcie.0","addr":"0x0"}' \ +-usb \ +-chardev pty,id=charserial0 \ +-device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/powernv8-root-port.xml b/tests/qemuxml2argvdata/powernv8-root-port.xml new file mode 100644 index 0000000000..1acb37222d --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-root-port.xml @@ -0,0 +1,17 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + </os> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='pcie-root-port'/> + <console type='pty'> + <target type='serial' port='0'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a4dcac4d95..2da767e2bc 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2176,6 +2176,7 @@ mymain(void) DO_TEST_PARSE_ERROR_NOCAPS("seclabel-device-duplicates"); DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); DO_TEST("pseries-basic", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, diff --git a/tests/qemuxml2xmloutdata/powernv8-root-port.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv8-root-port.ppc64-latest.xml new file mode 100644 index 0000000000..a24154c47f --- /dev/null +++ b/tests/qemuxml2xmloutdata/powernv8-root-port.ppc64-latest.xml @@ -0,0 +1,39 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER8</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pnv-phb3-root-port'/> + <target chassis='1' port='0x0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> + </controller> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <audio id='1' type='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index da55b3368f..288e9698dc 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -663,6 +663,7 @@ mymain(void) DO_TEST_CAPS_LATEST("virtio-rng-builtin"); DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); DO_TEST("pseries-nvram", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, -- 2.35.1

PowerNV PHBs uses the 'targetIndex' attribute in a different manner than pSeries PHBs, having no restiction of targetIndex = 0 in controllers with non-zero indexes. This can happen when the domain has 2 or more sockets and the pnv-phb3 controller can have targetIndex=0 in a different chip-id. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_validate.c | 5 ++- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_validate.c | 5 +++ .../powernv8-two-sockets.ppc64-latest.args | 35 +++++++++++++++++ .../qemuxml2argvdata/powernv8-two-sockets.xml | 26 +++++++++++++ tests/qemuxml2argvtest.c | 1 + .../powernv8-two-sockets.ppc64-latest.xml | 39 +++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 8 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/powernv8-two-sockets.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-two-sockets.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-two-sockets.ppc64-latest.xml diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index f0b8aa2655..27febb7074 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1055,8 +1055,9 @@ virDomainControllerDefValidate(const virDomainControllerDef *controller) return -1; } - if ((controller->idx == 0 && opts->targetIndex != 0) || - (controller->idx != 0 && opts->targetIndex == 0)) { + if (!virDomainControllerIsPowerNVPHB(controller) && + ((controller->idx == 0 && opts->targetIndex != 0) || + (controller->idx != 0 && opts->targetIndex == 0))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only the PCI controller with index 0 can " "have target index 0, and vice versa")); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4cf030c485..2257419cbc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5112,7 +5112,7 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, /* pSeries guests can have multiple pci-root controllers, * but other machine types only support a single one */ - if (!qemuDomainIsPSeries(def) && + if (!qemuDomainIsPowerPC(def) && (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT || cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) && cont->idx != 0) { diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index ad1deb9b56..a172d395aa 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3701,6 +3701,11 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, break; } + /* PowerNV domains, like pSeries guest, can also have + * multiple PHBs. */ + if (virDomainControllerIsPowerNVPHB(cont)) + break; + /* For all other pci-root and pcie-root controllers, though, * the index must be zero */ if (cont->idx != 0) { diff --git a/tests/qemuxml2argvdata/powernv8-two-sockets.ppc64-latest.args b/tests/qemuxml2argvdata/powernv8-two-sockets.ppc64-latest.args new file mode 100644 index 0000000000..67f0611d79 --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-two-sockets.ppc64-latest.args @@ -0,0 +1,35 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine powernv8,usb=off,dump-guest-core=off,memory-backend=pnv.ram \ +-accel tcg \ +-cpu POWER8 \ +-m 2048 \ +-object '{"qom-type":"memory-backend-ram","id":"pnv.ram","size":2147483648}' \ +-overcommit mem-lock=off \ +-smp 2,sockets=2,dies=1,cores=1,threads=1 \ +-uuid b20fcfe3-4a0a-4039-8735-9e024256e0f7 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"pnv-phb3","index":0,"chip-id":0,"id":"pcie.0"}' \ +-device '{"driver":"pnv-phb3","index":0,"chip-id":1,"id":"pcie.1"}' \ +-usb \ +-chardev pty,id=charserial0 \ +-device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/powernv8-two-sockets.xml b/tests/qemuxml2argvdata/powernv8-two-sockets.xml new file mode 100644 index 0000000000..c6f2024a33 --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-two-sockets.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + </os> + <cpu> + <topology sockets='2' dies='1' cores='1' threads='1'/> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='0' chip-id='1'/> + </controller> + <console type='pty'> + <target type='serial' port='0'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 2da767e2bc..d688004251 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2177,6 +2177,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("powernv8-two-sockets", "ppc64"); DO_TEST("pseries-basic", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, diff --git a/tests/qemuxml2xmloutdata/powernv8-two-sockets.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv8-two-sockets.ppc64-latest.xml new file mode 100644 index 0000000000..5d48b79b9f --- /dev/null +++ b/tests/qemuxml2xmloutdata/powernv8-two-sockets.ppc64-latest.xml @@ -0,0 +1,39 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER8</model> + <topology sockets='2' dies='1' cores='1' threads='1'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='0' chip-id='1'/> + </controller> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <audio id='1' type='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 288e9698dc..4514b5a6b2 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -664,6 +664,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("powernv8-two-sockets", "ppc64"); DO_TEST("pseries-nvram", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, -- 2.35.1

These devices must have unique targetIndex/chip-id pairs. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 35 +++++++++++++++++++ tests/qemuxml2argvdata/powernv8-dupPHBs.err | 1 + .../powernv8-dupPHBs.ppc64-latest.err | 1 + tests/qemuxml2argvdata/powernv8-dupPHBs.xml | 27 ++++++++++++++ tests/qemuxml2argvtest.c | 1 + 5 files changed, 65 insertions(+) create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.err create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.ppc64-latest.err create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 625949e44e..c551134d37 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2485,6 +2485,33 @@ virDomainControllerIsPowerNVRootPort(const virDomainControllerDef *cont) } +/* Caller must ensure that 'cont' is a PowerNV PHB device */ +static bool +virDomainControllerDuplicatedPHB(virDomainDef *def, + virDomainControllerDef *cont) +{ + int chipId = cont->opts.pciopts.chipId; + int targetIndex = cont->opts.pciopts.targetIndex; + size_t i; + + for (i = 0; i < def->ncontrollers; i++) { + virDomainControllerDef *cont2 = def->controllers[i]; + + if (!virDomainControllerIsPowerNVPHB(cont2)) + continue; + + if (cont2 == cont) + continue; + + if (cont2->opts.pciopts.chipId == chipId && + cont2->opts.pciopts.targetIndex == targetIndex) + return true; + } + + return false; +} + + virDomainFSDef * virDomainFSDefNew(virDomainXMLOption *xmlopt) { @@ -4749,6 +4776,14 @@ virDomainDefRejectDuplicateControllers(virDomainDef *def) cont->idx); goto cleanup; } + + if (virDomainControllerIsPowerNVPHB(cont) && + virDomainControllerDuplicatedPHB(def, cont)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Multiple pnv-phb controllers with same chip-id and index")); + goto cleanup; + } + ignore_value(virBitmapSetBit(bitmaps[cont->type], cont->idx)); } diff --git a/tests/qemuxml2argvdata/powernv8-dupPHBs.err b/tests/qemuxml2argvdata/powernv8-dupPHBs.err new file mode 100644 index 0000000000..bc5879640d --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-dupPHBs.err @@ -0,0 +1 @@ +XML error: Multiple pnv-phb controllers with same chip-id and index diff --git a/tests/qemuxml2argvdata/powernv8-dupPHBs.ppc64-latest.err b/tests/qemuxml2argvdata/powernv8-dupPHBs.ppc64-latest.err new file mode 100644 index 0000000000..bc5879640d --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-dupPHBs.ppc64-latest.err @@ -0,0 +1 @@ +XML error: Multiple pnv-phb controllers with same chip-id and index diff --git a/tests/qemuxml2argvdata/powernv8-dupPHBs.xml b/tests/qemuxml2argvdata/powernv8-dupPHBs.xml new file mode 100644 index 0000000000..43ee3051eb --- /dev/null +++ b/tests/qemuxml2argvdata/powernv8-dupPHBs.xml @@ -0,0 +1,27 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv8'>hvm</type> + </os> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='1' chip-id='0'/> + </controller> + <controller type='pci' index='2' model='pcie-root'> + <model name='pnv-phb3'/> + <target index='1' chip-id='0'/> + </controller> + <console type='pty'> + <target type='serial' port='0'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d688004251..82e8b4482f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2178,6 +2178,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-two-sockets", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST_PARSE_ERROR("powernv8-dupPHBs", "ppc64"); DO_TEST("pseries-basic", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, -- 2.35.1

This capability enables two devices: - pnv-phb4 device, the pcie-root controller for PowerNV9 domains - pnv-phb4-root-port, the pcie-root-port model that is used with the pnv-phb4 device. As with the pnv-phb3 devices, these are also user creatable only after QEMU 6.2.0 but the capability is available since 5.0.0, meaning that we need to check QEMU version and arch manually before setting it. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_capabilities.c | 6 +++++- src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 1 + 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index dbd9065a99..12f296347d 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -668,6 +668,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 425 */ "pnv-phb3", /* QEMU_CAPS_DEVICE_PNV_PHB3 */ + "pnv-phb4", /* QEMU_CAPS_DEVICE_PNV_PHB4 */ ); @@ -1405,6 +1406,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST }, { "virtio-mem-pci", QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI }, { "pnv-phb3", QEMU_CAPS_DEVICE_PNV_PHB3 }, + { "pnv-phb4", QEMU_CAPS_DEVICE_PNV_PHB4 }, }; @@ -5252,8 +5254,10 @@ virQEMUCapsInitQMPVersionCaps(virQEMUCaps *qemuCaps) * QEMU 6.2.0. The version value set here was taken from a * binary post 6.2.0 release that has user creatable pnv-phb * support. */ - if (qemuCaps->version <= 6002000 && ARCH_IS_PPC64(qemuCaps->arch)) + if (qemuCaps->version <= 6002000 && ARCH_IS_PPC64(qemuCaps->arch)) { virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_PNV_PHB3); + virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_PNV_PHB4); + } } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 47845fbc59..f0d6ba2018 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -643,6 +643,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 425 */ QEMU_CAPS_DEVICE_PNV_PHB3, /* devices pnv-phb3 and pnv-phb3-root-port */ + QEMU_CAPS_DEVICE_PNV_PHB4, /* devices pnv-phb4 and pnv-phb4-root-port */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml index adaa13f6e1..913c28e11b 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -187,6 +187,7 @@ <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> <flag name='pnv-phb3'/> + <flag name='pnv-phb4'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml index 4c3526f499..7a635a4743 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml @@ -191,6 +191,7 @@ <flag name='query-dirty-rate'/> <flag name='calc-dirty-rate'/> <flag name='pnv-phb3'/> + <flag name='pnv-phb4'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml index 7dfe86ba30..6a5675105e 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml @@ -202,6 +202,7 @@ <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> <flag name='pnv-phb3'/> + <flag name='pnv-phb4'/> <version>6002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml index 57c5ead7a4..9770707bca 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml @@ -203,6 +203,7 @@ <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> <flag name='pnv-phb3'/> + <flag name='pnv-phb4'/> <version>6002050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900243</microcodeVersion> -- 2.35.1

This device is an implementation of pcie-root-port, similar to its sibling pnv-phb3-root-port. Since it's a new model name that Libvirt automatically sets, we refrain from documenting it to users. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_domain_address.c | 14 +++++++++++++- src/qemu/qemu_validate.c | 8 ++++++-- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index d85290a164..43f78473e1 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2605,6 +2605,7 @@ <value>ioh3420</value> <value>pcie-root-port</value> <value>pnv-phb3-root-port</value> + <value>pnv-phb4-root-port</value> <!-- implementations of "pcie-switch-upstream-port" --> <value>x3130-upstream</value> <!-- implementations of "pcie-switch-downstream-port" --> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c551134d37..089237007a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -440,6 +440,7 @@ VIR_ENUM_IMPL(virDomainControllerPCIModelName, "pcie-pci-bridge", "pnv-phb3-root-port", "pnv-phb3", + "pnv-phb4-root-port", ); VIR_ENUM_IMPL(virDomainControllerModelSCSI, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 835b8111e0..1313534622 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -648,6 +648,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3, + VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST } virDomainControllerPCIModelName; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index d75b175f82..9290083f39 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2413,6 +2413,18 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, } +static virDomainControllerPCIModelName +virDomainControllerGetPowerNVRootPortName(virDomainDef *def) +{ + if (STREQ(def->os.machine, "powernv8")) + return VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT; + else if (STREQ(def->os.machine, "powernv9")) + return VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT; + + return VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE; +} + + static void qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDef *cont, virDomainDef *def, @@ -2436,7 +2448,7 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDef *cont, break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: if (qemuDomainIsPowerNV(def)) { - *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT; + *modelName = virDomainControllerGetPowerNVRootPortName(def); break; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index a172d395aa..37e7c5616c 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3437,6 +3437,8 @@ virValidateControllerPCIModelNameToQEMUCaps(int modelName) return QEMU_CAPS_DEVICE_PNV_PHB3; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3: return QEMU_CAPS_DEVICE_PNV_PHB3; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT: + return QEMU_CAPS_DEVICE_PNV_PHB4; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE: return 0; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST: @@ -3606,12 +3608,14 @@ qemuValidateDomainDeviceDefControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420 && pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT && - pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT) { + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT && + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT) { virReportControllerInvalidValue(cont, model, modelName, "modelName"); return -1; } - if (pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT && + if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT || + pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT) && !qemuDomainIsPowerNV(def)) { virReportControllerInvalidValue(cont, model, modelName, "modelName"); return -1; -- 2.35.1

Make the virDomainControllerIsPowerNVRootPort() helper recognize pnv-phb4-root-port as a PowerNV root port. This will spare us from duplicating checks where the constraints of pnv-phb3-root-port also applies for the pnv-phb4-root-port device. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 089237007a..c6b071c153 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2479,7 +2479,8 @@ virDomainControllerIsPowerNVRootPort(const virDomainControllerDef *cont) name = cont->opts.pciopts.modelName; - if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT) + if ((name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT) && + (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT)) return false; return true; -- 2.35.1

Similar to the existing pnv-phb3 device, pnv-phb4 is also an implementation of pcie-root. No user doc is needed in this case since the user doesn't ideally set PCI model names manually. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_domain_address.c | 14 +++++++++++++- src/qemu/qemu_validate.c | 2 ++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 43f78473e1..9a9ce91aeb 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2599,6 +2599,7 @@ <value>i82801b11-bridge</value> <!-- implementations of "pcie-root" --> <value>pnv-phb3</value> + <value>pnv-phb4</value> <!-- implementations of "pcie-to-pci-bridge" --> <value>pcie-pci-bridge</value> <!-- implementations of "pcie-root-port" --> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c6b071c153..9767aa5c7b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -441,6 +441,7 @@ VIR_ENUM_IMPL(virDomainControllerPCIModelName, "pnv-phb3-root-port", "pnv-phb3", "pnv-phb4-root-port", + "pnv-phb4", ); VIR_ENUM_IMPL(virDomainControllerModelSCSI, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1313534622..7e4c0fc786 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -649,6 +649,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3_ROOT_PORT, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT, + VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST } virDomainControllerPCIModelName; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 9290083f39..9d9da31bc7 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2425,6 +2425,18 @@ virDomainControllerGetPowerNVRootPortName(virDomainDef *def) } +static virDomainControllerPCIModelName +virDomainControllerGetPowerNVPHBName(virDomainDef *def) +{ + if (STREQ(def->os.machine, "powernv8")) + return VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3; + else if (STREQ(def->os.machine, "powernv9")) + return VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4; + + return VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE; +} + + static void qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDef *cont, virDomainDef *def, @@ -2477,7 +2489,7 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDef *cont, break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: if (qemuDomainIsPowerNV(def)) - *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3; + *modelName = virDomainControllerGetPowerNVPHBName(def); break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 37e7c5616c..2d813355d3 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3439,6 +3439,8 @@ virValidateControllerPCIModelNameToQEMUCaps(int modelName) return QEMU_CAPS_DEVICE_PNV_PHB3; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4_ROOT_PORT: return QEMU_CAPS_DEVICE_PNV_PHB4; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4: + return QEMU_CAPS_DEVICE_PNV_PHB4; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE: return 0; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST: -- 2.35.1

Update the virDomainControllerIsPowerNVPHB() helper to make the pnv-phb4 device receive the same handling as the existing pnv-phb3. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9767aa5c7b..d086b5666c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2461,7 +2461,8 @@ virDomainControllerIsPowerNVPHB(const virDomainControllerDef *cont) name = cont->opts.pciopts.modelName; - if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3) + if ((name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB3) && + (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PNV_PHB4)) return false; return true; -- 2.35.1

Since the nuances of PowerNV PHBs and root ports were already handled when adding support for pnv-phb3* devices, we're already set to support PowerNV9 PHBs and root ports as well. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- .../powernv9-dupPHBs.ppc64-latest.err | 1 + tests/qemuxml2argvdata/powernv9-dupPHBs.xml | 27 +++++++++++++ .../powernv9-root-port.ppc64-latest.args | 35 +++++++++++++++++ tests/qemuxml2argvdata/powernv9-root-port.xml | 17 ++++++++ tests/qemuxml2argvtest.c | 2 + .../powernv9-root-port.ppc64-latest.xml | 39 +++++++++++++++++++ .../qemuxml2xmloutdata/powernv9-root-port.xml | 36 +++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 8 files changed, 158 insertions(+) create mode 100644 tests/qemuxml2argvdata/powernv9-dupPHBs.ppc64-latest.err create mode 100644 tests/qemuxml2argvdata/powernv9-dupPHBs.xml create mode 100644 tests/qemuxml2argvdata/powernv9-root-port.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv9-root-port.xml create mode 100644 tests/qemuxml2xmloutdata/powernv9-root-port.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv9-root-port.xml diff --git a/tests/qemuxml2argvdata/powernv9-dupPHBs.ppc64-latest.err b/tests/qemuxml2argvdata/powernv9-dupPHBs.ppc64-latest.err new file mode 100644 index 0000000000..bc5879640d --- /dev/null +++ b/tests/qemuxml2argvdata/powernv9-dupPHBs.ppc64-latest.err @@ -0,0 +1 @@ +XML error: Multiple pnv-phb controllers with same chip-id and index diff --git a/tests/qemuxml2argvdata/powernv9-dupPHBs.xml b/tests/qemuxml2argvdata/powernv9-dupPHBs.xml new file mode 100644 index 0000000000..49af69e6c4 --- /dev/null +++ b/tests/qemuxml2argvdata/powernv9-dupPHBs.xml @@ -0,0 +1,27 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv9'>hvm</type> + </os> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb4'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root'> + <model name='pnv-phb4'/> + <target index='1' chip-id='0'/> + </controller> + <controller type='pci' index='2' model='pcie-root'> + <model name='pnv-phb4'/> + <target index='1' chip-id='0'/> + </controller> + <console type='pty'> + <target type='serial' port='0'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/powernv9-root-port.ppc64-latest.args b/tests/qemuxml2argvdata/powernv9-root-port.ppc64-latest.args new file mode 100644 index 0000000000..007f425273 --- /dev/null +++ b/tests/qemuxml2argvdata/powernv9-root-port.ppc64-latest.args @@ -0,0 +1,35 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine powernv9,usb=off,dump-guest-core=off,memory-backend=pnv.ram \ +-accel tcg \ +-cpu POWER9 \ +-m 2048 \ +-object '{"qom-type":"memory-backend-ram","id":"pnv.ram","size":2147483648}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid b20fcfe3-4a0a-4039-8735-9e024256e0f7 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"pnv-phb4","index":0,"chip-id":0,"id":"pcie.0"}' \ +-device '{"driver":"pnv-phb4-root-port","port":0,"chassis":1,"id":"pci.1","bus":"pcie.0","addr":"0x0"}' \ +-usb \ +-chardev pty,id=charserial0 \ +-device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/powernv9-root-port.xml b/tests/qemuxml2argvdata/powernv9-root-port.xml new file mode 100644 index 0000000000..dfd74446f9 --- /dev/null +++ b/tests/qemuxml2argvdata/powernv9-root-port.xml @@ -0,0 +1,17 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv9'>hvm</type> + </os> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='pcie-root-port'/> + <console type='pty'> + <target type='serial' port='0'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 82e8b4482f..d445ec9871 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2179,6 +2179,8 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-two-sockets", "ppc64"); DO_TEST_CAPS_ARCH_LATEST_PARSE_ERROR("powernv8-dupPHBs", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("powernv9-root-port", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST_PARSE_ERROR("powernv9-dupPHBs", "ppc64"); DO_TEST("pseries-basic", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, diff --git a/tests/qemuxml2xmloutdata/powernv9-root-port.ppc64-latest.xml b/tests/qemuxml2xmloutdata/powernv9-root-port.ppc64-latest.xml new file mode 100644 index 0000000000..135489cf6e --- /dev/null +++ b/tests/qemuxml2xmloutdata/powernv9-root-port.ppc64-latest.xml @@ -0,0 +1,39 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv9'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER9</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb4'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pnv-phb4-root-port'/> + <target chassis='1' port='0x0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> + </controller> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <audio id='1' type='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/powernv9-root-port.xml b/tests/qemuxml2xmloutdata/powernv9-root-port.xml new file mode 100644 index 0000000000..5649526969 --- /dev/null +++ b/tests/qemuxml2xmloutdata/powernv9-root-port.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>b20fcfe3-4a0a-4039-8735-9e024256e0f7</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='powernv9'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <model name='pnv-phb4'/> + <target index='0' chip-id='0'/> + </controller> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pnv-phb4-root-port'/> + <target chassis='1' port='0x0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x00' function='0x0'/> + </controller> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <audio id='1' type='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 4514b5a6b2..a114d58457 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -665,6 +665,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("powernv8-basic", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-root-port", "ppc64"); DO_TEST_CAPS_ARCH_LATEST("powernv8-two-sockets", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("powernv9-root-port", "ppc64"); DO_TEST("pseries-nvram", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, -- 2.35.1

Hi, Just to warn any by passer who might want to review the remaining patches: there are changes in the QEMU side that we would like to make that would make the proposed support here simpler. The planned changes are: - add virtual pnv-phb and pnv-phb-root-port devices. These virtual devices will not be versioned and will be used in all PowerNV machines (powernv8/9/10), meaning that we wouldn't need to add a pnv-phbN/pnv-phbN-root-port pair for each machine; - this new virtual device will have its own capability (QEMU_CAPS_DEVICE_PNV_PHB), which will also simplify what we're doing here - we won't need to snapshot an specific QEMU version that happened to have user creatable PHBs. Most of the already reviewed code will be used in the next version. As soon as the 7.1 support is upstream I'll reroll this series with these changes. Thanks, Daniel On 2/23/22 10:19, Daniel Henrique Barboza wrote:
Hi,
This new version contains changes proposed by Jano. The most notable change is on patch 9, where pnv_pnv3/pnv_phb4 capabilities are now being probed and, if the QEMU version isn't high enough, they are cleared from qemuCaps.
For convenience, the patches that are pending review/acks are patches 14, 17, 19, 20, 22, 23 and 24.
v2 link: https://listman.redhat.com/archives/libvir-list/2022-January/msg01149.html
Daniel Henrique Barboza (29): qemu_domain.c: add PowerNV machine helpers qemu_capabilities.c: use 'MachineIsPowerPC' in DeviceDiskCaps qemu_domain: turn qemuDomainMachineIsPSeries() static qemu_validate.c: use qemuDomainIsPowerPC() in qemuValidateDomainChrDef() qemu_domain.c: define ISA as default PowerNV serial qemu_validate.c: enhance 'machine type not supported' message qemu_domain.c: disable default devices for PowerNV machines tests: add basic PowerNV8 test qemu: introduce QEMU_CAPS_DEVICE_PNV_PHB3 conf, qemu: add 'pnv-phb3-root-port' PCI controller model name conf, qemu: add 'pnv-phb3' PCI controller model name domain_conf.c: fix identation in virDomainControllerDefParseXML() conf: parse and format <target chip-id='...'/> formatdomain.rst: add 'index' semantics for PowerNV domains conf: introduce virDomainControllerIsPowerNVPHB conf, qemu: add default 'chip-id' value for pnv-phb3 controllers conf, qemu: add default 'targetIndex' value for pnv-phb3 devs qemu_command.c: add command line for the pnv-phb3 device qemu_domain_address.c: change pnv-phb3 minimal downstream slot domain_conf: always format pnv-phb3-root-port address tests: add pnv-phb3-root-port test domain_validate.c: allow targetIndex 0 out of idx 0 for PowerNV PHBs domain_conf.c: reject duplicated pnv-phb3 devices qemu: introduce QEMU_CAPS_DEVICE_PNV_PHB4 conf, qemu: add 'pnv-phb4-root-port' PCI controller model name domain_conf.c: add phb4-root-port to IsPowerNVRootPort() conf, qemu: add 'pnv-phb4' controller model name domain_conf.c: add pnv-phb4 to ControllerIsPowerNVPHB() tests: add PowerNV9 tests
docs/formatdomain.rst | 12 +- docs/schemas/domaincommon.rng | 10 ++ src/conf/domain_conf.c | 156 ++++++++++++++---- src/conf/domain_conf.h | 8 + src/conf/domain_validate.c | 5 +- src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 19 ++- src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_command.c | 21 ++- src/qemu/qemu_domain.c | 51 +++++- src/qemu/qemu_domain.h | 4 +- src/qemu/qemu_domain_address.c | 64 ++++++- src/qemu/qemu_validate.c | 62 ++++++- .../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 2 + .../qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 2 + .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 2 + .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 2 + .../powernv8-basic.ppc64-latest.args | 34 ++++ tests/qemuxml2argvdata/powernv8-basic.xml | 16 ++ tests/qemuxml2argvdata/powernv8-dupPHBs.err | 1 + .../powernv8-dupPHBs.ppc64-latest.err | 1 + tests/qemuxml2argvdata/powernv8-dupPHBs.xml | 27 +++ .../powernv8-root-port.ppc64-latest.args | 35 ++++ tests/qemuxml2argvdata/powernv8-root-port.xml | 17 ++ .../powernv8-two-sockets.ppc64-latest.args | 35 ++++ .../qemuxml2argvdata/powernv8-two-sockets.xml | 26 +++ .../powernv9-dupPHBs.ppc64-latest.err | 1 + tests/qemuxml2argvdata/powernv9-dupPHBs.xml | 27 +++ .../powernv9-root-port.ppc64-latest.args | 35 ++++ tests/qemuxml2argvdata/powernv9-root-port.xml | 17 ++ tests/qemuxml2argvtest.c | 7 + .../powernv8-basic.ppc64-latest.xml | 34 ++++ .../powernv8-root-port.ppc64-latest.xml | 39 +++++ .../powernv8-two-sockets.ppc64-latest.xml | 39 +++++ .../powernv9-root-port.ppc64-latest.xml | 39 +++++ .../qemuxml2xmloutdata/powernv9-root-port.xml | 36 ++++ tests/qemuxml2xmltest.c | 5 + 37 files changed, 848 insertions(+), 48 deletions(-) create mode 100644 tests/qemuxml2argvdata/powernv8-basic.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-basic.xml create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.err create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.ppc64-latest.err create mode 100644 tests/qemuxml2argvdata/powernv8-dupPHBs.xml create mode 100644 tests/qemuxml2argvdata/powernv8-root-port.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-root-port.xml create mode 100644 tests/qemuxml2argvdata/powernv8-two-sockets.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv8-two-sockets.xml create mode 100644 tests/qemuxml2argvdata/powernv9-dupPHBs.ppc64-latest.err create mode 100644 tests/qemuxml2argvdata/powernv9-dupPHBs.xml create mode 100644 tests/qemuxml2argvdata/powernv9-root-port.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/powernv9-root-port.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-basic.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-root-port.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv8-two-sockets.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv9-root-port.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/powernv9-root-port.xml
participants (1)
-
Daniel Henrique Barboza