From: David Matlack <dmatlack@google.com>
To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
Cc: Alex Williamson <alex@shazbot.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Jason Gunthorpe <jgg@nvidia.com>,
Josh Hilke <jrhilke@google.com>, Lukas Wunner <lukas@wunner.de>,
Mahesh J Salgaonkar <mahesh@linux.ibm.com>,
"Oliver O'Halloran" <oohall@gmail.com>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Pratyush Yadav <pratyush@kernel.org>,
Samiullah Khawaja <skhawaja@google.com>,
Vipin Sharma <vipinsh@google.com>,
David Matlack <dmatlack@google.com>
Subject: [PATCH 14/15] PCI: Save reserved capability registers in a single pass
Date: Thu, 24 Sep 2026 17:35:00 +0000 [thread overview]
Message-ID: <20260924173501.856380-15-dmatlack@google.com> (raw)
In-Reply-To: <20260924173501.856380-1-dmatlack@google.com>
Every capability that the PCI core saves now reserves room for its
registers during device setup, so the reservation bitmap already records
exactly which configuration space DWORDs pci_save_state() has to read.
Walk the bitmap once instead of dispatching to a save function per
capability.
Values in the store are kept in ascending offset order, the same order
that for_each_set_bit() visits the bitmap, so the generic pass fills
slots sequentially and never has to look one up.
Delete pci_save_pcie_state(), pci_save_pcix_state(), pci_save_ltr_state(),
pci_save_aer_state(), pci_save_ptm_state(), pci_save_tph_state(),
pci_save_dpc_state() and pci_save_vc_state(), along with the PCI_VC_SAVE
arm of the Virtual Channel walker and pci_save_cap_word(), which loses
its last caller. Each of them existed only to rediscover offsets the
bitmap already knows.
pci_save_aspm_l1ss_state() is the one save function that survives,
because it saves the *parent's* L1SS registers into the parent's store,
which a pass over this device's bitmap cannot do. Move its call from the
deleted pci_save_pcie_state() to pci_save_state().
The PCIe capability is the one place where this is not a pure refactor.
pci_save_pcie_state() read each register with pcie_capability_read_word(),
which returns 0 for registers the device does not implement, and stored
that 0 into the containing DWORD's slot. The generic pass reads the DWORD
raw, so those slots now hold whatever the device returns. Restore is
unaffected: pci_restore_pcie_state() still writes through
pcie_capability_write_word(), which skips unimplemented registers. If
anything this is a fix, since a slot shared with another capability can
no longer be fed a synthetic 0 for a register that does not exist; slot N
is now always configuration space DWORD N.
Every other capability used pci_save_cap_word() or pci_save_cap_dword(),
both of which already read the containing DWORD raw, so their saved
values are unchanged.
The cost is a few extra configuration space reads for devices whose save
function had a runtime guard, e.g. TPH only saved its registers while TPH
was enabled. Restore keeps those guards, so the extra reads only make the
store a more faithful snapshot.
Assisted-by: LLM
Signed-off-by: David Matlack <dmatlack@google.com>
---
drivers/pci/pci.c | 47 +++++++++-------------------------------
drivers/pci/pci.h | 12 +---------
drivers/pci/pcie/aer.c | 13 +----------
drivers/pci/pcie/aspm.c | 17 +--------------
drivers/pci/pcie/dpc.c | 8 -------
drivers/pci/pcie/ptm.c | 8 -------
drivers/pci/saved-caps.c | 35 ++++++++++++++++++++----------
drivers/pci/tph.c | 22 -------------------
drivers/pci/vc.c | 45 +++++++-------------------------------
9 files changed, 44 insertions(+), 163 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 171763f560b8..73aa526e6901 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1649,7 +1649,7 @@ int pci_set_power_state_locked(struct pci_dev *dev, pci_power_t state)
EXPORT_SYMBOL(pci_set_power_state_locked);
/*
- * PCIe capability registers saved and restored by the PCI core. Registers a
+ * PCIe capability registers reserved and restored by the PCI core. Registers a
* device does not implement are skipped by the pcie_capability_*() accessors,
* so space is reserved for all of them regardless of the device.
*/
@@ -1685,24 +1685,6 @@ struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev, u16 cap)
return _pci_find_saved_cap(dev, cap, true);
}
-static void pci_save_pcie_state(struct pci_dev *dev)
-{
- unsigned int i;
- u16 val;
-
- if (!pci_is_pcie(dev))
- return;
-
- for (i = 0; i < ARRAY_SIZE(pcie_saved_regs); i++) {
- pcie_capability_read_word(dev, pcie_saved_regs[i], &val);
- pci_write_saved_cap_word(dev, dev->pcie_cap + pcie_saved_regs[i],
- val);
- }
-
- pci_save_aspm_l1ss_state(dev);
- pci_save_ltr_state(dev);
-}
-
static void pci_restore_pcie_state(struct pci_dev *dev)
{
unsigned int i;
@@ -1733,17 +1715,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
}
}
-static void pci_save_pcix_state(struct pci_dev *dev)
-{
- int pos;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!pos)
- return;
-
- pci_save_cap_word(dev, pos + PCI_X_CMD);
-}
-
static void pci_restore_pcix_state(struct pci_dev *dev)
{
int pos;
@@ -1771,13 +1742,15 @@ int pci_save_state(struct pci_dev *dev)
}
dev->state_saved = true;
- pci_save_pcie_state(dev);
- pci_save_pcix_state(dev);
- pci_save_dpc_state(dev);
- pci_save_aer_state(dev);
- pci_save_ptm_state(dev);
- pci_save_tph_state(dev);
- pci_save_vc_state(dev);
+ pci_save_caps(dev);
+
+ /*
+ * L1SS is the one capability whose state does not live entirely in
+ * this device's store: an endpoint's L1 substates only take effect if
+ * its upstream port is programmed to match, so the two are saved and
+ * restored together.
+ */
+ pci_save_aspm_l1ss_state(dev);
return 0;
}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 68c19f5025de..99de55799826 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -265,7 +265,7 @@ void pci_saved_caps_finalize(struct pci_dev *dev);
void pci_saved_caps_release(struct pci_dev *dev);
int pci_reserve_saved_cap(struct pci_dev *dev, unsigned int off, unsigned int len);
bool pci_saved_cap_reserved(struct pci_dev *dev, unsigned int off);
-void pci_save_cap_word(struct pci_dev *dev, unsigned int off);
+void pci_save_caps(struct pci_dev *dev);
void pci_save_cap_dword(struct pci_dev *dev, unsigned int off);
void pci_restore_cap_word(struct pci_dev *dev, unsigned int off);
void pci_restore_cap_dword(struct pci_dev *dev, unsigned int off);
@@ -359,7 +359,6 @@ void pci_vpd_init(struct pci_dev *dev);
extern const struct attribute_group pci_dev_vpd_attr_group;
/* PCI Virtual Channel */
-void pci_save_vc_state(struct pci_dev *dev);
void pci_restore_vc_state(struct pci_dev *dev);
void pci_vc_reserve_saved_caps(struct pci_dev *dev);
@@ -944,7 +943,6 @@ struct rcec_ea {
#endif
#ifdef CONFIG_PCIE_DPC
-void pci_save_dpc_state(struct pci_dev *dev);
void pci_restore_dpc_state(struct pci_dev *dev);
void pci_dpc_init(struct pci_dev *pdev);
void dpc_process_error(struct pci_dev *pdev);
@@ -952,7 +950,6 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev);
bool pci_dpc_recovered(struct pci_dev *pdev);
unsigned int dpc_tlp_log_len(struct pci_dev *dev);
#else
-static inline void pci_save_dpc_state(struct pci_dev *dev) { }
static inline void pci_restore_dpc_state(struct pci_dev *dev) { }
static inline void pci_dpc_init(struct pci_dev *pdev) { }
static inline bool pci_dpc_recovered(struct pci_dev *pdev) { return false; }
@@ -1077,25 +1074,21 @@ static inline int pci_resource_num_to_vf_bar(int resno)
#ifdef CONFIG_PCIE_TPH
void pci_restore_tph_state(struct pci_dev *dev);
-void pci_save_tph_state(struct pci_dev *dev);
void pci_no_tph(void);
void pci_tph_init(struct pci_dev *dev);
#else
static inline void pci_restore_tph_state(struct pci_dev *dev) { }
-static inline void pci_save_tph_state(struct pci_dev *dev) { }
static inline void pci_no_tph(void) { }
static inline void pci_tph_init(struct pci_dev *dev) { }
#endif
#ifdef CONFIG_PCIE_PTM
void pci_ptm_init(struct pci_dev *dev);
-void pci_save_ptm_state(struct pci_dev *dev);
void pci_restore_ptm_state(struct pci_dev *dev);
void pci_suspend_ptm(struct pci_dev *dev);
void pci_resume_ptm(struct pci_dev *dev);
#else
static inline void pci_ptm_init(struct pci_dev *dev) { }
-static inline void pci_save_ptm_state(struct pci_dev *dev) { }
static inline void pci_restore_ptm_state(struct pci_dev *dev) { }
static inline void pci_suspend_ptm(struct pci_dev *dev) { }
static inline void pci_resume_ptm(struct pci_dev *dev) { }
@@ -1145,7 +1138,6 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active);
int pcie_retrain_link(struct pci_dev *pdev, bool use_lt);
/* ASPM-related functionality we need even without CONFIG_PCIEASPM */
-void pci_save_ltr_state(struct pci_dev *dev);
void pci_restore_ltr_state(struct pci_dev *dev);
void pci_configure_aspm_l1ss(struct pci_dev *dev);
void pci_save_aspm_l1ss_state(struct pci_dev *dev);
@@ -1354,7 +1346,6 @@ extern const struct attribute_group aer_attr_group;
void pci_aer_clear_fatal_status(struct pci_dev *dev);
int pci_aer_clear_status(struct pci_dev *dev);
int pci_aer_raw_clear_status(struct pci_dev *dev);
-void pci_save_aer_state(struct pci_dev *dev);
void pci_restore_aer_state(struct pci_dev *dev);
#else
static inline void pci_no_aer(void) { }
@@ -1363,7 +1354,6 @@ static inline void pci_aer_exit(struct pci_dev *d) { }
static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
static inline int pci_aer_clear_status(struct pci_dev *dev) { return -EINVAL; }
static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL; }
-static inline void pci_save_aer_state(struct pci_dev *dev) { }
static inline void pci_restore_aer_state(struct pci_dev *dev) { }
#endif
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 765899cf4046..8ebe5b5a1aef 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -353,7 +353,7 @@ int pci_aer_clear_status(struct pci_dev *dev)
}
/*
- * AER registers saved and restored by the PCI core. PCI_ERR_ROOT_COMMAND is
+ * AER registers reserved and restored by the PCI core. PCI_ERR_ROOT_COMMAND is
* only implemented by Root Ports and Root Complex Event Collectors (PCIe
* r6.0, sec 7.8.4.9) and so must come last.
*/
@@ -373,17 +373,6 @@ static unsigned int aer_nr_saved_regs(struct pci_dev *dev)
return ARRAY_SIZE(aer_saved_regs) - 1;
}
-void pci_save_aer_state(struct pci_dev *dev)
-{
- unsigned int i;
-
- if (!dev->aer_cap)
- return;
-
- for (i = 0; i < aer_nr_saved_regs(dev); i++)
- pci_save_cap_dword(dev, dev->aer_cap + aer_saved_regs[i]);
-}
-
void pci_restore_aer_state(struct pci_dev *dev)
{
unsigned int i;
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 9d64c6aebb9f..a026bda8c364 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -27,21 +27,6 @@
#include "../pci.h"
-void pci_save_ltr_state(struct pci_dev *dev)
-{
- int ltr;
-
- if (!pci_is_pcie(dev))
- return;
-
- ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
- if (!ltr)
- return;
-
- /* Some broken devices only support dword access to LTR */
- pci_save_cap_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT);
-}
-
void pci_restore_ltr_state(struct pci_dev *dev)
{
int ltr;
@@ -86,7 +71,7 @@ void pci_save_aspm_l1ss_state(struct pci_dev *pdev)
/*
* Save L1 substate configuration. The ASPM L0s/L1 configuration
- * in PCI_EXP_LNKCTL_ASPMC is saved by pci_save_pcie_state().
+ * in PCI_EXP_LNKCTL_ASPMC is saved by pci_save_caps().
*/
pci_save_cap_dword(pdev, pdev->l1ss + PCI_L1SS_CTL2);
pci_save_cap_dword(pdev, pdev->l1ss + PCI_L1SS_CTL1);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 6f40cf2c712c..1f3ba582a31c 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -43,14 +43,6 @@ static const char * const rp_pio_error_string[] = {
"Memory Request Completion Timeout", /* Bit Position 18 */
};
-void pci_save_dpc_state(struct pci_dev *dev)
-{
- if (!dev->dpc_cap)
- return;
-
- pci_save_cap_word(dev, dev->dpc_cap + PCI_EXP_DPC_CTL);
-}
-
void pci_restore_dpc_state(struct pci_dev *dev)
{
if (!dev->dpc_cap)
diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c
index a9e29e19b0f9..b2c1e2a4b81e 100644
--- a/drivers/pci/pcie/ptm.c
+++ b/drivers/pci/pcie/ptm.c
@@ -89,14 +89,6 @@ void pci_ptm_init(struct pci_dev *dev)
dev->ptm_requester = 1;
}
-void pci_save_ptm_state(struct pci_dev *dev)
-{
- if (!dev->ptm_cap)
- return;
-
- pci_save_cap_dword(dev, dev->ptm_cap + PCI_PTM_CTRL);
-}
-
void pci_restore_ptm_state(struct pci_dev *dev)
{
if (!dev->ptm_cap)
diff --git a/drivers/pci/saved-caps.c b/drivers/pci/saved-caps.c
index eaacc3b3ea74..a5755bdf8e01 100644
--- a/drivers/pci/saved-caps.c
+++ b/drivers/pci/saved-caps.c
@@ -94,9 +94,9 @@ bool pci_saved_cap_reserved(struct pci_dev *dev, unsigned int off)
* @off: offset of the register in configuration space
* @len: size of the register in bytes
*
- * Reserve room to save the register at @off, which may then be saved with
- * pci_save_cap_word() and friends. Must be called during device setup, before
- * the store is finalized.
+ * Reserve room to save the register at @off, which pci_save_caps() then reads
+ * into the store. Must be called during device setup, before the store is
+ * finalized.
*
* Return: 0 on success, negative errno otherwise.
*/
@@ -136,28 +136,39 @@ int pci_reserve_saved_cap(struct pci_dev *dev, unsigned int off, unsigned int le
}
/**
- * pci_save_cap_dword - save a 32-bit capability register
+ * pci_save_caps - save every reserved capability register
* @dev: the PCI device
- * @off: offset of the register in configuration space
+ *
+ * Read all of the configuration space DWORDs that capabilities reserved during
+ * device setup into the store. Values are kept in ascending offset order, the
+ * same order that for_each_set_bit() walks the reservation bitmap, so the
+ * destination slot advances in lockstep with the bitmap and needs no lookup.
*/
-void pci_save_cap_dword(struct pci_dev *dev, unsigned int off)
+void pci_save_caps(struct pci_dev *dev)
{
- u32 *slot = pci_saved_cap_slot(dev, off);
+ struct pci_saved_caps *caps = &dev->saved_caps;
+ unsigned int dword, i = 0;
- if (!slot)
+ if (!caps->dword_val)
return;
- pci_read_config_dword(dev, ALIGN_DOWN(off, sizeof(u32)), slot);
+ for_each_set_bit(dword, caps->dword_map, PCI_CFG_SPACE_EXP_DWORDS)
+ pci_read_config_dword(dev, dword * sizeof(u32), &caps->dword_val[i++]);
}
/**
- * pci_save_cap_word - save a 16-bit capability register
+ * pci_save_cap_dword - save a 32-bit capability register
* @dev: the PCI device
* @off: offset of the register in configuration space
*/
-void pci_save_cap_word(struct pci_dev *dev, unsigned int off)
+void pci_save_cap_dword(struct pci_dev *dev, unsigned int off)
{
- pci_save_cap_dword(dev, ALIGN_DOWN(off, sizeof(u32)));
+ u32 *slot = pci_saved_cap_slot(dev, off);
+
+ if (!slot)
+ return;
+
+ pci_read_config_dword(dev, ALIGN_DOWN(off, sizeof(u32)), slot);
}
/**
diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
index fa9f60e5a431..6f46d55eba54 100644
--- a/drivers/pci/tph.c
+++ b/drivers/pci/tph.c
@@ -457,28 +457,6 @@ void pci_restore_tph_state(struct pci_dev *pdev)
}
}
-void pci_save_tph_state(struct pci_dev *pdev)
-{
- int num_entries, i, offset;
-
- if (!pdev->tph_cap)
- return;
-
- if (!pdev->tph_enabled)
- return;
-
- /* Save control register */
- pci_save_cap_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL);
-
- /* Save all ST entries in extended capability structure */
- offset = PCI_TPH_BASE_SIZEOF;
- num_entries = pcie_tph_get_st_table_size(pdev);
- for (i = 0; i < num_entries; i++) {
- pci_save_cap_word(pdev, pdev->tph_cap + offset);
- offset += sizeof(u16);
- }
-}
-
void pci_no_tph(void)
{
pci_tph_disabled = true;
diff --git a/drivers/pci/vc.c b/drivers/pci/vc.c
index d72d67dae78e..49725bbc2a9e 100644
--- a/drivers/pci/vc.c
+++ b/drivers/pci/vc.c
@@ -19,12 +19,11 @@
/* What to do with the registers of a VC capability */
enum pci_vc_op {
PCI_VC_RESERVE, /* Reserve room to save them */
- PCI_VC_SAVE, /* Copy them into the saved capabilities */
PCI_VC_RESTORE, /* Write the saved capabilities back */
};
/**
- * pci_vc_do_word - Reserve, save, or restore a word
+ * pci_vc_do_word - Reserve or restore a word
* @dev: device
* @pos: config space position
* @op: what to do with it
@@ -36,9 +35,6 @@ static int pci_vc_do_word(struct pci_dev *dev, int pos, enum pci_vc_op op)
switch (op) {
case PCI_VC_RESERVE:
return pci_reserve_saved_cap(dev, pos, sizeof(u16));
- case PCI_VC_SAVE:
- pci_save_cap_word(dev, pos);
- break;
case PCI_VC_RESTORE:
if (!pci_saved_cap_reserved(dev, pos))
return -ENOENT;
@@ -51,7 +47,7 @@ static int pci_vc_do_word(struct pci_dev *dev, int pos, enum pci_vc_op op)
}
/**
- * pci_vc_do_dwords - Reserve, save, or restore a series of dwords
+ * pci_vc_do_dwords - Reserve or restore a series of dwords
* @dev: device
* @pos: starting config space position
* @dwords: number of dwords
@@ -70,18 +66,14 @@ static int pci_vc_do_dwords(struct pci_dev *dev, int pos, int dwords,
/*
* The device supplies the table offsets and sizes, so what it reports
* now may not match what was reserved during setup, e.g. if it is no
- * longer responding. Save or restore all of the table, or none of it.
+ * longer responding. Restore all of the table or none of it.
*/
for (i = 0; i < dwords; i++)
if (!pci_saved_cap_reserved(dev, pos + i * sizeof(u32)))
return -ENOENT;
- for (i = 0; i < dwords; i++, pos += sizeof(u32)) {
- if (op == PCI_VC_SAVE)
- pci_save_cap_dword(dev, pos);
- else
- pci_restore_cap_dword(dev, pos);
- }
+ for (i = 0; i < dwords; i++, pos += sizeof(u32))
+ pci_restore_cap_dword(dev, pos);
return 0;
}
@@ -250,13 +242,13 @@ static void pci_vc_restore_res_ctrl(struct pci_dev *dev, int pos, int res)
}
/**
- * pci_vc_do_saved_caps - Reserve, save, or restore VC state
+ * pci_vc_do_saved_caps - Reserve or restore VC state
* @dev: device
* @pos: starting position of VC capability (VC/VC9/MFVC)
* @op: what to do with the registers found along the way
*
- * Walking Virtual Channel config space is complicated, so reserving, saving
- * and restoring it are all driven from one function to reduce code and
+ * Walking Virtual Channel config space is complicated, so reserving and
+ * restoring it are both driven from one function to reduce code and
* guarantee that they agree on which registers are involved.
*
* Return: 0 on success, negative errno otherwise.
@@ -387,27 +379,6 @@ static struct {
{ PCI_EXT_CAP_ID_VC, "VC" },
{ PCI_EXT_CAP_ID_VC9, "VC9" } };
-/**
- * pci_save_vc_state - Save VC state to the saved capability store
- * @dev: device
- *
- * For each type of VC capability, VC/VC9/MFVC, find the capability and
- * save it to the previously reserved capability store.
- */
-void pci_save_vc_state(struct pci_dev *dev)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(vc_caps); i++) {
- int pos = pci_find_ext_capability(dev, vc_caps[i].id);
-
- if (!pos)
- continue;
-
- pci_vc_do_saved_caps(dev, pos, PCI_VC_SAVE);
- }
-}
-
/**
* pci_restore_vc_state - Restore VC state from the saved capability store
* @dev: device
--
2.56.0.rc1.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-09-24 17:35 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 17:34 [PATCH 00/15] PCI: Index saved capability state by configuration space offset David Matlack
2026-09-24 17:34 ` [PATCH 01/15] PCI/DPC: Allocate the DPC save buffer during device setup David Matlack
2026-09-24 17:34 ` [PATCH 02/15] PCI: Add an offset-indexed store for saved capability registers David Matlack
2026-09-24 17:34 ` [PATCH 03/15] PCI: Lay out struct pci_saved_state by configuration space offset David Matlack
2026-09-24 17:34 ` [PATCH 04/15] PCI: Save PCIe state in the saved capability store David Matlack
2026-09-24 17:34 ` [PATCH 05/15] PCI: Save PCI-X " David Matlack
2026-09-24 17:34 ` [PATCH 06/15] PCI/ASPM: Save LTR " David Matlack
2026-09-24 17:34 ` [PATCH 07/15] PCI/ASPM: Save L1SS " David Matlack
2026-09-24 17:34 ` [PATCH 08/15] PCI/AER: Save AER " David Matlack
2026-09-24 17:34 ` [PATCH 09/15] PCI/PTM: Save PTM " David Matlack
2026-09-24 17:34 ` [PATCH 10/15] PCI/TPH: Save TPH " David Matlack
2026-09-24 17:34 ` [PATCH 11/15] PCI/DPC: Save DPC " David Matlack
2026-09-24 17:34 ` [PATCH 12/15] PCI/VC: Split the VC Resource Control restore into a helper David Matlack
2026-09-24 17:34 ` [PATCH 13/15] PCI/VC: Save VC state in the saved capability store David Matlack
2026-09-24 17:35 ` David Matlack [this message]
2026-09-24 17:35 ` [PATCH 15/15] PCI: Remove the per-capability save buffers David Matlack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260924173501.856380-15-dmatlack@google.com \
--to=dmatlack@google.com \
--cc=alex@shazbot.org \
--cc=bhelgaas@google.com \
--cc=jgg@nvidia.com \
--cc=jrhilke@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=lukas@wunner.de \
--cc=mahesh@linux.ibm.com \
--cc=oohall@gmail.com \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=skhawaja@google.com \
--cc=vipinsh@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®