aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2025-02-25 14:52:25 -0700
committerCédric Le Goater <clg@redhat.com>2025-03-06 06:47:33 +0100
commit9461afd2008b0820fc45a6a7bc675df1b6791e4f (patch)
tree6b6d38ed8b7bedb93c084de1b5f9fa3f92a32f72 /include
parent3f8f6ef701ac6b3691b6003025005a970b2075de (diff)
downloadqemu-9461afd2008b0820fc45a6a7bc675df1b6791e4f.zip
qemu-9461afd2008b0820fc45a6a7bc675df1b6791e4f.tar.gz
qemu-9461afd2008b0820fc45a6a7bc675df1b6791e4f.tar.bz2
hw/pci: Basic support for PCI power management
The memory and IO BARs for devices are only accessible in the D0 power state. In other power states the PCI spec defines that the device responds to TLPs and messages with an Unsupported Request response. To approximate this behavior, consider the BARs as unmapped when the device is not in the D0 power state. This makes the BARs inaccessible and has the additional bonus for vfio-pci that we don't attempt to DMA map BARs for devices in a non-D0 power state. To support this, an interface is added for devices to register the PM capability, which allows central tracking to enforce valid transitions and unmap BARs in non-D0 states. NB. We currently have device models (eepro100 and pcie_pci_bridge) that register a PM capability but do not set wmask to enable writes to the power state field. In order to maintain migration compatibility, this new helper does not manage the wmask to enable guest writes to initiate a power state change. The contents and write access of the PM capability are still managed by the caller. Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250225215237.3314011-2-alex.williamson@redhat.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/hw/pci/pci.h3
-rw-r--r--include/hw/pci/pci_device.h3
2 files changed, 6 insertions, 0 deletions
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 4002bbe..c220cc8 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -216,6 +216,8 @@ enum {
QEMU_PCIE_ARI_NEXTFN_1 = (1 << QEMU_PCIE_ARI_NEXTFN_1_BITNR),
#define QEMU_PCIE_EXT_TAG_BITNR 13
QEMU_PCIE_EXT_TAG = (1 << QEMU_PCIE_EXT_TAG_BITNR),
+#define QEMU_PCI_CAP_PM_BITNR 14
+ QEMU_PCI_CAP_PM = (1 << QEMU_PCI_CAP_PM_BITNR),
};
typedef struct PCIINTxRoute {
@@ -676,5 +678,6 @@ static inline void pci_irq_deassert(PCIDevice *pci_dev)
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
void pci_set_enabled(PCIDevice *pci_dev, bool state);
void pci_set_power(PCIDevice *pci_dev, bool state);
+int pci_pm_init(PCIDevice *pci_dev, uint8_t offset, Error **errp);
#endif
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index add208e..345b12e 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -105,6 +105,9 @@ struct PCIDevice {
/* Capability bits */
uint32_t cap_present;
+ /* Offset of PM capability in config space */
+ uint8_t pm_cap;
+
/* Offset of MSI-X capability in config space */
uint8_t msix_cap;