mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
pcie_sriov: make pcie_sriov_pf_exit() safe on non-SR-IOV devices
Commit3f9cfaa92c("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 <odaki@rsg.ci.i.u-tokyo.ac.jp> Cc: Michael S. Tsirkin <mst@redhat.com> Reported-by: Qing Wang <qinwang@redhat.com> Buglink: https://issues.redhat.com/browse/RHEL-116443 Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Fixes:cab1398a60("pcie_sriov: Reuse SR-IOV VF device instances") Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20250924155153.579495-1-stefanha@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
acaa3be3f7
commit
bab681f752
+5
-1
@@ -195,7 +195,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;
|
||||
}
|
||||
|
||||
if (dev->exp.sriov_pf.vf_user_created) {
|
||||
uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
|
||||
@@ -211,6 +213,8 @@ void pcie_sriov_pf_exit(PCIDevice *dev)
|
||||
pci_config_set_device_id(dev->exp.sriov_pf.vf[i]->config, vf_dev_id);
|
||||
}
|
||||
} else {
|
||||
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
|
||||
|
||||
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user