From: Stefan Hajnoczi <[email protected]>
Commit 3f9cfaa92c96 ("virtio-pci: Implement SR-IOV PF") added an
unconditional call from virtio_pci_exit() to pcie_sriov_pf_exit().
pcie_sriov_pf_exit() reads from the SR-IOV Capability in Configuration
Space:
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
...
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This results in undefined behavior when dev->exp.sriov_cap is 0 because
this is not an SR-IOV device. For example, unparent_vfs() segfaults when
total_vfs happens to be non-zero.
Fix this by returning early from pcie_sriov_pf_exit() when
dev->exp.sriov_cap is 0 because this is not an SR-IOV device.
Cc: Akihiko Odaki <[email protected]>
Cc: Michael S. Tsirkin <[email protected]>
Reported-by: Qing Wang <[email protected]>
Buglink: https://issues.redhat.com/browse/RHEL-116443
Signed-off-by: Stefan Hajnoczi <[email protected]>
Reviewed-by: Akihiko Odaki <[email protected]>
Fixes: cab1398a60eb ("pcie_sriov: Reuse SR-IOV VF device instances")
Reviewed-by: Michael S. Tsirkin <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
(cherry picked from commit bab681f752048c3bc22d561b1d314c7ec16419c9)
(Mjt: backport to before v10.0.0-819-g19e55471d4e8
"pcie_sriov: Allow user to create SR-IOV device")
Signed-off-by: Michael Tokarev <[email protected]>
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index dd4fbaea46..6281bd61d9 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -112,6 +112,9 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
void pcie_sriov_pf_exit(PCIDevice *dev)
{
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
+ if (dev->exp.sriov_cap == 0) {
+ return;
+ }
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
}
--
2.47.3