You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qemu/hw/pci
Peter Maydell ef44cc0a76 hw/pci: Make msix_init take a uint32_t for nentries
msix_init() and msix_init_exclusive_bar() take an "unsigned short"
argument for the number of MSI-X vectors to try to use.  This is big
enough for the maximum permitted number of vectors, which is 2048.
Unfortunately, we have several devices (most notably virtio) which
allow the user to specify the desired number of vectors, and which
use uint32_t properties for this.  If the user sets the property to a
value that is too big for a uint16_t, the value will be truncated
when it is passed to msix_init(), and msix_init() may then return
success if the truncated value is a valid one.

The resulting mismatch between the number of vectors the msix code
thinks the device has and the number of vectors the device itself
thinks it has can cause assertions, such as the one in issue 2631,
where "-device virtio-mouse-pci,vectors=19923041" is interpreted by
msix as "97 vectors" and by the virtio-pci layer as "19923041
vectors"; a guest attempt to access vector 97 thus passes the
virtio-pci bounds checking and hits an essertion in
msix_vector_use().

Avoid this by making msix_init() and its wrapper function
msix_init_exclusive_bar() take the number of vectors as a uint32_t.
The erroneous command line will now produce the warning

 qemu-system-i386: -device virtio-mouse-pci,vectors=19923041:
   warning: unable to init msix vectors to 19923041

and proceed without crashing.  (The virtio device warns and falls
back to not using MSIX, rather than complaining that the option is
not a valid value this is the same as the existing behaviour for
values that are beyond the MSI-X maximum possible value but fit into
a 16-bit integer, like 2049.)

To ensure this doesn't result in potential overflows in calculation
of the BAR size in msix_init_exclusive_bar(), we duplicate the
nentries error-check from msix_init() at the top of
msix_init_exclusive_bar(), so we know nentries is sane before we
start using it.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2631
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251107131044.1321637-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
1 week ago
..
Kconfig kconfig: Add PCIe devices to s390x machines 2 years ago
meson.build meson: remove CONFIG_ALL 2 years ago
msi.c include: Rename sysemu/ -> system/ 12 months ago
msix.c hw/pci: Make msix_init take a uint32_t for nentries 1 week ago
pci-hmp-cmds.c qapi: Move include/qapi/qmp/ to include/qobject/ 10 months ago
pci-internal.h hw/pci/aer: Make PCIE AER error injection facility available for other emulation to use. 3 years ago
pci-qmp-cmds.c pci: Move QMP commands to new hw/pci/pci-qmp-cmds.c 3 years ago
pci-stub.c hw/pci: remove return after g_assert_not_reached() 1 year ago
pci.c migration: Fix regression of passing error_fatal into vmstate_load_state() 1 month ago
pci_bridge.c qom: Make InterfaceInfo[] uses const 7 months ago
pci_host.c hw/pci-host: Remove unused pci_host_data_be_ops 7 months ago
pcie.c pcie: Add a way to get the outstanding page request allocation (pri) from the config space. 2 months ago
pcie_aer.c hw/pci: Constify VMState 2 years ago
pcie_doe.c hw/pci: PCIe Data Object Exchange emulation 3 years ago
pcie_host.c include/hw/pci: Split pci_device.h off pci.h 3 years ago
pcie_port.c hw/pci/pcie_port: Fix pcie_slot_is_hotpluggbale_bus typo 7 months ago
pcie_sriov.c pcie_sriov: make pcie_sriov_pf_exit() safe on non-SR-IOV devices 2 months ago
shpc.c hw/pci: add some convenient trace-events for pcie and shpc hotplug 2 years ago
slotid_cap.c include/hw/pci: Split pci_device.h off pci.h 3 years ago
trace-events hw/pci/pci.c: Turn DPRINTF into trace events 7 months ago
trace.h trace: switch position of headers to what Meson requires 5 years ago