* [PATCH 0/3] cxl/pci: Fix the GPF DVSEC setup path
@ 2026-09-22 10:00 Guixin Liu
2026-09-22 10:00 ` [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints Guixin Liu
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Guixin Liu @ 2026-09-22 10:00 UTC (permalink / raw)
To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield,
Vishal Verma, Dan Williams, Ira Weiny, Li Ming
Cc: linux-cxl
Three small fixes for the GPF setup path in cxl/core/pci.c, found
while reworking the same area for a downstream backport.
Patch 1 is the one with user-visible impact: on an RCD the GPF DVSEC
lookup takes the port path, so dirty shutdown tracking never arms and
the count stays invalid. The other two deal with error handling and
a full-register rewrite of the phase control register.
Testing on a QEMU CXL topology, with the patched cxl_core hot-swapped
in and the topology re-enumerated. With the phase 1/2 timeout
registers of all four dports (two root ports, two switch downstream
ports) zeroed beforehand, every dport came back at 0x0702 — base 2,
scale 7, the same value the unpatched code writes. So the timeout
write ran on each of them: the read-modify-write of patch 3, through
the error-checked setup of patch 2. With the registers left at their
programmed value instead, the setup takes the "already at max" early
return and writes nothing. Re-enumeration comes up clean, all three
memdevs back.
What QEMU cannot exercise: the topology has no RCD, so the RC_END
branch of patch 1 never ran — though the emulated type-3 devices do
expose the Device GPF DVSEC that the fix selects for a restricted
endpoint. A config write to a live DVSEC does not fail, so the error
paths of patch 2 stayed cold. And the phase control register defines
no non-timeout bits today, so patch 3 lands on the same value the old
full rewrite did.
Guixin Liu (3):
cxl/pci: Use the Device GPF DVSEC for restricted endpoints
cxl/pci: Program the Port GPF timeouts before caching the DVSEC
cxl/pci: Update only the Port GPF timeout fields
drivers/cxl/core/pci.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)
--
2.43.7
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints 2026-09-22 10:00 [PATCH 0/3] cxl/pci: Fix the GPF DVSEC setup path Guixin Liu @ 2026-09-22 10:00 ` Guixin Liu 2026-09-25 23:36 ` Jonathan Cameron 2026-09-28 23:45 ` Dave Jiang 2026-09-22 10:00 ` [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC Guixin Liu 2026-09-22 10:00 ` [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields Guixin Liu 2 siblings, 2 replies; 10+ messages in thread From: Guixin Liu @ 2026-09-22 10:00 UTC (permalink / raw) To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming Cc: linux-cxl cxl_gpf_get_dvsec() picks between the Port and the Device GPF DVSEC from the PCIe type of the given device, and only a plain endpoint counts as a device. A restricted CXL device is an endpoint too, but it falls into the port case and is probed for the Port GPF DVSEC instead of the Device GPF DVSEC. On an RCD, dirty shutdown tracking therefore never arms: the DVSEC lookup in cxl_nvdimm_arm_dirty_shutdown_tracking() fails, the dirty shutdown count stays invalid, and the warning complains about a missing Port GPF DVSEC on a device. Treat restricted endpoints as devices. Fixes: 36aace15d9bd ("cxl/pci: Drop the parameter is_port of cxl_gpf_get_dvsec()") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> --- drivers/cxl/core/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index 9d807c1a002c..e31aad7a525a 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -804,7 +804,8 @@ u16 cxl_gpf_get_dvsec(struct device *dev) return 0; pdev = to_pci_dev(dev); - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT || + is_cxl_restricted(pdev)) is_port = false; dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL, -- 2.43.7 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints 2026-09-22 10:00 ` [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints Guixin Liu @ 2026-09-25 23:36 ` Jonathan Cameron 2026-09-28 23:45 ` Dave Jiang 1 sibling, 0 replies; 10+ messages in thread From: Jonathan Cameron @ 2026-09-25 23:36 UTC (permalink / raw) To: Guixin Liu Cc: Davidlohr Bueso, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming, linux-cxl On Tue, 22 Sep 2026 18:00:11 +0800 Guixin Liu <kanie@linux.alibaba.com> wrote: > cxl_gpf_get_dvsec() picks between the Port and the Device GPF DVSEC > from the PCIe type of the given device, and only a plain endpoint > counts as a device. A restricted CXL device is an endpoint too, but > it falls into the port case and is probed for the Port GPF DVSEC > instead of the Device GPF DVSEC. > > On an RCD, dirty shutdown tracking therefore never arms: the DVSEC > lookup in cxl_nvdimm_arm_dirty_shutdown_tracking() fails, the dirty > shutdown count stays invalid, and the warning complains about a > missing Port GPF DVSEC on a device. > > Treat restricted endpoints as devices. > > Fixes: 36aace15d9bd ("cxl/pci: Drop the parameter is_port of cxl_gpf_get_dvsec()") > Cc: stable@vger.kernel.org > Assisted-by: LLM > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Not an area I ever really messed around with, but the description and fix look valid to me. So a somewhat tentative. Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> > --- > drivers/cxl/core/pci.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c > index 9d807c1a002c..e31aad7a525a 100644 > --- a/drivers/cxl/core/pci.c > +++ b/drivers/cxl/core/pci.c > @@ -804,7 +804,8 @@ u16 cxl_gpf_get_dvsec(struct device *dev) > return 0; > > pdev = to_pci_dev(dev); > - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) > + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT || > + is_cxl_restricted(pdev)) > is_port = false; > > dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL, ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints 2026-09-22 10:00 ` [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints Guixin Liu 2026-09-25 23:36 ` Jonathan Cameron @ 2026-09-28 23:45 ` Dave Jiang 1 sibling, 0 replies; 10+ messages in thread From: Dave Jiang @ 2026-09-28 23:45 UTC (permalink / raw) To: Guixin Liu, Davidlohr Bueso, Jonathan Cameron, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming Cc: linux-cxl On 9/22/26 3:00 AM, Guixin Liu wrote: > cxl_gpf_get_dvsec() picks between the Port and the Device GPF DVSEC > from the PCIe type of the given device, and only a plain endpoint > counts as a device. A restricted CXL device is an endpoint too, but > it falls into the port case and is probed for the Port GPF DVSEC > instead of the Device GPF DVSEC. > > On an RCD, dirty shutdown tracking therefore never arms: the DVSEC > lookup in cxl_nvdimm_arm_dirty_shutdown_tracking() fails, the dirty > shutdown count stays invalid, and the warning complains about a > missing Port GPF DVSEC on a device. > > Treat restricted endpoints as devices. > > Fixes: 36aace15d9bd ("cxl/pci: Drop the parameter is_port of cxl_gpf_get_dvsec()") > Cc: stable@vger.kernel.org > Assisted-by: LLM > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> > --- > drivers/cxl/core/pci.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c > index 9d807c1a002c..e31aad7a525a 100644 > --- a/drivers/cxl/core/pci.c > +++ b/drivers/cxl/core/pci.c > @@ -804,7 +804,8 @@ u16 cxl_gpf_get_dvsec(struct device *dev) > return 0; > > pdev = to_pci_dev(dev); > - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) > + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT || > + is_cxl_restricted(pdev)) > is_port = false; > > dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL, ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC 2026-09-22 10:00 [PATCH 0/3] cxl/pci: Fix the GPF DVSEC setup path Guixin Liu 2026-09-22 10:00 ` [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints Guixin Liu @ 2026-09-22 10:00 ` Guixin Liu 2026-09-25 23:43 ` Jonathan Cameron 2026-09-28 23:46 ` Dave Jiang 2026-09-22 10:00 ` [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields Guixin Liu 2 siblings, 2 replies; 10+ messages in thread From: Guixin Liu @ 2026-09-22 10:00 UTC (permalink / raw) To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming Cc: linux-cxl cxl_gpf_port_setup() caches the Port GPF DVSEC offset in the dport before programming the phase timeouts, and ignores the return value of both update_gpf_port_dvsec() calls: the function always reports success. A failing config write is therefore not only silent, it is also permanent: the timeouts stay at the hardware defaults instead of the maximum flush window the kernel is asking for, and the cached offset keeps any later endpoint attach from retrying the update. Propagate the errors and cache the offset only after both phases are programmed, so the next endpoint attach retries the setup. Fixes: 6af941db6a60 ("cxl/pci: Update Port GPF timeout only when the first EP attaching") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> --- drivers/cxl/core/pci.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index e31aad7a525a..1f470ab0df3b 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -840,7 +840,7 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) rc = pci_read_config_word(pdev, dvsec + offset, &ctrl); if (rc) - return rc; + return pcibios_err_to_errno(rc); if (FIELD_GET(base, ctrl) == GPF_TIMEOUT_BASE_MAX && FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX) @@ -850,11 +850,17 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); rc = pci_write_config_word(pdev, dvsec + offset, ctrl); - if (!rc) - pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n", - phase, GPF_TIMEOUT_BASE_MAX); + if (rc) { + rc = pcibios_err_to_errno(rc); + pci_warn(pdev, "Port GPF phase %d timeout write failed: %d\n", + phase, rc); + return rc; + } - return rc; + pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n", + phase, GPF_TIMEOUT_BASE_MAX); + + return 0; } int cxl_gpf_port_setup(struct cxl_dport *dport) @@ -864,16 +870,22 @@ int cxl_gpf_port_setup(struct cxl_dport *dport) if (!dport->gpf_dvsec) { struct pci_dev *pdev; - int dvsec; + int dvsec, rc; dvsec = cxl_gpf_get_dvsec(dport->dport_dev); if (!dvsec) return -EINVAL; - dport->gpf_dvsec = dvsec; pdev = to_pci_dev(dport->dport_dev); - update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 1); - update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 2); + rc = update_gpf_port_dvsec(pdev, dvsec, 1); + if (rc) + return rc; + + rc = update_gpf_port_dvsec(pdev, dvsec, 2); + if (rc) + return rc; + + dport->gpf_dvsec = dvsec; } return 0; -- 2.43.7 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC 2026-09-22 10:00 ` [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC Guixin Liu @ 2026-09-25 23:43 ` Jonathan Cameron 2026-09-28 23:46 ` Dave Jiang 1 sibling, 0 replies; 10+ messages in thread From: Jonathan Cameron @ 2026-09-25 23:43 UTC (permalink / raw) To: Guixin Liu Cc: Davidlohr Bueso, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming, linux-cxl On Tue, 22 Sep 2026 18:00:12 +0800 Guixin Liu <kanie@linux.alibaba.com> wrote: > cxl_gpf_port_setup() caches the Port GPF DVSEC offset in the dport > before programming the phase timeouts, and ignores the return value > of both update_gpf_port_dvsec() calls: the function always reports > success. > > A failing config write is therefore not only silent, it is also > permanent: the timeouts stay at the hardware defaults instead of the > maximum flush window the kernel is asking for, and the cached offset > keeps any later endpoint attach from retrying the update. > > Propagate the errors and cache the offset only after both phases are > programmed, so the next endpoint attach retries the setup. > > Fixes: 6af941db6a60 ("cxl/pci: Update Port GPF timeout only when the first EP attaching") > Cc: stable@vger.kernel.org > Assisted-by: LLM > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Handling config write fails is a bit of an esoteric corner. I don't mind it being improved but not for me that important unless there is some reason we see these in the real world? Definitely good to make it return errno rather than the pcibios_err_ though so overall I think this is good to have. Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> > --- > drivers/cxl/core/pci.c | 30 +++++++++++++++++++++--------- > 1 file changed, 21 insertions(+), 9 deletions(-) > > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c > index e31aad7a525a..1f470ab0df3b 100644 > --- a/drivers/cxl/core/pci.c > +++ b/drivers/cxl/core/pci.c > @@ -840,7 +840,7 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) > > rc = pci_read_config_word(pdev, dvsec + offset, &ctrl); > if (rc) > - return rc; > + return pcibios_err_to_errno(rc); > > if (FIELD_GET(base, ctrl) == GPF_TIMEOUT_BASE_MAX && > FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX) > @@ -850,11 +850,17 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) > ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); > > rc = pci_write_config_word(pdev, dvsec + offset, ctrl); > - if (!rc) > - pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n", > - phase, GPF_TIMEOUT_BASE_MAX); > + if (rc) { > + rc = pcibios_err_to_errno(rc); > + pci_warn(pdev, "Port GPF phase %d timeout write failed: %d\n", > + phase, rc); > + return rc; > + } > > - return rc; > + pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n", > + phase, GPF_TIMEOUT_BASE_MAX); > + > + return 0; > } > > int cxl_gpf_port_setup(struct cxl_dport *dport) > @@ -864,16 +870,22 @@ int cxl_gpf_port_setup(struct cxl_dport *dport) > > if (!dport->gpf_dvsec) { > struct pci_dev *pdev; > - int dvsec; > + int dvsec, rc; > > dvsec = cxl_gpf_get_dvsec(dport->dport_dev); > if (!dvsec) > return -EINVAL; > > - dport->gpf_dvsec = dvsec; > pdev = to_pci_dev(dport->dport_dev); > - update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 1); > - update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 2); > + rc = update_gpf_port_dvsec(pdev, dvsec, 1); > + if (rc) > + return rc; > + > + rc = update_gpf_port_dvsec(pdev, dvsec, 2); > + if (rc) > + return rc; > + > + dport->gpf_dvsec = dvsec; > } > > return 0; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC 2026-09-22 10:00 ` [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC Guixin Liu 2026-09-25 23:43 ` Jonathan Cameron @ 2026-09-28 23:46 ` Dave Jiang 1 sibling, 0 replies; 10+ messages in thread From: Dave Jiang @ 2026-09-28 23:46 UTC (permalink / raw) To: Guixin Liu, Davidlohr Bueso, Jonathan Cameron, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming Cc: linux-cxl On 9/22/26 3:00 AM, Guixin Liu wrote: > cxl_gpf_port_setup() caches the Port GPF DVSEC offset in the dport > before programming the phase timeouts, and ignores the return value > of both update_gpf_port_dvsec() calls: the function always reports > success. > > A failing config write is therefore not only silent, it is also > permanent: the timeouts stay at the hardware defaults instead of the > maximum flush window the kernel is asking for, and the cached offset > keeps any later endpoint attach from retrying the update. > > Propagate the errors and cache the offset only after both phases are > programmed, so the next endpoint attach retries the setup. > > Fixes: 6af941db6a60 ("cxl/pci: Update Port GPF timeout only when the first EP attaching") > Cc: stable@vger.kernel.org > Assisted-by: LLM > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> > --- > drivers/cxl/core/pci.c | 30 +++++++++++++++++++++--------- > 1 file changed, 21 insertions(+), 9 deletions(-) > > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c > index e31aad7a525a..1f470ab0df3b 100644 > --- a/drivers/cxl/core/pci.c > +++ b/drivers/cxl/core/pci.c > @@ -840,7 +840,7 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) > > rc = pci_read_config_word(pdev, dvsec + offset, &ctrl); > if (rc) > - return rc; > + return pcibios_err_to_errno(rc); > > if (FIELD_GET(base, ctrl) == GPF_TIMEOUT_BASE_MAX && > FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX) > @@ -850,11 +850,17 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) > ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); > > rc = pci_write_config_word(pdev, dvsec + offset, ctrl); > - if (!rc) > - pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n", > - phase, GPF_TIMEOUT_BASE_MAX); > + if (rc) { > + rc = pcibios_err_to_errno(rc); > + pci_warn(pdev, "Port GPF phase %d timeout write failed: %d\n", > + phase, rc); > + return rc; > + } > > - return rc; > + pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n", > + phase, GPF_TIMEOUT_BASE_MAX); > + > + return 0; > } > > int cxl_gpf_port_setup(struct cxl_dport *dport) > @@ -864,16 +870,22 @@ int cxl_gpf_port_setup(struct cxl_dport *dport) > > if (!dport->gpf_dvsec) { > struct pci_dev *pdev; > - int dvsec; > + int dvsec, rc; > > dvsec = cxl_gpf_get_dvsec(dport->dport_dev); > if (!dvsec) > return -EINVAL; > > - dport->gpf_dvsec = dvsec; > pdev = to_pci_dev(dport->dport_dev); > - update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 1); > - update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 2); > + rc = update_gpf_port_dvsec(pdev, dvsec, 1); > + if (rc) > + return rc; > + > + rc = update_gpf_port_dvsec(pdev, dvsec, 2); > + if (rc) > + return rc; > + > + dport->gpf_dvsec = dvsec; > } > > return 0; ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields 2026-09-22 10:00 [PATCH 0/3] cxl/pci: Fix the GPF DVSEC setup path Guixin Liu 2026-09-22 10:00 ` [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints Guixin Liu 2026-09-22 10:00 ` [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC Guixin Liu @ 2026-09-22 10:00 ` Guixin Liu 2026-09-25 23:44 ` Jonathan Cameron 2 siblings, 1 reply; 10+ messages in thread From: Guixin Liu @ 2026-09-22 10:00 UTC (permalink / raw) To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming Cc: linux-cxl update_gpf_port_dvsec() rebuilds the phase control register from just the timeout base and scale, so the rest of the register is cleared by the write. The other bits are reserved today and nothing is lost, but the full-register rewrite would clobber any field the spec defines there later. Read-modify-write the register and change only the two timeout fields. Fixes: a52b6a2c1c99 ("cxl/pci: Support Global Persistent Flush (GPF)") Assisted-by: LLM Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> --- drivers/cxl/core/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index 1f470ab0df3b..72e54facafe8 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -846,8 +846,9 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX) return 0; - ctrl = FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX); - ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); + ctrl &= ~(base | scale); + ctrl |= FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX) | + FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); rc = pci_write_config_word(pdev, dvsec + offset, ctrl); if (rc) { -- 2.43.7 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields 2026-09-22 10:00 ` [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields Guixin Liu @ 2026-09-25 23:44 ` Jonathan Cameron 2026-10-08 3:15 ` Guixin Liu 0 siblings, 1 reply; 10+ messages in thread From: Jonathan Cameron @ 2026-09-25 23:44 UTC (permalink / raw) To: Guixin Liu Cc: Davidlohr Bueso, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming, linux-cxl On Tue, 22 Sep 2026 18:00:13 +0800 Guixin Liu <kanie@linux.alibaba.com> wrote: > update_gpf_port_dvsec() rebuilds the phase control register from just > the timeout base and scale, so the rest of the register is cleared by > the write. The other bits are reserved today and nothing is lost, but > the full-register rewrite would clobber any field the spec defines > there later. > > Read-modify-write the register and change only the two timeout > fields. > > Fixes: a52b6a2c1c99 ("cxl/pci: Support Global Persistent Flush (GPF)") > Assisted-by: LLM > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> > --- > drivers/cxl/core/pci.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c > index 1f470ab0df3b..72e54facafe8 100644 > --- a/drivers/cxl/core/pci.c > +++ b/drivers/cxl/core/pci.c > @@ -846,8 +846,9 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) > FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX) > return 0; > > - ctrl = FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX); > - ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); > + ctrl &= ~(base | scale); > + ctrl |= FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX) | > + FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); I think a little nicer if you use a pair of FIELD_MODIFY() and let the compiler figure out that it can combine things. > > rc = pci_write_config_word(pdev, dvsec + offset, ctrl); > if (rc) { ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields 2026-09-25 23:44 ` Jonathan Cameron @ 2026-10-08 3:15 ` Guixin Liu 0 siblings, 0 replies; 10+ messages in thread From: Guixin Liu @ 2026-10-08 3:15 UTC (permalink / raw) To: Jonathan Cameron Cc: Davidlohr Bueso, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming, linux-cxl 在 2026/9/26 07:44, Jonathan Cameron 写道: > On Tue, 22 Sep 2026 18:00:13 +0800 > Guixin Liu <kanie@linux.alibaba.com> wrote: > >> update_gpf_port_dvsec() rebuilds the phase control register from just >> the timeout base and scale, so the rest of the register is cleared by >> the write. The other bits are reserved today and nothing is lost, but >> the full-register rewrite would clobber any field the spec defines >> there later. >> >> Read-modify-write the register and change only the two timeout >> fields. >> >> Fixes: a52b6a2c1c99 ("cxl/pci: Support Global Persistent Flush (GPF)") >> Assisted-by: LLM >> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> >> --- >> drivers/cxl/core/pci.c | 5 +++-- >> 1 file changed, 3 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c >> index 1f470ab0df3b..72e54facafe8 100644 >> --- a/drivers/cxl/core/pci.c >> +++ b/drivers/cxl/core/pci.c >> @@ -846,8 +846,9 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) >> FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX) >> return 0; >> >> - ctrl = FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX); >> - ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); >> + ctrl &= ~(base | scale); >> + ctrl |= FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX) | >> + FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX); > I think a little nicer if you use a pair of FIELD_MODIFY() and let > the compiler figure out that it can combine things. Sure, changed in v2 thanks. Best Regards, Guixin Liu >> >> rc = pci_write_config_word(pdev, dvsec + offset, ctrl); >> if (rc) { ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-10-08 3:20 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-22 10:00 [PATCH 0/3] cxl/pci: Fix the GPF DVSEC setup path Guixin Liu 2026-09-22 10:00 ` [PATCH 1/3] cxl/pci: Use the Device GPF DVSEC for restricted endpoints Guixin Liu 2026-09-25 23:36 ` Jonathan Cameron 2026-09-28 23:45 ` Dave Jiang 2026-09-22 10:00 ` [PATCH 2/3] cxl/pci: Program the Port GPF timeouts before caching the DVSEC Guixin Liu 2026-09-25 23:43 ` Jonathan Cameron 2026-09-28 23:46 ` Dave Jiang 2026-09-22 10:00 ` [PATCH 3/3] cxl/pci: Update only the Port GPF timeout fields Guixin Liu 2026-09-25 23:44 ` Jonathan Cameron 2026-10-08 3:15 ` Guixin Liu
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.