aboutsummaryrefslogtreecommitdiff
path: root/hw/pci/pci.c
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki@daynix.com>2025-01-16 18:00:59 +0900
committerMichael S. Tsirkin <mst@redhat.com>2025-02-20 18:23:19 -0500
commitcab1398a60eb0cb2d2d1998c9b46aaa5e0bf3ee8 (patch)
treec826783719b4f760bf5e40868c6c7672df85c380 /hw/pci/pci.c
parent3391d68e906114c364c173c7f3f7389d47d15a11 (diff)
downloadqemu-cab1398a60eb0cb2d2d1998c9b46aaa5e0bf3ee8.zip
qemu-cab1398a60eb0cb2d2d1998c9b46aaa5e0bf3ee8.tar.gz
qemu-cab1398a60eb0cb2d2d1998c9b46aaa5e0bf3ee8.tar.bz2
pcie_sriov: Reuse SR-IOV VF device instances
Disable SR-IOV VF devices by reusing code to power down PCI devices instead of removing them when the guest requests to disable VFs. This allows to realize devices and report VF realization errors at PF realization time. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Message-Id: <20250116-reuse-v20-8-7cb370606368@daynix.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci/pci.c')
-rw-r--r--hw/pci/pci.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2afa423..3e29b30 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2963,7 +2963,17 @@ MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
void pci_set_power(PCIDevice *d, bool state)
{
- pci_set_enabled(d, state);
+ /*
+ * Don't change the enabled state of VFs when powering on/off the device.
+ *
+ * When powering on, VFs must not be enabled immediately but they must
+ * wait until the guest configures SR-IOV.
+ * When powering off, their corresponding PFs will be reset and disable
+ * VFs.
+ */
+ if (!pci_is_vf(d)) {
+ pci_set_enabled(d, state);
+ }
}
void pci_set_enabled(PCIDevice *d, bool state)
@@ -2977,7 +2987,7 @@ void pci_set_enabled(PCIDevice *d, bool state)
memory_region_set_enabled(&d->bus_master_enable_region,
(pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER) && d->enabled);
- if (!d->enabled) {
+ if (qdev_is_realized(&d->qdev)) {
pci_device_reset(d);
}
}