[libvirt] [PATCH v3 00/12] qemu: Validate PCI controller options

Applies cleanly on top of f565321b26dfb78c1dc2d6cf5456b9b80f04c7f3. Changes from [v2]: * replace the old implementation bit by bit using a clever trick suggested by pkrempa; * don't move QEMU capability validation; * add a default: label to all switch statements as recommended by danpb. Changes from [v1]: * error out instead of silently accept invalid options; * shave quite a lot of yaks. [v2] https://www.redhat.com/archives/libvir-list/2018-February/msg00813.html [v1] https://www.redhat.com/archives/libvir-list/2018-February/msg00244.html Andrea Bolognani (12): tests: Add some tests for PCI controller options qemu: Create new qemuDomainDeviceDefValidateControllerPCI() qemu: Validate PCI controller options (modelName) qemu: Validate PCI controller options (index) qemu: Validate PCI controller options (targetIndex) qemu: Validate PCI controller options (pcihole64) qemu: Validate PCI controller options (busNr) qemu: Validate PCI controller options (numaNode) qemu: Validate PCI controller options (chassisNr) qemu: Validate PCI controller options (chassis and port) qemu: Validate PCI controllers (QEMU capabilities) qemu: Remove old qemuDomainDeviceDefValidateControllerPCI() src/qemu/qemu_domain.c | 594 +++++++++++++++------ .../i440fx-controllers-pciopts.xml | 36 ++ tests/qemuxml2argvdata/pcie-expander-bus.xml | 3 - .../pseries-controllers-pciopts.xml | 35 ++ tests/qemuxml2argvdata/q35-controllers-pciopts.xml | 60 +++ tests/qemuxml2argvtest.c | 4 + tests/qemuxml2xmloutdata/pcie-expander-bus.xml | 4 +- 7 files changed, 575 insertions(+), 161 deletions(-) create mode 100644 tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml create mode 100644 tests/qemuxml2argvdata/pseries-controllers-pciopts.xml create mode 100644 tests/qemuxml2argvdata/q35-controllers-pciopts.xml -- 2.14.3

The input configurations set all existing options for all PCI controllers, even those that are not valid for the controller. As we implement validation for PCI controller options, we expect these test to start failing. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../i440fx-controllers-pciopts.args | 24 +++++++ .../i440fx-controllers-pciopts.xml | 36 ++++++++++ .../pseries-controllers-pciopts.args | 22 +++++++ .../pseries-controllers-pciopts.xml | 35 ++++++++++ .../qemuxml2argvdata/q35-controllers-pciopts.args | 28 ++++++++ tests/qemuxml2argvdata/q35-controllers-pciopts.xml | 60 +++++++++++++++++ tests/qemuxml2argvtest.c | 17 +++++ .../i440fx-controllers-pciopts.xml | 45 +++++++++++++ .../pseries-controllers-pciopts.xml | 43 ++++++++++++ .../qemuxml2xmloutdata/q35-controllers-pciopts.xml | 76 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 17 +++++ 11 files changed, 403 insertions(+) create mode 100644 tests/qemuxml2argvdata/i440fx-controllers-pciopts.args create mode 100644 tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml create mode 100644 tests/qemuxml2argvdata/pseries-controllers-pciopts.args create mode 100644 tests/qemuxml2argvdata/pseries-controllers-pciopts.xml create mode 100644 tests/qemuxml2argvdata/q35-controllers-pciopts.args create mode 100644 tests/qemuxml2argvdata/q35-controllers-pciopts.xml create mode 100644 tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml create mode 100644 tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml create mode 100644 tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml diff --git a/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args new file mode 100644 index 0000000000..d85fae5c96 --- /dev/null +++ b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args @@ -0,0 +1,24 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name guest \ +-S \ +-M pc \ +-m 1024 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-numa node,nodeid=0,cpus=0,mem=1024 \ +-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-global i440FX-pcihost.pci-hole64-size=1024K \ +-device pci-bridge,chassis_nr=2,id=pci.1,bus=pci.0,addr=0x3 \ +-device pxb,bus_nr=3,id=pci.2,numa_node=0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml new file mode 100644 index 0000000000..06008b7338 --- /dev/null +++ b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='pci' index='0' model='pci-root'> + <!-- Only pcihole64 is valid --> + <target busNr='1' chassis='1' chassisNr='1' index='0' port='1'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='pci-bridge'> + <!-- Only chassisNr is valid --> + <target busNr='2' chassis='2' chassisNr='2' index='2' port='2'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-expander-bus'> + <!-- Only busNr and numaNode are valid --> + <target busNr='3' chassis='3' chassisNr='3' index='3' port='3'> + <node>0</node> + </target> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/pseries-controllers-pciopts.args b/tests/qemuxml2argvdata/pseries-controllers-pciopts.args new file mode 100644 index 0000000000..5f1edfc833 --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-controllers-pciopts.args @@ -0,0 +1,22 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest \ +-S \ +-M pseries \ +-m 1024 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-numa node,nodeid=0,cpus=0,mem=1024 \ +-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-boot c \ +-device spapr-pci-host-bridge,index=1,id=pci.1,numa_node=0 \ +-device pci-bridge,chassis_nr=3,id=pci.2,bus=pci.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/pseries-controllers-pciopts.xml b/tests/qemuxml2argvdata/pseries-controllers-pciopts.xml new file mode 100644 index 0000000000..088c7159c3 --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-controllers-pciopts.xml @@ -0,0 +1,35 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='pseries'>hvm</type> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pci-root'> + <!-- Only targetIndex is valid --> + <target busNr='1' chassis='1' chassisNr='1' index='0' port='1'/> + </controller> + <controller type='pci' index='1' model='pci-root'> + <!-- Only numaNode and targetIndex are valid --> + <target busNr='2' chassis='2' chassisNr='2' index='1' port='2'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <!-- Only chassisNr is valid --> + <target busNr='3' chassis='3' chassisNr='3' index='3' port='3'> + <node>0</node> + </target> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/q35-controllers-pciopts.args b/tests/qemuxml2argvdata/q35-controllers-pciopts.args new file mode 100644 index 0000000000..44259f5027 --- /dev/null +++ b/tests/qemuxml2argvdata/q35-controllers-pciopts.args @@ -0,0 +1,28 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name guest \ +-S \ +-M q35 \ +-m 1024 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-numa node,nodeid=0,cpus=0,mem=1024 \ +-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-global q35-pcihost.pci-hole64-size=1024K \ +-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ +-device pci-bridge,chassis_nr=3,id=pci.2,bus=pci.1,addr=0x0 \ +-device pxb-pcie,bus_nr=4,id=pci.3,numa_node=0,bus=pcie.0,addr=0x2 \ +-device pcie-root-port,port=0x5,chassis=5,id=pci.4,bus=pcie.0,addr=0x3 \ +-device x3130-upstream,id=pci.5,bus=pci.4,addr=0x0 \ +-device xio3130-downstream,port=0x7,chassis=7,id=pci.6,bus=pci.5,addr=0x0 diff --git a/tests/qemuxml2argvdata/q35-controllers-pciopts.xml b/tests/qemuxml2argvdata/q35-controllers-pciopts.xml new file mode 100644 index 0000000000..f5b8d1e355 --- /dev/null +++ b/tests/qemuxml2argvdata/q35-controllers-pciopts.xml @@ -0,0 +1,60 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <!-- Only pcihole64 is valid --> + <target busNr='1' chassis='1' chassisNr='1' index='0' port='1'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <!-- No option is valid --> + <target busNr='2' chassis='2' chassisNr='2' index='2' port='2'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <!-- Only chassisNr is valid --> + <target busNr='3' chassis='3' chassisNr='3' index='3' port='3'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='3' model='pcie-expander-bus'> + <!-- Only busNr and numaNode are valid --> + <target busNr='4' chassis='4' chassisNr='4' index='4' port='4'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <!-- Only chassis and port are valid --> + <target busNr='5' chassis='5' chassisNr='5' index='5' port='5'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='5' model='pcie-switch-upstream-port'> + <!-- No option is valid --> + <target busNr='6' chassis='6' chassisNr='6' index='6' port='6'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='6' model='pcie-switch-downstream-port'> + <!-- Only chassis and port are valid --> + <target busNr='7' chassis='7' chassisNr='7' index='7' port='7'> + <node>0</node> + </target> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 688846b9b4..9015eb5fb3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2436,6 +2436,23 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_DEVICE_PXB_PCIE); + DO_TEST("i440fx-controllers-pciopts", + QEMU_CAPS_I440FX_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB); + DO_TEST("q35-controllers-pciopts", + QEMU_CAPS_Q35_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB_PCIE, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_X3130_UPSTREAM, + QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM); + DO_TEST("pseries-controllers-pciopts", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, + QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI, QEMU_CAPS_DEVICE_SCSI_GENERIC); diff --git a/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml new file mode 100644 index 0000000000..d171d13705 --- /dev/null +++ b/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml @@ -0,0 +1,45 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </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-x86_64</emulator> + <controller type='pci' index='0' model='pci-root'> + <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='2'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-expander-bus'> + <model name='pxb'/> + <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <controller type='usb' index='0' model='none'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml new file mode 100644 index 0000000000..bbe360e25d --- /dev/null +++ b/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </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='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> + </controller> + <controller type='pci' index='1' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='1'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml new file mode 100644 index 0000000000..5ef7aa564c --- /dev/null +++ b/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml @@ -0,0 +1,76 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </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-x86_64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='2'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-expander-bus'> + <model name='pxb-pcie'/> + <target chassisNr='4' chassis='4' port='0x4' busNr='4' index='4'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassisNr='5' chassis='5' port='0x5' busNr='5' index='5'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='5' model='pcie-switch-upstream-port'> + <model name='x3130-upstream'/> + <target chassisNr='6' chassis='6' port='0x6' busNr='6' index='6'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='6' model='pcie-switch-downstream-port'> + <model name='xio3130-downstream'/> + <target chassisNr='7' chassis='7' port='0x7' busNr='7' index='7'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + </controller> + <controller type='usb' index='0' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0eb9e6c77a..7b8a160788 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1102,6 +1102,23 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_HDA_DUPLEX); + DO_TEST("i440fx-controllers-pciopts", + QEMU_CAPS_I440FX_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB); + DO_TEST("q35-controllers-pciopts", + QEMU_CAPS_Q35_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB_PCIE, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_X3130_UPSTREAM, + QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM); + DO_TEST("pseries-controllers-pciopts", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, + QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST("hostdev-scsi-vhost-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VHOST_SCSI, QEMU_CAPS_DEVICE_SCSI_GENERIC, QEMU_CAPS_VIRTIO_CCW); -- 2.14.3

On 02/21/2018 09:14 AM, Andrea Bolognani wrote:
The input configurations set all existing options for all PCI controllers, even those that are not valid for the controller. As we implement validation for PCI controller options, we expect these test to start failing.
A noble cause, but since multiple options are being tested for multiple controllers in the same file, once you have all the proper checks in place the tests won't actually be verifying all of the negative tests - only the first failure will be noticed - if one of the others is missed, it won't "fail extra hard" or anything. Although I hate to explode the number of tests, I think if you want to have proper negative testing for every options that doesn't belong on a particular controller, then you'll need a separate test case for each combination of option and controller model. And since that would make for a *lot* of test cases if we tried to extrapolate to all other options for all other elements, I don't know that it's worth going down that rabbit hole. (What we really need is a more intelligent test rig that would allow specifying a single test with a list of variations/diffs and a note of whether the test should succeed or fail with that difference. It would end up taking the same amount of time to run the tests, but at least the amount of xml would be drastically reduced.)
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../i440fx-controllers-pciopts.args | 24 +++++++ .../i440fx-controllers-pciopts.xml | 36 ++++++++++ .../pseries-controllers-pciopts.args | 22 +++++++ .../pseries-controllers-pciopts.xml | 35 ++++++++++ .../qemuxml2argvdata/q35-controllers-pciopts.args | 28 ++++++++ tests/qemuxml2argvdata/q35-controllers-pciopts.xml | 60 +++++++++++++++++ tests/qemuxml2argvtest.c | 17 +++++ .../i440fx-controllers-pciopts.xml | 45 +++++++++++++ .../pseries-controllers-pciopts.xml | 43 ++++++++++++ .../qemuxml2xmloutdata/q35-controllers-pciopts.xml | 76 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 17 +++++ 11 files changed, 403 insertions(+) create mode 100644 tests/qemuxml2argvdata/i440fx-controllers-pciopts.args create mode 100644 tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml create mode 100644 tests/qemuxml2argvdata/pseries-controllers-pciopts.args create mode 100644 tests/qemuxml2argvdata/pseries-controllers-pciopts.xml create mode 100644 tests/qemuxml2argvdata/q35-controllers-pciopts.args create mode 100644 tests/qemuxml2argvdata/q35-controllers-pciopts.xml create mode 100644 tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml create mode 100644 tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml create mode 100644 tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml
diff --git a/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args new file mode 100644 index 0000000000..d85fae5c96 --- /dev/null +++ b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args @@ -0,0 +1,24 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name guest \ +-S \ +-M pc \ +-m 1024 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-numa node,nodeid=0,cpus=0,mem=1024 \ +-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-global i440FX-pcihost.pci-hole64-size=1024K \ +-device pci-bridge,chassis_nr=2,id=pci.1,bus=pci.0,addr=0x3 \ +-device pxb,bus_nr=3,id=pci.2,numa_node=0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml new file mode 100644 index 0000000000..06008b7338 --- /dev/null +++ b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='pci' index='0' model='pci-root'> + <!-- Only pcihole64 is valid --> + <target busNr='1' chassis='1' chassisNr='1' index='0' port='1'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='pci-bridge'> + <!-- Only chassisNr is valid --> + <target busNr='2' chassis='2' chassisNr='2' index='2' port='2'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-expander-bus'> + <!-- Only busNr and numaNode are valid --> + <target busNr='3' chassis='3' chassisNr='3' index='3' port='3'> + <node>0</node> + </target> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/pseries-controllers-pciopts.args b/tests/qemuxml2argvdata/pseries-controllers-pciopts.args new file mode 100644 index 0000000000..5f1edfc833 --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-controllers-pciopts.args @@ -0,0 +1,22 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest \ +-S \ +-M pseries \ +-m 1024 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-numa node,nodeid=0,cpus=0,mem=1024 \ +-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-boot c \ +-device spapr-pci-host-bridge,index=1,id=pci.1,numa_node=0 \ +-device pci-bridge,chassis_nr=3,id=pci.2,bus=pci.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/pseries-controllers-pciopts.xml b/tests/qemuxml2argvdata/pseries-controllers-pciopts.xml new file mode 100644 index 0000000000..088c7159c3 --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-controllers-pciopts.xml @@ -0,0 +1,35 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='pseries'>hvm</type> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='pci' index='0' model='pci-root'> + <!-- Only targetIndex is valid --> + <target busNr='1' chassis='1' chassisNr='1' index='0' port='1'/> + </controller> + <controller type='pci' index='1' model='pci-root'> + <!-- Only numaNode and targetIndex are valid --> + <target busNr='2' chassis='2' chassisNr='2' index='1' port='2'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <!-- Only chassisNr is valid --> + <target busNr='3' chassis='3' chassisNr='3' index='3' port='3'> + <node>0</node> + </target> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/q35-controllers-pciopts.args b/tests/qemuxml2argvdata/q35-controllers-pciopts.args new file mode 100644 index 0000000000..44259f5027 --- /dev/null +++ b/tests/qemuxml2argvdata/q35-controllers-pciopts.args @@ -0,0 +1,28 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name guest \ +-S \ +-M q35 \ +-m 1024 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-numa node,nodeid=0,cpus=0,mem=1024 \ +-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-global q35-pcihost.pci-hole64-size=1024K \ +-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ +-device pci-bridge,chassis_nr=3,id=pci.2,bus=pci.1,addr=0x0 \ +-device pxb-pcie,bus_nr=4,id=pci.3,numa_node=0,bus=pcie.0,addr=0x2 \ +-device pcie-root-port,port=0x5,chassis=5,id=pci.4,bus=pcie.0,addr=0x3 \ +-device x3130-upstream,id=pci.5,bus=pci.4,addr=0x0 \ +-device xio3130-downstream,port=0x7,chassis=7,id=pci.6,bus=pci.5,addr=0x0 diff --git a/tests/qemuxml2argvdata/q35-controllers-pciopts.xml b/tests/qemuxml2argvdata/q35-controllers-pciopts.xml new file mode 100644 index 0000000000..f5b8d1e355 --- /dev/null +++ b/tests/qemuxml2argvdata/q35-controllers-pciopts.xml @@ -0,0 +1,60 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <!-- Only pcihole64 is valid --> + <target busNr='1' chassis='1' chassisNr='1' index='0' port='1'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <!-- No option is valid --> + <target busNr='2' chassis='2' chassisNr='2' index='2' port='2'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <!-- Only chassisNr is valid --> + <target busNr='3' chassis='3' chassisNr='3' index='3' port='3'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='3' model='pcie-expander-bus'> + <!-- Only busNr and numaNode are valid --> + <target busNr='4' chassis='4' chassisNr='4' index='4' port='4'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <!-- Only chassis and port are valid --> + <target busNr='5' chassis='5' chassisNr='5' index='5' port='5'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='5' model='pcie-switch-upstream-port'> + <!-- No option is valid --> + <target busNr='6' chassis='6' chassisNr='6' index='6' port='6'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='6' model='pcie-switch-downstream-port'> + <!-- Only chassis and port are valid --> + <target busNr='7' chassis='7' chassisNr='7' index='7' port='7'> + <node>0</node> + </target> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 688846b9b4..9015eb5fb3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2436,6 +2436,23 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_DEVICE_PXB_PCIE);
+ DO_TEST("i440fx-controllers-pciopts", + QEMU_CAPS_I440FX_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB); + DO_TEST("q35-controllers-pciopts", + QEMU_CAPS_Q35_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB_PCIE, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_X3130_UPSTREAM, + QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM); + DO_TEST("pseries-controllers-pciopts", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, + QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI, QEMU_CAPS_DEVICE_SCSI_GENERIC); diff --git a/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml new file mode 100644 index 0000000000..d171d13705 --- /dev/null +++ b/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml @@ -0,0 +1,45 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </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-x86_64</emulator> + <controller type='pci' index='0' model='pci-root'> + <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='2'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-expander-bus'> + <model name='pxb'/> + <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <controller type='usb' index='0' model='none'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml new file mode 100644 index 0000000000..bbe360e25d --- /dev/null +++ b/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </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='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> + </controller> + <controller type='pci' index='1' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='1'> + <node>0</node> + </target> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml new file mode 100644 index 0000000000..5ef7aa564c --- /dev/null +++ b/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml @@ -0,0 +1,76 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <cpu> + <numa> + <cell id='0' cpus='0' memory='1048576' unit='KiB'/> + </numa> + </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-x86_64</emulator> + <controller type='pci' index='0' model='pcie-root'> + <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> + <pcihole64 unit='KiB'>1024</pcihole64> + </controller> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='2'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-expander-bus'> + <model name='pxb-pcie'/> + <target chassisNr='4' chassis='4' port='0x4' busNr='4' index='4'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassisNr='5' chassis='5' port='0x5' busNr='5' index='5'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='5' model='pcie-switch-upstream-port'> + <model name='x3130-upstream'/> + <target chassisNr='6' chassis='6' port='0x6' busNr='6' index='6'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='6' model='pcie-switch-downstream-port'> + <model name='xio3130-downstream'/> + <target chassisNr='7' chassis='7' port='0x7' busNr='7' index='7'> + <node>0</node> + </target> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + </controller> + <controller type='usb' index='0' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0eb9e6c77a..7b8a160788 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1102,6 +1102,23 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_HDA_DUPLEX);
+ DO_TEST("i440fx-controllers-pciopts", + QEMU_CAPS_I440FX_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB); + DO_TEST("q35-controllers-pciopts", + QEMU_CAPS_Q35_PCI_HOLE64_SIZE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PXB_PCIE, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_X3130_UPSTREAM, + QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM); + DO_TEST("pseries-controllers-pciopts", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, + QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST("hostdev-scsi-vhost-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VHOST_SCSI, QEMU_CAPS_DEVICE_SCSI_GENERIC, QEMU_CAPS_VIRTIO_CCW);

On Fri, 2018-02-23 at 14:18 -0500, Laine Stump wrote:
On 02/21/2018 09:14 AM, Andrea Bolognani wrote:
The input configurations set all existing options for all PCI controllers, even those that are not valid for the controller. As we implement validation for PCI controller options, we expect these test to start failing.
A noble cause, but since multiple options are being tested for multiple controllers in the same file, once you have all the proper checks in place the tests won't actually be verifying all of the negative tests - only the first failure will be noticed - if one of the others is missed, it won't "fail extra hard" or anything.
I'm well aware of that.
Although I hate to explode the number of tests, I think if you want to have proper negative testing for every options that doesn't belong on a particular controller, then you'll need a separate test case for each combination of option and controller model. And since that would make for a *lot* of test cases if we tried to extrapolate to all other options for all other elements, I don't know that it's worth going down that rabbit hole.
So should I just drop this one, or is it still somewhat valuable to have any sort of test suite coverage for PCI controller options? -- Andrea Bolognani / Red Hat / Virtualization

On 02/27/2018 07:17 AM, Andrea Bolognani wrote:
On Fri, 2018-02-23 at 14:18 -0500, Laine Stump wrote:
The input configurations set all existing options for all PCI controllers, even those that are not valid for the controller. As we implement validation for PCI controller options, we expect these test to start failing. A noble cause, but since multiple options are being tested for multiple controllers in the same file, once you have all the proper checks in
On 02/21/2018 09:14 AM, Andrea Bolognani wrote: place the tests won't actually be verifying all of the negative tests - only the first failure will be noticed - if one of the others is missed, it won't "fail extra hard" or anything. I'm well aware of that.
Yeah, I'm just trying to be funny.
Although I hate to explode the number of tests, I think if you want to have proper negative testing for every options that doesn't belong on a particular controller, then you'll need a separate test case for each combination of option and controller model. And since that would make for a *lot* of test cases if we tried to extrapolate to all other options for all other elements, I don't know that it's worth going down that rabbit hole. So should I just drop this one, or is it still somewhat valuable to have any sort of test suite coverage for PCI controller options?
I was thinking that having this test is better than not having this test. But then I thought about what would happen if there was a regression in just a single one of these validations - the negative test would still "succeed" (i.e. "succeed in detecting a failure") because it would hit the next disallowed attribute. As a matter of fact, the test would continue to "succeed" until there was a regression in the validation of every single attribute, so that no error would be triggered. So having a negative test that has multiple examples of failures actually gives us a false sense of security - we believe that it's verifying we're catching incorrect config, but it won't actually notify us until *all* of the bad config is missed by validation. So, I think each negative test should have exactly one piece of incorrect data. That necessarily means that it's only testing for proper validation of a single aspect of a single attribute. But making this generally useful with the current test apparatus would mean a huge explosion in the number of test files, and I don't think that's practical. But if we're only testing for one out of a thousand validations, there's really not much point in it.

On Tue, 2018-02-27 at 09:59 -0500, Laine Stump wrote:
So should I just drop this one, or is it still somewhat valuable to have any sort of test suite coverage for PCI controller options?
I was thinking that having this test is better than not having this test. But then I thought about what would happen if there was a regression in just a single one of these validations - the negative test would still "succeed" (i.e. "succeed in detecting a failure") because it would hit the next disallowed attribute. As a matter of fact, the test would continue to "succeed" until there was a regression in the validation of every single attribute, so that no error would be triggered. So having a negative test that has multiple examples of failures actually gives us a false sense of security - we believe that it's verifying we're catching incorrect config, but it won't actually notify us until *all* of the bad config is missed by validation.
So, I think each negative test should have exactly one piece of incorrect data. That necessarily means that it's only testing for proper validation of a single aspect of a single attribute. But making this generally useful with the current test apparatus would mean a huge explosion in the number of test files, and I don't think that's practical. But if we're only testing for one out of a thousand validations, there's really not much point in it.
Okay, I'll drop it and respin then. -- Andrea Bolognani / Red Hat / Virtualization

On 02/21/2018 09:14 AM, Andrea Bolognani wrote:
The input configurations set all existing options for all PCI controllers, even those that are not valid for the controller. As we implement validation for PCI controller options, we expect these test to start failing.
Oh, and s/test/tests/.

The esisting function is renamed and called from the new one, so that even while we're in the process of implementing new checks all the existing ones will be performed. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- Based on the reviewer's preference, this patch can be pushed on its own or squashed into the next one. src/qemu/qemu_domain.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b1308e5a49..151d33aee3 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4247,9 +4247,9 @@ qemuDomainDeviceDefValidateControllerSCSI(const virDomainControllerDef *controll static int -qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controller, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) +qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *controller, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) { virDomainControllerModelPCI model = controller->model; const virDomainPCIControllerOpts *pciopts; @@ -4526,6 +4526,33 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle } +static int +qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) + +{ + const virDomainPCIControllerOpts *pciopts = &cont->opts.pciopts; + const char *model = virDomainControllerModelPCITypeToString(cont->model); + const char *modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName); + + if (!model) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerModelPCI value: %d"), + cont->model); + return -1; + } + if (!modelName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerPCIModelName value: %d"), + pciopts->modelName); + return -1; + } + + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); +} + + static int qemuDomainDeviceDefValidateControllerSATA(const virDomainControllerDef *controller, const virDomainDef *def, -- 2.14.3

On 02/21/2018 09:14 AM, Andrea Bolognani wrote:
The esisting function is renamed and called from the new one, so that even while we're in the process of implementing new checks all the existing ones will be performed.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- Based on the reviewer's preference, this patch can be pushed on its own or squashed into the next one.
src/qemu/qemu_domain.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b1308e5a49..151d33aee3 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4247,9 +4247,9 @@ qemuDomainDeviceDefValidateControllerSCSI(const virDomainControllerDef *controll
static int -qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controller, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) +qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *controller, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) { virDomainControllerModelPCI model = controller->model; const virDomainPCIControllerOpts *pciopts; @@ -4526,6 +4526,33 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle }
+static int +qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) + +{ + const virDomainPCIControllerOpts *pciopts = &cont->opts.pciopts; + const char *model = virDomainControllerModelPCITypeToString(cont->model); + const char *modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName); + + if (!model) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerModelPCI value: %d"), + cont->model); + return -1; + } + if (!modelName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerPCIModelName value: %d"), + pciopts->modelName); + return -1; + }
(meant to send this before, but kept forgetting...) 1) I thought modelName wasn't set for pci-root. Doesn't the above cause a validation error in that case? (too early in the day, haven't tried it) 2) danpb made a nice new function to standardize/simplify errors of the above type: virReportEnumRangeError().

On Fri, 2018-03-02 at 07:34 -0500, Laine Stump wrote:
On 02/21/2018 09:14 AM, Andrea Bolognani wrote: [...]
+static int +qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) + +{ + const virDomainPCIControllerOpts *pciopts = &cont->opts.pciopts; + const char *model = virDomainControllerModelPCITypeToString(cont->model); + const char *modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName); + + if (!model) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerModelPCI value: %d"), + cont->model); + return -1; + } + if (!modelName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerPCIModelName value: %d"), + pciopts->modelName); + return -1; + }
(meant to send this before, but kept forgetting...)
1) I thought modelName wasn't set for pci-root. Doesn't the above cause a validation error in that case? (too early in the day, haven't tried it)
The default value is _MODEL_NAME_NONE aka zero, which is still part of the enumeration, so virDomainControllerPCIModelNameTypeToString() won't return NULL and no error will be raised. For pSeries guests, it will be set to _MODEL_NAME_SPAPR_PCI_HOST_BRIDGE so once again no problem there.
2) danpb made a nice new function to standardize/simplify errors of the above type: virReportEnumRangeError().
His efforts on switch normalization and me rebasing this series happened pretty much at the same time; more specifically, the function you're talking about was introduced in 3b1020ac805e, while my series is based on the earlier f565321b26df. I guess this means another rebase! Yay! \o/ -- Andrea Bolognani / Red Hat / Virtualization

On 03/02/2018 08:05 AM, Andrea Bolognani wrote:
On 02/21/2018 09:14 AM, Andrea Bolognani wrote: [...]
+static int +qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) + +{ + const virDomainPCIControllerOpts *pciopts = &cont->opts.pciopts; + const char *model = virDomainControllerModelPCITypeToString(cont->model); + const char *modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName); + + if (!model) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerModelPCI value: %d"), + cont->model); + return -1; + } + if (!modelName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown virDomainControllerPCIModelName value: %d"), + pciopts->modelName); + return -1; + } (meant to send this before, but kept forgetting...)
1) I thought modelName wasn't set for pci-root. Doesn't the above cause a validation error in that case? (too early in the day, haven't tried it) The default value is _MODEL_NAME_NONE aka zero, which is still part of the enumeration, so virDomainControllerPCIModelNameTypeToString() won't return NULL and no error will be raised. For pSeries guests, it will be set to _MODEL_NAME_SPAPR_PCI_HOST_BRIDGE so once again no
On Fri, 2018-03-02 at 07:34 -0500, Laine Stump wrote: problem there.
Ah, right. So the name is "none", but when we're formatting for dumpxml we skip it if the value is 0, so that never shows up. "Nevermind" </EmilyLitella>
2) danpb made a nice new function to standardize/simplify errors of the above type: virReportEnumRangeError(). His efforts on switch normalization and me rebasing this series happened pretty much at the same time; more specifically, the function you're talking about was introduced in 3b1020ac805e, while my series is based on the earlier f565321b26df.
Yep, I saw his patches at about the same time as yours, and since you're respinning I thought I'd point it out.
I guess this means another rebase! Yay! \o/
Someday you'll learn to do what I'm doing right now - I want to add some extra validation of pci controller options, but I'm waiting to write any code until you've pushed your patches. :-)

https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 233 +++++++++++++++++++++++++++++++------------------ 1 file changed, 149 insertions(+), 84 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 151d33aee3..5bd879f4bc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4253,7 +4253,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro { virDomainControllerModelPCI model = controller->model; const virDomainPCIControllerOpts *pciopts; - const char *modelName = NULL; /* skip pcie-root */ if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) @@ -4291,24 +4290,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro } pciopts = &controller->opts.pciopts; - if (controller->model != VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT && - controller->model != VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST) { - if (pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("autogenerated %s options not set"), - virDomainControllerModelPCITypeToString(controller->model)); - return -1; - } - - modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName); - if (!modelName) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unknown %s modelName value %d"), - virDomainControllerModelPCITypeToString(controller->model), - pciopts->modelName); - return -1; - } - } /* Second pass - now the model specific checks */ switch (model) { @@ -4319,14 +4300,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro return -1; } - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pci-bridge"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pci-bridge controller is not supported " @@ -4343,14 +4316,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro return -1; } - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pci-expander-bus"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pxb controller is not supported in this " @@ -4361,14 +4326,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a dmi-to-pci-bridge"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the dmi-to-pci-bridge (i82801b11-bridge) " @@ -4385,15 +4342,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro return -1; } - if ((pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420) && - (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pcie-root-port"), - modelName); - return -1; - } - if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420) && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IOH3420)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -4413,14 +4361,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pcie-switch-upstream-port"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_X3130_UPSTREAM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pcie-switch-upstream-port (x3130-upstream) " @@ -4438,14 +4378,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro return -1; } - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pcie-switch-downstream-port"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("The pcie-switch-downstream-port " @@ -4463,14 +4395,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro return -1; } - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pcie-expander-bus"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB_PCIE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pxb-pcie controller is not supported " @@ -4491,14 +4415,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro if (pciopts->targetIndex == 0) return 0; - if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("PCI controller model name '%s' is not valid " - "for a pci-root"), - modelName); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the spapr-pci-host-bridge controller is not " @@ -4549,6 +4465,155 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* modelName */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + 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: + /* modelName should have been set automatically */ + if (pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "modelName", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + /* modelName must be set for pSeries guests, but it's an error + * for it to be set for any other guest */ + if (pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE && + qemuDomainIsPSeries(def)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "modelName", model); + return -1; + } + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE && + !qemuDomainIsPSeries(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "modelName", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "modelName", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + + /* modelName (cont'd) */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE && + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pci-root"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pci-bridge"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "dmi-to-pci-bridge"); + return -1; + } + break; + + 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) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pcie-root-port"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pcie-switch-upstream-port"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pci-switch-downstream-port"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pci-expander-bus"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pcie-expander-bus"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Model name '%s' is not valid for '%s' controller"), + modelName, "pcie-root"); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } -- 2.14.3

https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 70 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 5bd879f4bc..cf70481c41 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4264,31 +4264,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) return 0; - /* First pass - just check the controller index for the model's - * that we care to check... */ - switch (model) { - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: - 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: - if (controller->idx == 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("index for pci controllers of model '%s' must be > 0"), - virDomainControllerModelPCITypeToString(model)); - return -1; - } - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: - break; - } - pciopts = &controller->opts.pciopts; /* Second pass - now the model specific checks */ @@ -4614,6 +4589,51 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* index */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + 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: + if (cont->idx == 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Index for '%s' controllers must be > 0"), + model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + /* pSeries guests can have multiple PHBs, so it's expected that + * the index will not be zero for some of them */ + if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT && + pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE) { + break; + } + + /* For all other pci-root and pcie-root controllers, though, + * the index must be zero*/ + if (cont->idx != 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Index for '%s' controllers must be 0"), + model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } -- 2.14.3

Some test cases that were specifically set up to exploit the lack of checks on PCI controller options start failing with these changes, so they are marked as such. https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 54 +++++++++++++-- .../i440fx-controllers-pciopts.args | 24 ------- .../pseries-controllers-pciopts.args | 22 ------- .../qemuxml2argvdata/q35-controllers-pciopts.args | 28 -------- tests/qemuxml2argvtest.c | 19 +----- .../i440fx-controllers-pciopts.xml | 45 ------------- .../pseries-controllers-pciopts.xml | 43 ------------ .../qemuxml2xmloutdata/q35-controllers-pciopts.xml | 76 ---------------------- tests/qemuxml2xmltest.c | 17 ----- 9 files changed, 51 insertions(+), 277 deletions(-) delete mode 100644 tests/qemuxml2argvdata/i440fx-controllers-pciopts.args delete mode 100644 tests/qemuxml2argvdata/pseries-controllers-pciopts.args delete mode 100644 tests/qemuxml2argvdata/q35-controllers-pciopts.args delete mode 100644 tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml delete mode 100644 tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml delete mode 100644 tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index cf70481c41..f7dfcaa386 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4380,12 +4380,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: - if (pciopts->targetIndex == -1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("autogenerated pci-root options not set")); - return -1; - } - /* Skip the implicit one */ if (pciopts->targetIndex == 0) return 0; @@ -4634,6 +4628,54 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* targetIndex */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + /* PHBs for pSeries guests must have been assigned a targetIndex */ + if (pciopts->targetIndex == -1 && + pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "targetIndex", model); + return -1; + } + + /* targetIndex only applies to PHBs, so for any other pci-root + * controller it being present is an error */ + if (pciopts->targetIndex != -1 && + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "targetIndex", model); + 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: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + 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: + if (pciopts->targetIndex != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "targetIndex", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } diff --git a/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args b/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args deleted file mode 100644 index d85fae5c96..0000000000 --- a/tests/qemuxml2argvdata/i440fx-controllers-pciopts.args +++ /dev/null @@ -1,24 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/home/test \ -USER=test \ -LOGNAME=test \ -QEMU_AUDIO_DRV=none \ -/usr/bin/qemu-system-x86_64 \ --name guest \ --S \ --M pc \ --m 1024 \ --smp 1,sockets=1,cores=1,threads=1 \ --numa node,nodeid=0,cpus=0,mem=1024 \ --uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ --nographic \ --nodefaults \ --chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ -server,nowait \ --mon chardev=charmonitor,id=monitor,mode=readline \ --no-acpi \ --boot c \ --global i440FX-pcihost.pci-hole64-size=1024K \ --device pci-bridge,chassis_nr=2,id=pci.1,bus=pci.0,addr=0x3 \ --device pxb,bus_nr=3,id=pci.2,numa_node=0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/pseries-controllers-pciopts.args b/tests/qemuxml2argvdata/pseries-controllers-pciopts.args deleted file mode 100644 index 5f1edfc833..0000000000 --- a/tests/qemuxml2argvdata/pseries-controllers-pciopts.args +++ /dev/null @@ -1,22 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/home/test \ -USER=test \ -LOGNAME=test \ -QEMU_AUDIO_DRV=none \ -/usr/bin/qemu-system-ppc64 \ --name guest \ --S \ --M pseries \ --m 1024 \ --smp 1,sockets=1,cores=1,threads=1 \ --numa node,nodeid=0,cpus=0,mem=1024 \ --uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ --nographic \ --nodefaults \ --chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ -server,nowait \ --mon chardev=charmonitor,id=monitor,mode=readline \ --boot c \ --device spapr-pci-host-bridge,index=1,id=pci.1,numa_node=0 \ --device pci-bridge,chassis_nr=3,id=pci.2,bus=pci.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/q35-controllers-pciopts.args b/tests/qemuxml2argvdata/q35-controllers-pciopts.args deleted file mode 100644 index 44259f5027..0000000000 --- a/tests/qemuxml2argvdata/q35-controllers-pciopts.args +++ /dev/null @@ -1,28 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/home/test \ -USER=test \ -LOGNAME=test \ -QEMU_AUDIO_DRV=none \ -/usr/bin/qemu-system-x86_64 \ --name guest \ --S \ --M q35 \ --m 1024 \ --smp 1,sockets=1,cores=1,threads=1 \ --numa node,nodeid=0,cpus=0,mem=1024 \ --uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ --nographic \ --nodefaults \ --chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ -server,nowait \ --mon chardev=charmonitor,id=monitor,mode=readline \ --no-acpi \ --boot c \ --global q35-pcihost.pci-hole64-size=1024K \ --device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ --device pci-bridge,chassis_nr=3,id=pci.2,bus=pci.1,addr=0x0 \ --device pxb-pcie,bus_nr=4,id=pci.3,numa_node=0,bus=pcie.0,addr=0x2 \ --device pcie-root-port,port=0x5,chassis=5,id=pci.4,bus=pcie.0,addr=0x3 \ --device x3130-upstream,id=pci.5,bus=pci.4,addr=0x0 \ --device xio3130-downstream,port=0x7,chassis=7,id=pci.6,bus=pci.5,addr=0x0 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 9015eb5fb3..a3942c0043 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2436,22 +2436,9 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_DEVICE_PXB_PCIE); - DO_TEST("i440fx-controllers-pciopts", - QEMU_CAPS_I440FX_PCI_HOLE64_SIZE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, - QEMU_CAPS_DEVICE_PXB); - DO_TEST("q35-controllers-pciopts", - QEMU_CAPS_Q35_PCI_HOLE64_SIZE, - QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, - QEMU_CAPS_DEVICE_PXB_PCIE, - QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, - QEMU_CAPS_DEVICE_X3130_UPSTREAM, - QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM); - DO_TEST("pseries-controllers-pciopts", - QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, - QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, - QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST_PARSE_ERROR("i440fx-controllers-pciopts", NONE); + DO_TEST_PARSE_ERROR("q35-controllers-pciopts", NONE); + DO_TEST_PARSE_ERROR("pseries-controllers-pciopts", NONE); DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI, diff --git a/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml deleted file mode 100644 index d171d13705..0000000000 --- a/tests/qemuxml2xmloutdata/i440fx-controllers-pciopts.xml +++ /dev/null @@ -1,45 +0,0 @@ -<domain type='qemu'> - <name>guest</name> - <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> - <memory unit='KiB'>1048576</memory> - <currentMemory unit='KiB'>1048576</currentMemory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='x86_64' machine='pc'>hvm</type> - <boot dev='hd'/> - </os> - <cpu> - <numa> - <cell id='0' cpus='0' memory='1048576' unit='KiB'/> - </numa> - </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-x86_64</emulator> - <controller type='pci' index='0' model='pci-root'> - <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> - <pcihole64 unit='KiB'>1024</pcihole64> - </controller> - <controller type='pci' index='1' model='pci-bridge'> - <model name='pci-bridge'/> - <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='2'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> - </controller> - <controller type='pci' index='2' model='pci-expander-bus'> - <model name='pxb'/> - <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> - </controller> - <controller type='usb' index='0' model='none'/> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml deleted file mode 100644 index bbe360e25d..0000000000 --- a/tests/qemuxml2xmloutdata/pseries-controllers-pciopts.xml +++ /dev/null @@ -1,43 +0,0 @@ -<domain type='qemu'> - <name>guest</name> - <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> - <memory unit='KiB'>1048576</memory> - <currentMemory unit='KiB'>1048576</currentMemory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='ppc64' machine='pseries'>hvm</type> - <boot dev='hd'/> - </os> - <cpu> - <numa> - <cell id='0' cpus='0' memory='1048576' unit='KiB'/> - </numa> - </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='pci-root'> - <model name='spapr-pci-host-bridge'/> - <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> - </controller> - <controller type='pci' index='1' model='pci-root'> - <model name='spapr-pci-host-bridge'/> - <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='1'> - <node>0</node> - </target> - </controller> - <controller type='pci' index='2' model='pci-bridge'> - <model name='pci-bridge'/> - <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> - </controller> - <controller type='usb' index='0' model='none'/> - <memballoon model='none'/> - <panic model='pseries'/> - </devices> -</domain> diff --git a/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml b/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml deleted file mode 100644 index 5ef7aa564c..0000000000 --- a/tests/qemuxml2xmloutdata/q35-controllers-pciopts.xml +++ /dev/null @@ -1,76 +0,0 @@ -<domain type='qemu'> - <name>guest</name> - <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid> - <memory unit='KiB'>1048576</memory> - <currentMemory unit='KiB'>1048576</currentMemory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='x86_64' machine='q35'>hvm</type> - <boot dev='hd'/> - </os> - <cpu> - <numa> - <cell id='0' cpus='0' memory='1048576' unit='KiB'/> - </numa> - </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-x86_64</emulator> - <controller type='pci' index='0' model='pcie-root'> - <target chassisNr='1' chassis='1' port='0x1' busNr='1' index='0'/> - <pcihole64 unit='KiB'>1024</pcihole64> - </controller> - <controller type='pci' index='1' model='dmi-to-pci-bridge'> - <model name='i82801b11-bridge'/> - <target chassisNr='2' chassis='2' port='0x2' busNr='2' index='2'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> - </controller> - <controller type='pci' index='2' model='pci-bridge'> - <model name='pci-bridge'/> - <target chassisNr='3' chassis='3' port='0x3' busNr='3' index='3'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> - </controller> - <controller type='pci' index='3' model='pcie-expander-bus'> - <model name='pxb-pcie'/> - <target chassisNr='4' chassis='4' port='0x4' busNr='4' index='4'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> - </controller> - <controller type='pci' index='4' model='pcie-root-port'> - <model name='pcie-root-port'/> - <target chassisNr='5' chassis='5' port='0x5' busNr='5' index='5'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> - </controller> - <controller type='pci' index='5' model='pcie-switch-upstream-port'> - <model name='x3130-upstream'/> - <target chassisNr='6' chassis='6' port='0x6' busNr='6' index='6'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> - </controller> - <controller type='pci' index='6' model='pcie-switch-downstream-port'> - <model name='xio3130-downstream'/> - <target chassisNr='7' chassis='7' port='0x7' busNr='7' index='7'> - <node>0</node> - </target> - <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> - </controller> - <controller type='usb' index='0' model='none'/> - <controller type='sata' index='0'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> - </controller> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 7b8a160788..0eb9e6c77a 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1102,23 +1102,6 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_HDA_DUPLEX); - DO_TEST("i440fx-controllers-pciopts", - QEMU_CAPS_I440FX_PCI_HOLE64_SIZE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, - QEMU_CAPS_DEVICE_PXB); - DO_TEST("q35-controllers-pciopts", - QEMU_CAPS_Q35_PCI_HOLE64_SIZE, - QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, - QEMU_CAPS_DEVICE_PXB_PCIE, - QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, - QEMU_CAPS_DEVICE_X3130_UPSTREAM, - QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM); - DO_TEST("pseries-controllers-pciopts", - QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, - QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, - QEMU_CAPS_DEVICE_PCI_BRIDGE); - DO_TEST("hostdev-scsi-vhost-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VHOST_SCSI, QEMU_CAPS_DEVICE_SCSI_GENERIC, QEMU_CAPS_VIRTIO_CCW); -- 2.14.3

https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f7dfcaa386..34ab40b1ed 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4676,6 +4676,48 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* pcihole64 */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + /* The pcihole64 option only applies to x86 guests */ + if ((pciopts->pcihole64 || + pciopts->pcihole64size != 0) && + !ARCH_IS_X86(def->os.arch)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller " + "on '%s' architecture or '%s' machine type"), + "pcihole64", model, + virArchToString(def->os.arch), def->os.machine); + 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: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + 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: + if (pciopts->pcihole64 || + pciopts->pcihole64size != 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "pcihole64", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } -- 2.14.3

This change catches an invalid use of the option in our test suite. https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 48 +++++++++++++++++++------- tests/qemuxml2argvdata/pcie-expander-bus.xml | 2 +- tests/qemuxml2xmloutdata/pcie-expander-bus.xml | 2 +- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 34ab40b1ed..52a556ec99 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4285,12 +4285,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: - if (pciopts->busNr == -1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("autogenerated pci-expander-bus options not set")); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pxb controller is not supported in this " @@ -4364,12 +4358,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: - if (pciopts->busNr == -1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("autogenerated pcie-expander-bus options not set")); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB_PCIE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pxb-pcie controller is not supported " @@ -4718,6 +4706,42 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* busNr */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + if (pciopts->busNr == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "busNr", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (pciopts->busNr != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "busNr", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } diff --git a/tests/qemuxml2argvdata/pcie-expander-bus.xml b/tests/qemuxml2argvdata/pcie-expander-bus.xml index ac01c26ccf..237430a1e5 100644 --- a/tests/qemuxml2argvdata/pcie-expander-bus.xml +++ b/tests/qemuxml2argvdata/pcie-expander-bus.xml @@ -35,7 +35,7 @@ <address type='pci' bus='0x00' slot='4'/> </controller> <controller type='pci' index='2' model='pcie-root-port'> - <target busNr='220'> + <target> <node>1</node> </target> <address type='pci' bus='0x01'/> diff --git a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml index aaac423cac..d5e741b80d 100644 --- a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml +++ b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml @@ -36,7 +36,7 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x0' busNr='220'> + <target chassis='2' port='0x0'> <node>1</node> </target> <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> -- 2.14.3

This change catches an invalid use of the option in our test suite. https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 54 ++++++++++++++++++++++++++ tests/qemuxml2argvdata/pcie-expander-bus.xml | 3 -- tests/qemuxml2xmloutdata/pcie-expander-bus.xml | 4 +- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 52a556ec99..d5ec9302f6 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4742,6 +4742,60 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* numaNode */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + /* numaNode can be used for these controllers, but it's not set + * automatically so it can be missing */ + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + /* Only PHBs support numaNode */ + if (pciopts->numaNode != -1 && + pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "numaNode", model); + return -1; + } + + /* However, the default PHB doesn't support numaNode */ + if (pciopts->numaNode != -1 && + pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE && + pciopts->targetIndex == 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller " + "with '%s' equal to 0"), + "numaNode", model, + "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: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (pciopts->numaNode != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "numaNode", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } diff --git a/tests/qemuxml2argvdata/pcie-expander-bus.xml b/tests/qemuxml2argvdata/pcie-expander-bus.xml index 237430a1e5..5c5d34d1e0 100644 --- a/tests/qemuxml2argvdata/pcie-expander-bus.xml +++ b/tests/qemuxml2argvdata/pcie-expander-bus.xml @@ -35,9 +35,6 @@ <address type='pci' bus='0x00' slot='4'/> </controller> <controller type='pci' index='2' model='pcie-root-port'> - <target> - <node>1</node> - </target> <address type='pci' bus='0x01'/> </controller> <controller type='pci' index='3' model='pcie-switch-upstream-port'> diff --git a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml index d5e741b80d..b6498fd2eb 100644 --- a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml +++ b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml @@ -36,9 +36,7 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x0'> - <node>1</node> - </target> + <target chassis='2' port='0x0'/> <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </controller> <controller type='pci' index='3' model='pcie-switch-upstream-port'> -- 2.14.3

https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d5ec9302f6..0ce70c16c7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4269,12 +4269,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro /* Second pass - now the model specific checks */ switch (model) { case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - if (pciopts->chassisNr == -1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("autogenerated pci-bridge options not set")); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("the pci-bridge controller is not supported " @@ -4796,6 +4790,42 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* chassisNr */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + if (pciopts->chassisNr == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "chassisNr", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + 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: + if (pciopts->chassisNr != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "chassisNr", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } -- 2.14.3

https://bugzilla.redhat.com/show_bug.cgi?id=1483816 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 61 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0ce70c16c7..ed41c90c2d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4299,12 +4299,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - if (pciopts->chassis == -1 || pciopts->port == -1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("autogenerated pcie-root-port options not set")); - return -1; - } - if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420) && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IOH3420)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -4334,13 +4328,6 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: - if (pciopts->chassis == -1 || pciopts->port == -1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("autogenerated pcie-switch-downstream-port " - "options not set")); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("The pcie-switch-downstream-port " @@ -4826,6 +4813,54 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* chassis and port */ + switch ((virDomainControllerModelPCI) cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: + if (pciopts->chassis == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "chassis", model); + return -1; + } + if (pciopts->port == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Option '%s' not set for '%s' controller"), + "port", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + if (pciopts->chassis != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "chassis", model); + return -1; + } + if (pciopts->port != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not valid for '%s' controller"), + "port", model); + return -1; + } + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid '%s' value '%d'"), + "virDomainControllerModelPCI", cont->model); + return -1; + } + return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } -- 2.14.3

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 190 ++++++++++++++++++++----------------------------- 1 file changed, 77 insertions(+), 113 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ed41c90c2d..3bd80e7886 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4249,11 +4249,8 @@ qemuDomainDeviceDefValidateControllerSCSI(const virDomainControllerDef *controll static int qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *controller, const virDomainDef *def, - virQEMUCapsPtr qemuCaps) + virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED) { - virDomainControllerModelPCI model = controller->model; - const virDomainPCIControllerOpts *pciopts; - /* skip pcie-root */ if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) return 0; @@ -4264,119 +4261,50 @@ qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *contro controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) return 0; - pciopts = &controller->opts.pciopts; - - /* Second pass - now the model specific checks */ - switch (model) { - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the pci-bridge controller is not supported " - "in this QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the pxb controller is not supported in this " - "QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the dmi-to-pci-bridge (i82801b11-bridge) " - "controller is not supported in this QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420) && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IOH3420)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the pcie-root-port (ioh3420) controller " - "is not supported in this QEMU binary")); - return -1; - } - - if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT) && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCIE_ROOT_PORT)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the pcie-root-port (pcie-root-port) controller " - "is not supported in this QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_X3130_UPSTREAM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the pcie-switch-upstream-port (x3130-upstream) " - "controller is not supported in this QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("The pcie-switch-downstream-port " - "(xio3130-downstream) controller is not " - "supported in this QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB_PCIE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the pxb-pcie controller is not supported " - "in this QEMU binary")); - return -1; - } - - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: - /* Skip the implicit one */ - if (pciopts->targetIndex == 0) - return 0; - - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the spapr-pci-host-bridge controller is not " - "supported in this QEMU binary")); - return -1; - } - - if (pciopts->numaNode != -1 && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the spapr-pci-host-bridge controller doesn't " - "support numa_node in this QEMU binary")); - return -1; - } + return 0; +} - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: - break; +/** + * virDomainControllerPCIModelNameToQEMUCaps: + * @modelName: model name + * + * Maps model names for PCI controllers (virDomainControllerPCIModelName) + * to the QEMU capabilities required to use them (virQEMUCapsFlags). + * + * Returns: the QEMU capability itself (>0) on success; 0 if no QEMU + * capability is needed; <0 on error. + */ +static int +virDomainControllerPCIModelNameToQEMUCaps(int modelName) +{ + switch ((virDomainControllerPCIModelName) modelName) { + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE: + return QEMU_CAPS_DEVICE_PCI_BRIDGE; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE: + return QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420: + return QEMU_CAPS_DEVICE_IOH3420; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM: + return QEMU_CAPS_DEVICE_X3130_UPSTREAM; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM: + return QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB: + return QEMU_CAPS_DEVICE_PXB; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE: + return QEMU_CAPS_DEVICE_PXB_PCIE; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT: + return QEMU_CAPS_DEVICE_PCIE_ROOT_PORT; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE: + return QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE: + return 0; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST: + default: + return 1; } - return 0; + return -1; } @@ -4389,6 +4317,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, const virDomainPCIControllerOpts *pciopts = &cont->opts.pciopts; const char *model = virDomainControllerModelPCITypeToString(cont->model); const char *modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName); + int cap = virDomainControllerPCIModelNameToQEMUCaps(pciopts->modelName); if (!model) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -4861,6 +4790,41 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, return -1; } + /* The default PHB for pSeries guests doesn't need any QEMU capability + * to be used, so we should skip the capabilities check altogether */ + if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT && + pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE && + pciopts->targetIndex == 0) { + goto done; + } + + /* QEMU device availability */ + if (cap < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown QEMU device for '%s' controller"), + modelName); + return -1; + } + if (cap > 0 && !virQEMUCapsGet(qemuCaps, cap)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The '%s' device is not supported by this QEMU binary"), + modelName); + return -1; + } + + /* PHBs didn't support numaNode from the very beginning, so an extra + * capability check is required */ + if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT && + pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE && + pciopts->numaNode != -1 && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Option '%s' is not supported by '%s' device with this QEMU binary"), + "numaNode", modelName); + return -1; + } + + done: return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); } -- 2.14.3

We've implemented all existing checks, and more, in the new function, so we can finally drop the old one. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- Based on the reviewer's preference, this patch can be pushed on its own or squashed into the previous one. src/qemu/qemu_domain.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3bd80e7886..89bf166aae 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4246,25 +4246,6 @@ qemuDomainDeviceDefValidateControllerSCSI(const virDomainControllerDef *controll } -static int -qemuDomainDeviceDefValidateControllerPCIOld(const virDomainControllerDef *controller, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED) -{ - /* skip pcie-root */ - if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) - return 0; - - /* Skip pci-root, except for pSeries guests (which actually - * support more than one PCI Host Bridge per guest) */ - if (!qemuDomainIsPSeries(def) && - controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) - return 0; - - return 0; -} - - /** * virDomainControllerPCIModelNameToQEMUCaps: * @modelName: model name @@ -4825,7 +4806,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, } done: - return qemuDomainDeviceDefValidateControllerPCIOld(cont, def, qemuCaps); + return 0; } -- 2.14.3
participants (2)
-
Andrea Bolognani
-
Laine Stump