]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Prevent use of PCI devices when PCI is not supported
authorAndrea Bolognani <abologna@redhat.com>
Wed, 9 Jul 2025 15:57:24 +0000 (17:57 +0200)
committerAndrea Bolognani <abologna@redhat.com>
Mon, 6 Oct 2025 09:15:41 +0000 (11:15 +0200)
At the moment, we check whether the machine type supports PCI
before attempting to allocate PCI addresses, and if it does
not, we simply skip the step entirely.

This means that an attempt to use a PCI device with a machine
type that has no PCI support won't be rejected by libvirt, and
only once the QEMU process is started the problem will be made
apparent.

Validate things ahead of time instead, rejecting any such
configurations.

Note that we only do this for new domains, because otherwise
existing domains that are configured incorrectly would disappear
and we generally try really hard to avoid that.

A few tests start failing after this change, demonstrating that
things are now working as desired.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_domain_address.c
tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.aarch64-latest.args [deleted file]
tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.aarch64-latest.xml [deleted file]
tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.xml [deleted symlink]
tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.abi-update.err [new file with mode: 0644]
tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.args [deleted file]
tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.err [new file with mode: 0644]
tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.aarch64-latest.err [deleted file]
tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.aarch64-latest.xml [deleted file]
tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.xml [deleted symlink]
tests/qemuxmlconftest.c

index ebf6a38fdeb61bb0ac8d4c3f4b481c4001a7ce34..774541ca063195f1f8636797bf56e1c167633d10 100644 (file)
@@ -2672,7 +2672,8 @@ static int
 qemuDomainAssignPCIAddresses(virDomainDef *def,
                              virQEMUCaps *qemuCaps,
                              virQEMUDriver *driver,
-                             virDomainObj *obj)
+                             virDomainObj *obj,
+                             bool newDomain)
 {
     int ret = -1;
     virDomainPCIAddressSet *addrs = NULL;
@@ -2840,10 +2841,17 @@ qemuDomainAssignPCIAddresses(virDomainDef *def,
         g_clear_pointer(&addrs, virDomainPCIAddressSetFree);
     }
 
-    if (!(addrs = qemuDomainPCIAddressSetCreate(def, qemuCaps, nbuses, false)))
-        goto cleanup;
+    /* We're done collecting available information, now we're going
+     * to allocate PCI addresses for real. We normally skip this part
+     * for machine type that don't support PCI, but we run it for new
+     * domains to catch situation in which the user is incorrectly
+     * asking for PCI devices to be used. If that's the case, an
+     * error will naturally be raised when attempting to allocate a
+     * PCI address since no PCI buses exist */
+    if (qemuDomainSupportsPCI(def) || newDomain) {
+        if (!(addrs = qemuDomainPCIAddressSetCreate(def, qemuCaps, nbuses, false)))
+            goto cleanup;
 
-    if (qemuDomainSupportsPCI(def)) {
         if (qemuDomainValidateDevicePCISlotsChipsets(def, addrs) < 0)
             goto cleanup;
 
@@ -3287,7 +3295,7 @@ qemuDomainAssignAddresses(virDomainDef *def,
 
     qemuDomainAssignVirtioMMIOAddresses(def, qemuCaps);
 
-    if (qemuDomainAssignPCIAddresses(def, qemuCaps, driver, obj) < 0)
+    if (qemuDomainAssignPCIAddresses(def, qemuCaps, driver, obj, newDomain) < 0)
         return -1;
 
     if (qemuDomainAssignUSBAddresses(def, obj, newDomain) < 0)
diff --git a/tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.aarch64-latest.args b/tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.aarch64-latest.args
deleted file mode 100644 (file)
index 0fb2909..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-LC_ALL=C \
-PATH=/bin \
-HOME=/var/lib/libvirt/qemu/domain--1-aarch64test \
-USER=test \
-LOGNAME=test \
-XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-aarch64test/.local/share \
-XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-aarch64test/.cache \
-XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-aarch64test/.config \
-/usr/bin/qemu-system-aarch64 \
--name guest=aarch64test,debug-threads=on \
--S \
--object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-aarch64test/master-key.aes"}' \
--machine collie,usb=off,dump-guest-core=off,memory-backend=strongarm.sdram \
--accel kvm \
--cpu host \
--m size=1048576k \
--object '{"qom-type":"memory-backend-ram","id":"strongarm.sdram","size":1073741824}' \
--overcommit mem-lock=off \
--smp 1,sockets=1,cores=1,threads=1 \
--uuid 6ba410c5-1e5c-4d57-bee7-2228e7ffa32f \
--display none \
--no-user-config \
--nodefaults \
--chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
--mon chardev=charmonitor,id=monitor,mode=control \
--rtc base=utc \
--no-shutdown \
--boot strict=on \
--device '{"driver":"qemu-xhci","id":"usb"}' \
--audiodev '{"id":"audio1","driver":"none"}' \
--sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--msg timestamp=on
diff --git a/tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.aarch64-latest.xml b/tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.aarch64-latest.xml
deleted file mode 100644 (file)
index fa258c5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<domain type='kvm'>
-  <name>aarch64test</name>
-  <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
-  <memory unit='KiB'>1048576</memory>
-  <currentMemory unit='KiB'>1048576</currentMemory>
-  <vcpu placement='static'>1</vcpu>
-  <os>
-    <type arch='aarch64' machine='collie'>hvm</type>
-    <boot dev='hd'/>
-  </os>
-  <cpu mode='host-passthrough' check='none'/>
-  <clock offset='utc'/>
-  <on_poweroff>destroy</on_poweroff>
-  <on_reboot>restart</on_reboot>
-  <on_crash>destroy</on_crash>
-  <devices>
-    <emulator>/usr/bin/qemu-system-aarch64</emulator>
-    <controller type='usb' index='0' model='qemu-xhci'/>
-    <audio id='1' type='none'/>
-    <memballoon model='none'/>
-  </devices>
-</domain>
diff --git a/tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.xml b/tests/qemuxmlconfdata/usb-controller-default-fallback-nousb.xml
deleted file mode 120000 (symlink)
index 9cba7c3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-usb-controller-default-nousb.xml
\ No newline at end of file
diff --git a/tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.abi-update.err b/tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.abi-update.err
new file mode 100644 (file)
index 0000000..a0ca4fb
--- /dev/null
@@ -0,0 +1 @@
+XML error: No PCI buses available
diff --git a/tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.args b/tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.args
deleted file mode 100644 (file)
index 0fb2909..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-LC_ALL=C \
-PATH=/bin \
-HOME=/var/lib/libvirt/qemu/domain--1-aarch64test \
-USER=test \
-LOGNAME=test \
-XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-aarch64test/.local/share \
-XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-aarch64test/.cache \
-XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-aarch64test/.config \
-/usr/bin/qemu-system-aarch64 \
--name guest=aarch64test,debug-threads=on \
--S \
--object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-aarch64test/master-key.aes"}' \
--machine collie,usb=off,dump-guest-core=off,memory-backend=strongarm.sdram \
--accel kvm \
--cpu host \
--m size=1048576k \
--object '{"qom-type":"memory-backend-ram","id":"strongarm.sdram","size":1073741824}' \
--overcommit mem-lock=off \
--smp 1,sockets=1,cores=1,threads=1 \
--uuid 6ba410c5-1e5c-4d57-bee7-2228e7ffa32f \
--display none \
--no-user-config \
--nodefaults \
--chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
--mon chardev=charmonitor,id=monitor,mode=control \
--rtc base=utc \
--no-shutdown \
--boot strict=on \
--device '{"driver":"qemu-xhci","id":"usb"}' \
--audiodev '{"id":"audio1","driver":"none"}' \
--sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--msg timestamp=on
diff --git a/tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.err b/tests/qemuxmlconfdata/usb-controller-default-nousb.aarch64-latest.err
new file mode 100644 (file)
index 0000000..a0ca4fb
--- /dev/null
@@ -0,0 +1 @@
+XML error: No PCI buses available
diff --git a/tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.aarch64-latest.err b/tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.aarch64-latest.err
deleted file mode 100644 (file)
index cac4e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-internal error: Unable to determine model for USB controller idx=0
diff --git a/tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.aarch64-latest.xml b/tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.aarch64-latest.xml
deleted file mode 100644 (file)
index ac5f270..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<domain type='kvm'>
-  <name>aarch64test</name>
-  <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
-  <memory unit='KiB'>1048576</memory>
-  <currentMemory unit='KiB'>1048576</currentMemory>
-  <vcpu placement='static'>1</vcpu>
-  <os>
-    <type arch='aarch64' machine='collie'>hvm</type>
-    <boot dev='hd'/>
-  </os>
-  <cpu mode='host-passthrough' check='none'/>
-  <clock offset='utc'/>
-  <on_poweroff>destroy</on_poweroff>
-  <on_reboot>restart</on_reboot>
-  <on_crash>destroy</on_crash>
-  <devices>
-    <emulator>/usr/bin/qemu-system-aarch64</emulator>
-    <controller type='usb' index='0'/>
-    <audio id='1' type='none'/>
-    <memballoon model='none'/>
-  </devices>
-</domain>
diff --git a/tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.xml b/tests/qemuxmlconfdata/usb-controller-default-unavailable-nousb.xml
deleted file mode 120000 (symlink)
index 9cba7c3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-usb-controller-default-nousb.xml
\ No newline at end of file
index c135faf33cb5d1e21aabdfbc6742b6eef969d9b8..1ec20805c5ef520402d186576c9446f9179c36e7 100644 (file)
@@ -2229,18 +2229,8 @@ mymain(void)
                  ARG_END);
 
     /* The '-nousb' test case tests machine without a built-in USB controller */
-    DO_TEST_CAPS_ARCH_LATEST("usb-controller-default-nousb", "aarch64");
-    DO_TEST_FULL("usb-controller-default-fallback-nousb", ".aarch64-latest",
-                 ARG_CAPS_ARCH, "aarch64",
-                 ARG_CAPS_VER, "latest",
-                 ARG_QEMU_CAPS_DEL, QEMU_CAPS_PIIX3_USB_UHCI, QEMU_CAPS_LAST,
-                 ARG_END);
-    DO_TEST_FULL("usb-controller-default-unavailable-nousb", ".aarch64-latest",
-                 ARG_CAPS_ARCH, "aarch64",
-                 ARG_CAPS_VER, "latest",
-                 ARG_FLAGS, FLAG_EXPECT_FAILURE,
-                 ARG_QEMU_CAPS_DEL, QEMU_CAPS_DEVICE_QEMU_XHCI, QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_PIIX3_USB_UHCI, QEMU_CAPS_PCI_OHCI, QEMU_CAPS_LAST,
-                 ARG_END);
+    DO_TEST_CAPS_ARCH_LATEST_FAILURE("usb-controller-default-nousb", "aarch64");
+    DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE_PARSE_ERROR("usb-controller-default-nousb", "aarch64");
 
     DO_TEST_FULL("usb-controller-default-fallback-g3beige", ".ppc64-latest",
                  ARG_CAPS_ARCH, "ppc64",