[no subject]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux