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@xxxxxxxxxx> --- 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