[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250728-luo-pci-v1-14-955b078dd653@kernel.org>
Date: Mon, 28 Jul 2025 01:24:44 -0700
From: chrisl@...nel.org
To: Bjorn Helgaas <bhelgaas@...gle.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
"Rafael J. Wysocki" <rafael@...nel.org>, Danilo Krummrich <dakr@...nel.org>,
Len Brown <lenb@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-pci@...r.kernel.org,
linux-acpi@...r.kernel.org, David Matlack <dmatlack@...gle.com>,
Pasha Tatashin <tatashin@...gle.com>, Jason Miu <jasonmiu@...gle.com>,
Vipin Sharma <vipinsh@...gle.com>, Saeed Mahameed <saeedm@...dia.com>,
Adithya Jayachandran <ajayachandra@...dia.com>,
Parav Pandit <parav@...dia.com>, William Tu <witu@...dia.com>,
Mike Rapoport <rppt@...nel.org>, Chris Li <chrisl@...nel.org>,
Jason Gunthorpe <jgg@...pe.ca>, Leon Romanovsky <leon@...nel.org>
Subject: [PATCH RFC 14/25] PCI/LUO: Restore power state of a PCI device
From: Jason Miu <jasonmiu@...gle.com>
>From the liveupdate saved PCI device state, restore the device power
state.
The `pci_dev->current_state` is a cached power state. If the device
driver calls `pci_enable_device()`, this value can be modified from
reading the PMCSR register (see `pci_enable_device_flags()`). In the
future patches when a driver tries to enable the PCI device after
liveupdate, we should check the device power state at that moment with
the saved value.
Tested: QEMU liveupdate boot test. Trigger the liveupdate to the
`finish` phase.
Signed-off-by: Chris Li <chrisl@...nel.org>
---
drivers/pci/pci.h | 6 ++++++
drivers/pci/probe.c | 8 ++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 2ef12745ee05960878d8d3fe0cdf136f69c8d408..a8acc986a5aac808ec64395d7d946ee036270f5b 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1182,9 +1182,15 @@ static inline int pci_msix_write_tph_tag(struct pci_dev *pdev, unsigned int inde
PCI_CONF1_EXT_REG(reg))
#ifdef CONFIG_LIVEUPDATE
+#define PCI_SER_GET(__pci_dev, __var, __def) \
+ (__pci_dev->dev.lu.dev_state) ? \
+ ((struct pci_dev_ser *)__pci_dev->dev.lu.dev_state)->__var : __def
+
void pci_liveupdate_restore(struct pci_dev *dev);
void pci_liveupdate_override_driver(struct pci_dev *dev);
#else
+#define PCI_SER_GET(__dev, __var, __def) __def
+
static inline void pci_liveupdate_restore(struct pci_dev *dev) {}
static inline void pci_liveupdate_override_driver(struct pci_dev *dev) {}
#endif
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e41a1bef2083aa9184fd1c894d5de964f19d5c01..7dd2cf9f9e110636f8998df22a333638cce25e6b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2030,8 +2030,12 @@ int pci_setup_device(struct pci_dev *dev)
if (pci_is_pcie(dev))
dev->supported_speeds = pcie_get_supported_speeds(dev);
- /* "Unknown power state" */
- dev->current_state = PCI_UNKNOWN;
+ /*
+ * Restore the power state from liveupdate saved state.
+ * If we are not booted from liveupdate, default
+ * "Unknown power state".
+ */
+ dev->current_state = PCI_SER_GET(dev, current_state, PCI_UNKNOWN);
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
--
2.50.1.487.gc89ff58d15-goog
Powered by blists - more mailing lists