* [PATCH v18 04/13] cxl: Rename find_cxl_port() to find_cxl_port_by_dport()
From: Terry Bowman @ 2026-07-17 22:26 UTC (permalink / raw)
To: Bjorn Helgaas, Dan Williams, Dave Jiang, Ira Weiny,
Jonathan Cameron, Len Brown, Rafael J . Wysocki, Robert Richter
Cc: linux-acpi, linux-cxl, linux-doc, linux-kernel, linux-pci,
linuxppc-dev, Alejandro Lucero, Alison Schofield, Ankit Agrawal,
Ard Biesheuvel, Ben Cheatham, Borislav Petkov, Breno Leitao,
Davidlohr Bueso, Fabio M . De Francesco, Gregory Price,
Hanjun Guo, Jonathan Corbet, Kees Cook,
Kuppuswamy Sathyanarayanan, Li Ming, Mahesh J Salgaonkar,
Mauro Carvalho Chehab, Oliver O'Halloran, Shiju Jose,
Shuah Khan, Shuai Xue, Smita Koralahalli, Terry Bowman, Tony Luck,
Vishal Verma
In-Reply-To: <20260717222706.3540281-1-terry.bowman@amd.com>
From: Dan Williams <djbw@kernel.org>
find_cxl_port() and find_cxl_port_by_uport() are internal port lookup
functions that search the CXL bus by dport and uport respectively, but
their names do not make the lookup method clear.
Rename find_cxl_port() to find_cxl_port_by_dport() to make the lookup
method explicit and consistent with find_cxl_port_by_uport(). Both
functions remain static to port.c; the upcoming patch that adds the
first cross-file caller will widen their scope.
Co-developed-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Dan Williams <djbw@kernel.org>
---
Changes in v17 -> v18:
- New commit
---
drivers/cxl/core/port.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index f90f899c31d07..cadb51f70f854 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1379,7 +1379,7 @@ static int match_port_by_dport(struct device *dev, const void *data)
return dport != NULL;
}
-static struct cxl_port *__find_cxl_port(struct cxl_find_port_ctx *ctx)
+static struct cxl_port *__find_cxl_port_by_dport(struct cxl_find_port_ctx *ctx)
{
struct device *dev;
@@ -1392,8 +1392,16 @@ static struct cxl_port *__find_cxl_port(struct cxl_find_port_ctx *ctx)
return NULL;
}
-static struct cxl_port *find_cxl_port(struct device *dport_dev,
- struct cxl_dport **dport)
+/**
+ * find_cxl_port_by_dport - find a cxl_port by one of its targets
+ * @dport_dev: device representing the dport target
+ * @dport: optional output of the 'struct cxl_dport' companion of the @dport_dev
+ *
+ * Return a 'struct cxl_port' with an elevated reference if found. Use
+ * __free(put_cxl_port) to release.
+ */
+static struct cxl_port *find_cxl_port_by_dport(struct device *dport_dev,
+ struct cxl_dport **dport)
{
struct cxl_find_port_ctx ctx = {
.dport_dev = dport_dev,
@@ -1401,7 +1409,7 @@ static struct cxl_port *find_cxl_port(struct device *dport_dev,
};
struct cxl_port *port;
- port = __find_cxl_port(&ctx);
+ port = __find_cxl_port_by_dport(&ctx);
return port;
}
@@ -1895,14 +1903,14 @@ EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_ports, "CXL");
struct cxl_port *cxl_pci_find_port(struct pci_dev *pdev,
struct cxl_dport **dport)
{
- return find_cxl_port(pdev->dev.parent, dport);
+ return find_cxl_port_by_dport(pdev->dev.parent, dport);
}
EXPORT_SYMBOL_NS_GPL(cxl_pci_find_port, "CXL");
struct cxl_port *cxl_mem_find_port(struct cxl_memdev *cxlmd,
struct cxl_dport **dport)
{
- return find_cxl_port(grandparent(&cxlmd->dev), dport);
+ return find_cxl_port_by_dport(grandparent(&cxlmd->dev), dport);
}
EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, "CXL");
--
2.34.1
^ permalink raw reply related
* [PATCH v18 03/13] cxl: Tighten CPER kfifo registration API and symbol visibility
From: Terry Bowman @ 2026-07-17 22:26 UTC (permalink / raw)
To: Bjorn Helgaas, Dan Williams, Dave Jiang, Ira Weiny,
Jonathan Cameron, Len Brown, Rafael J . Wysocki, Robert Richter
Cc: linux-acpi, linux-cxl, linux-doc, linux-kernel, linux-pci,
linuxppc-dev, Alejandro Lucero, Alison Schofield, Ankit Agrawal,
Ard Biesheuvel, Ben Cheatham, Borislav Petkov, Breno Leitao,
Davidlohr Bueso, Fabio M . De Francesco, Gregory Price,
Hanjun Guo, Jonathan Corbet, Kees Cook,
Kuppuswamy Sathyanarayanan, Li Ming, Mahesh J Salgaonkar,
Mauro Carvalho Chehab, Oliver O'Halloran, Shiju Jose,
Shuah Khan, Shuai Xue, Smita Koralahalli, Terry Bowman, Tony Luck,
Vishal Verma
In-Reply-To: <20260717222706.3540281-1-terry.bowman@amd.com>
From: Dan Williams <djbw@kernel.org>
Tighten the CPER protocol error kfifo registration API and symbol
visibility.
Use EXPORT_SYMBOL_FOR_MODULES() instead of EXPORT_SYMBOL_NS_GPL() for
the CPER kfifo registration symbols. This names the consuming module
explicitly and gives compile-time enforcement.
Drop the work_struct argument from the unregister path. Change the
WARN_ONCE condition to a NULL check since there is no caller pointer
to compare against anymore.
Change register/unregister return types to void. Flag double registration
with WARN_ONCE() inside the lock instead of returning an error.
Change cxl_ras_init() to void because there is one consumer and one producer
so the error return was unnecessary. Remove the now-dead error check in
cxl_core_init().
Add a diagnostic log when the driver is not bound in
cxl_cper_handle_prot_err().
Co-developed-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Dan Williams <djbw@kernel.org>
---
Changes in v17 -> v18:
- New patch.
---
drivers/acpi/apei/ghes.c | 32 +++++++++++++++-----------------
drivers/cxl/core/core.h | 7 ++-----
drivers/cxl/core/port.c | 6 +-----
drivers/cxl/core/ras.c | 12 +++++++-----
include/cxl/event.h | 17 ++++++-----------
5 files changed, 31 insertions(+), 43 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index ca7a138c1ff2e..187f54e31c33e 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -778,41 +778,41 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
#endif
}
-int cxl_cper_register_prot_err_work(struct work_struct *work)
+void cxl_cper_register_prot_err_work(struct work_struct *work)
{
guard(raw_spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
if (WARN_ONCE(cxl_cper_prot_err_work,
"CPER-CXL kfifo consumer already registered\n"))
- return -EINVAL;
+ return;
cxl_cper_prot_err_work = work;
- return 0;
}
-EXPORT_SYMBOL_NS_GPL(cxl_cper_register_prot_err_work, "CXL");
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_register_prot_err_work, "cxl_core");
-int cxl_cper_unregister_prot_err_work(struct work_struct *work)
+void cxl_cper_unregister_prot_err_work(void)
{
+ struct work_struct *old;
+
scoped_guard(raw_spinlock_irqsave, &cxl_cper_prot_err_work_lock) {
- if (WARN_ONCE(cxl_cper_prot_err_work != work,
- "CPER-CXL kfifo consumer mismatch on unregister\n"))
- return -EINVAL;
+ WARN_ONCE(!cxl_cper_prot_err_work,
+ "CPER-CXL kfifo consumer not registered on unregister\n");
+ old = cxl_cper_prot_err_work;
cxl_cper_prot_err_work = NULL;
}
- cancel_work_sync(work);
+ if (old)
+ cancel_work_sync(old);
/* Discard stale entries so they are not replayed on next module load */
kfifo_reset(&cxl_cper_prot_err_fifo);
-
- return 0;
}
-EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_prot_err_work, "CXL");
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_unregister_prot_err_work, "cxl_core");
int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
{
return kfifo_get(&cxl_cper_prot_err_fifo, wd);
}
-EXPORT_SYMBOL_NS_GPL(cxl_cper_prot_err_kfifo_get, "CXL");
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_prot_err_kfifo_get, "cxl_core");
/* Room for 8 entries for each of the 4 event log queues */
#define CXL_CPER_FIFO_DEPTH 32
@@ -867,12 +867,12 @@ int cxl_cper_register_work(struct work_struct *work)
}
EXPORT_SYMBOL_NS_GPL(cxl_cper_register_work, "CXL");
-int cxl_cper_unregister_work(struct work_struct *work)
+void cxl_cper_unregister_work(struct work_struct *work)
{
scoped_guard(raw_spinlock_irqsave, &cxl_cper_work_lock) {
if (WARN_ONCE(cxl_cper_work != work,
"CXL CPER kfifo consumer mismatch on unregister\n"))
- return -EINVAL;
+ return;
cxl_cper_work = NULL;
}
@@ -880,8 +880,6 @@ int cxl_cper_unregister_work(struct work_struct *work)
/* Discard stale entries so they are not replayed on next module load */
kfifo_reset(&cxl_cper_fifo);
-
- return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_work, "CXL");
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 07555ae638594..23fe40ddf4c6b 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -183,7 +183,7 @@ static inline struct device *dport_to_host(struct cxl_dport *dport)
return &port->dev;
}
#ifdef CONFIG_CXL_RAS
-int cxl_ras_init(void);
+void cxl_ras_init(void);
void cxl_ras_exit(void);
bool cxl_handle_ras(struct device *dev, void __iomem *ras_base);
void cxl_handle_cor_ras(struct device *dev, void __iomem *ras_base);
@@ -192,10 +192,7 @@ void cxl_disable_rch_root_ints(struct cxl_dport *dport);
void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds);
void devm_cxl_dport_ras_setup(struct cxl_dport *dport);
#else
-static inline int cxl_ras_init(void)
-{
- return 0;
-}
+static inline void cxl_ras_init(void) { }
static inline void cxl_ras_exit(void) { }
static inline bool cxl_handle_ras(struct device *dev, void __iomem *ras_base)
{
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 1215ee4f40351..f90f899c31d07 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -2531,14 +2531,10 @@ static __init int cxl_core_init(void)
if (rc)
goto err_region;
- rc = cxl_ras_init();
- if (rc)
- goto err_ras;
+ cxl_ras_init();
return 0;
-err_ras:
- cxl_region_exit();
err_region:
bus_unregister(&cxl_bus_type);
err_bus:
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 99fb00949c2fa..135f1997e6f4f 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -104,8 +104,11 @@ void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
}
guard(device)(&pdev->dev);
- if (!pdev->dev.driver)
+ if (!pdev->dev.driver) {
+ dev_warn_ratelimited(&pdev->dev,
+ "Device is unbound, abort CPER error handling\n");
return;
+ }
struct device *mem_dev __free(put_device) = bus_find_device(
&cxl_bus_type, NULL, pdev, match_memdev_by_parent);
@@ -129,15 +132,14 @@ static void cxl_cper_prot_err_work_fn(struct work_struct *work)
}
static DECLARE_WORK(cxl_cper_prot_err_work, cxl_cper_prot_err_work_fn);
-int cxl_ras_init(void)
+void cxl_ras_init(void)
{
- return cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
+ cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
}
void cxl_ras_exit(void)
{
- cxl_cper_unregister_prot_err_work(&cxl_cper_prot_err_work);
- cancel_work_sync(&cxl_cper_prot_err_work);
+ cxl_cper_unregister_prot_err_work();
}
static void cxl_dport_map_ras(struct cxl_dport *dport)
diff --git a/include/cxl/event.h b/include/cxl/event.h
index ff97fea718d2c..3471d4f75c025 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -287,10 +287,10 @@ struct cxl_cper_prot_err_work_data {
#ifdef CONFIG_ACPI_APEI_GHES
int cxl_cper_register_work(struct work_struct *work);
-int cxl_cper_unregister_work(struct work_struct *work);
+void cxl_cper_unregister_work(struct work_struct *work);
int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd);
-int cxl_cper_register_prot_err_work(struct work_struct *work);
-int cxl_cper_unregister_prot_err_work(struct work_struct *work);
+void cxl_cper_register_prot_err_work(struct work_struct *work);
+void cxl_cper_unregister_prot_err_work(void);
int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd);
#else
static inline int cxl_cper_register_work(struct work_struct *work)
@@ -298,21 +298,16 @@ static inline int cxl_cper_register_work(struct work_struct *work)
return 0;
}
-static inline int cxl_cper_unregister_work(struct work_struct *work)
-{
- return 0;
-}
+static inline void cxl_cper_unregister_work(struct work_struct *work) { }
static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
{
return 0;
}
-static inline int cxl_cper_register_prot_err_work(struct work_struct *work)
+static inline void cxl_cper_register_prot_err_work(struct work_struct *work)
{
- return 0;
}
-static inline int cxl_cper_unregister_prot_err_work(struct work_struct *work)
+static inline void cxl_cper_unregister_prot_err_work(void)
{
- return 0;
}
static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
{
--
2.34.1
^ permalink raw reply related
* [PATCH v18 02/13] acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks
From: Terry Bowman @ 2026-07-17 22:26 UTC (permalink / raw)
To: Bjorn Helgaas, Dan Williams, Dave Jiang, Ira Weiny,
Jonathan Cameron, Len Brown, Rafael J . Wysocki, Robert Richter
Cc: linux-acpi, linux-cxl, linux-doc, linux-kernel, linux-pci,
linuxppc-dev, Alejandro Lucero, Alison Schofield, Ankit Agrawal,
Ard Biesheuvel, Ben Cheatham, Borislav Petkov, Breno Leitao,
Davidlohr Bueso, Fabio M . De Francesco, Gregory Price,
Hanjun Guo, Jonathan Corbet, Kees Cook,
Kuppuswamy Sathyanarayanan, Li Ming, Mahesh J Salgaonkar,
Mauro Carvalho Chehab, Oliver O'Halloran, Shiju Jose,
Shuah Khan, Shuai Xue, Smita Koralahalli, Terry Bowman, Tony Luck,
Vishal Verma
In-Reply-To: <20260717222706.3540281-1-terry.bowman@amd.com>
The CXL CPER work registration and unregistration helpers in
drivers/acpi/apei/ghes.c acquire cxl_cper_work_lock and
cxl_cper_prot_err_work_lock with guard(spinlock), which leaves local
interrupts enabled. The corresponding post paths
(cxl_cper_post_event(), cxl_cper_post_prot_err()) execute in hard IRQ
context (they are called from the GHES error notification path) and
acquire the same locks via guard(spinlock_irqsave).
If a CPU is holding one of these locks via guard(spinlock) when a
GHES interrupt arrives on the same CPU, the IRQ handler spins on the
held lock waiting for it to release, while the lock holder is
preempted by the IRQ. The result is a deadlock.
Convert both locks from spinlock_t to raw_spinlock_t and use
guard(raw_spinlock_irqsave) at all call sites. On PREEMPT_RT kernels
spinlock_t is backed by rt_mutex and sleeping from hard IRQ context is
not permitted; raw_spinlock_t is safe in both contexts.
Add WARN_ONCE to both register functions to surface double-registration
bugs at runtime.
Restructure both unregister functions to clear the global work pointer
under the lock before calling cancel_work_sync(), closing the window
where a CPER interrupt could schedule work on a pointer about to be
freed. Add kfifo_reset() after cancel_work_sync() so stale entries
are not replayed on next module load.
Both kfifos are single-consumer: only one work_struct is registered at
a time, enforced by the WARN_ONCE guard in the register functions.
kfifo_reset() is safe outside the lock because cancel_work_sync() has
already quiesced the consumer, and no new consumer can register until
the current module exit completes and a fresh module init runs.
Remove the now-redundant cancel_work_sync() call from
cxl_pci_driver_exit() - cxl_cper_unregister_work() handles quiescing
internally.
Reported-by: Sashiko <sashiko@linuxfoundation.org>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Fixes: 5e4a264bf8b5 ("acpi/ghes: Process CXL Component Events")
Fixes: 36f257e3b0ba ("acpi/ghes, cxl/pci: Process CXL CPER Protocol Errors")
Cc: stable@vger.kernel.org
---
Changes in v17 -> v18:
- New patch.
---
drivers/acpi/apei/ghes.c | 50 ++++++++++++++++++++++++++--------------
drivers/cxl/pci.c | 1 -
2 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 3236a3ce79d6b..ca7a138c1ff2e 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -749,7 +749,7 @@ static DEFINE_KFIFO(cxl_cper_prot_err_fifo, struct cxl_cper_prot_err_work_data,
CXL_CPER_PROT_ERR_FIFO_DEPTH);
/* Synchronize schedule_work() with cxl_cper_prot_err_work changes */
-static DEFINE_SPINLOCK(cxl_cper_prot_err_work_lock);
+static DEFINE_RAW_SPINLOCK(cxl_cper_prot_err_work_lock);
struct work_struct *cxl_cper_prot_err_work;
static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
@@ -761,7 +761,7 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
if (cxl_cper_sec_prot_err_valid(prot_err))
return;
- guard(spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
+ guard(raw_spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
if (!cxl_cper_prot_err_work)
return;
@@ -780,10 +780,11 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
int cxl_cper_register_prot_err_work(struct work_struct *work)
{
- if (cxl_cper_prot_err_work)
- return -EINVAL;
+ guard(raw_spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
- guard(spinlock)(&cxl_cper_prot_err_work_lock);
+ if (WARN_ONCE(cxl_cper_prot_err_work,
+ "CPER-CXL kfifo consumer already registered\n"))
+ return -EINVAL;
cxl_cper_prot_err_work = work;
return 0;
}
@@ -791,11 +792,18 @@ EXPORT_SYMBOL_NS_GPL(cxl_cper_register_prot_err_work, "CXL");
int cxl_cper_unregister_prot_err_work(struct work_struct *work)
{
- if (cxl_cper_prot_err_work != work)
- return -EINVAL;
+ scoped_guard(raw_spinlock_irqsave, &cxl_cper_prot_err_work_lock) {
+ if (WARN_ONCE(cxl_cper_prot_err_work != work,
+ "CPER-CXL kfifo consumer mismatch on unregister\n"))
+ return -EINVAL;
+ cxl_cper_prot_err_work = NULL;
+ }
+
+ cancel_work_sync(work);
+
+ /* Discard stale entries so they are not replayed on next module load */
+ kfifo_reset(&cxl_cper_prot_err_fifo);
- guard(spinlock)(&cxl_cper_prot_err_work_lock);
- cxl_cper_prot_err_work = NULL;
return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_prot_err_work, "CXL");
@@ -811,7 +819,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_cper_prot_err_kfifo_get, "CXL");
DEFINE_KFIFO(cxl_cper_fifo, struct cxl_cper_work_data, CXL_CPER_FIFO_DEPTH);
/* Synchronize schedule_work() with cxl_cper_work changes */
-static DEFINE_SPINLOCK(cxl_cper_work_lock);
+static DEFINE_RAW_SPINLOCK(cxl_cper_work_lock);
struct work_struct *cxl_cper_work;
static void cxl_cper_post_event(enum cxl_event_type event_type,
@@ -831,7 +839,7 @@ static void cxl_cper_post_event(enum cxl_event_type event_type,
return;
}
- guard(spinlock_irqsave)(&cxl_cper_work_lock);
+ guard(raw_spinlock_irqsave)(&cxl_cper_work_lock);
if (!cxl_cper_work)
return;
@@ -849,10 +857,11 @@ static void cxl_cper_post_event(enum cxl_event_type event_type,
int cxl_cper_register_work(struct work_struct *work)
{
- if (cxl_cper_work)
+ guard(raw_spinlock_irqsave)(&cxl_cper_work_lock);
+ if (WARN_ONCE(cxl_cper_work,
+ "CXL CPER kfifo consumer already registered\n"))
return -EINVAL;
- guard(spinlock)(&cxl_cper_work_lock);
cxl_cper_work = work;
return 0;
}
@@ -860,11 +869,18 @@ EXPORT_SYMBOL_NS_GPL(cxl_cper_register_work, "CXL");
int cxl_cper_unregister_work(struct work_struct *work)
{
- if (cxl_cper_work != work)
- return -EINVAL;
+ scoped_guard(raw_spinlock_irqsave, &cxl_cper_work_lock) {
+ if (WARN_ONCE(cxl_cper_work != work,
+ "CXL CPER kfifo consumer mismatch on unregister\n"))
+ return -EINVAL;
+ cxl_cper_work = NULL;
+ }
+
+ cancel_work_sync(work);
+
+ /* Discard stale entries so they are not replayed on next module load */
+ kfifo_reset(&cxl_cper_fifo);
- guard(spinlock)(&cxl_cper_work_lock);
- cxl_cper_work = NULL;
return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_work, "CXL");
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 267c679b0b3c2..7c6faee7f85ed 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1083,7 +1083,6 @@ static int __init cxl_pci_driver_init(void)
static void __exit cxl_pci_driver_exit(void)
{
cxl_cper_unregister_work(&cxl_cper_work);
- cancel_work_sync(&cxl_cper_work);
pci_unregister_driver(&cxl_pci_driver);
}
--
2.34.1
^ permalink raw reply related
* [PATCH v18 01/13] cxl/ras: Fix cxl_rch_get_aer_severity() wrong severity register
From: Terry Bowman @ 2026-07-17 22:26 UTC (permalink / raw)
To: Bjorn Helgaas, Dan Williams, Dave Jiang, Ira Weiny,
Jonathan Cameron, Len Brown, Rafael J . Wysocki, Robert Richter
Cc: linux-acpi, linux-cxl, linux-doc, linux-kernel, linux-pci,
linuxppc-dev, Alejandro Lucero, Alison Schofield, Ankit Agrawal,
Ard Biesheuvel, Ben Cheatham, Borislav Petkov, Breno Leitao,
Davidlohr Bueso, Fabio M . De Francesco, Gregory Price,
Hanjun Guo, Jonathan Corbet, Kees Cook,
Kuppuswamy Sathyanarayanan, Li Ming, Mahesh J Salgaonkar,
Mauro Carvalho Chehab, Oliver O'Halloran, Shiju Jose,
Shuah Khan, Shuai Xue, Smita Koralahalli, Terry Bowman, Tony Luck,
Vishal Verma
In-Reply-To: <20260717222706.3540281-1-terry.bowman@amd.com>
cxl_rch_get_aer_severity() classifies RCH Downstream Port uncorrectable
errors as fatal or non-fatal by ANDing uncorrectable status with
PCI_ERR_ROOT_FATAL_RCV. This is wrong because PCI_ERR_ROOT_FATAL_RCV is a
Root Error Status register bit (bit 6), not a severity bit. ANDing it
against uncorrectable status tests a reserved bit and produces incorrect
severity classification.
Fix by ANDing the unmasked uncor_status against uncor_severity. Per
PCIe Base Spec r6.0 Section 7.8.4.4, each bit in the Uncorrectable
Error Severity register indicates whether the corresponding error is
fatal (1) or non-fatal (0).
Fixes: 6ac07883dbb5 ("cxl/pci: Add RCH downstream port error logging")
Cc: stable@vger.kernel.org
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v17 -> v18:
- New patch.
---
drivers/cxl/core/ras_rch.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/cxl/core/ras_rch.c b/drivers/cxl/core/ras_rch.c
index 0a8b3b9b63884..44b335d560708 100644
--- a/drivers/cxl/core/ras_rch.c
+++ b/drivers/cxl/core/ras_rch.c
@@ -80,7 +80,8 @@ static bool cxl_rch_get_aer_severity(struct aer_capability_regs *aer_regs,
int *severity)
{
if (aer_regs->uncor_status & ~aer_regs->uncor_mask) {
- if (aer_regs->uncor_status & PCI_ERR_ROOT_FATAL_RCV)
+ if ((aer_regs->uncor_status & ~aer_regs->uncor_mask) &
+ aer_regs->uncor_severity)
*severity = AER_FATAL;
else
*severity = AER_NONFATAL;
--
2.34.1
^ permalink raw reply related
* [PATCH v18 00/13] Enable CXL PCIe Port Protocol Error handling and logging
From: Terry Bowman @ 2026-07-17 22:26 UTC (permalink / raw)
To: Bjorn Helgaas, Dan Williams, Dave Jiang, Ira Weiny,
Jonathan Cameron, Len Brown, Rafael J . Wysocki, Robert Richter
Cc: linux-acpi, linux-cxl, linux-doc, linux-kernel, linux-pci,
linuxppc-dev, Alejandro Lucero, Alison Schofield, Ankit Agrawal,
Ard Biesheuvel, Ben Cheatham, Borislav Petkov, Breno Leitao,
Davidlohr Bueso, Fabio M . De Francesco, Gregory Price,
Hanjun Guo, Jonathan Corbet, Kees Cook,
Kuppuswamy Sathyanarayanan, Li Ming, Mahesh J Salgaonkar,
Mauro Carvalho Chehab, Oliver O'Halloran, Shiju Jose,
Shuah Khan, Shuai Xue, Smita Koralahalli, Terry Bowman, Tony Luck,
Vishal Verma
This patch series enables CXL protocol error handling for both CXL Ports
and CXL Endpoints (EP). The previous revision is available at:
https://lore.kernel.org/linux-cxl/20260505173029.2718246-1-terry.bowman@amd.com/
Today the kernel handles native CXL.cachemem RAS only for Endpoints and
Restricted CXL Host (RCH) Downstream Ports. Root Ports, Upstream Switch
Ports, and Downstream Switch Ports are uncovered. This series introduces
a unified CXL protocol error path for all CXL device types, in both VH
and RCH topologies.
CXL protocol errors are layered as a distinct error plane on top of PCIe
AER. CXL RAS conditions are signaled as PCIe correctable (CE) and
uncorrectable (UCE) Internal AER Errors. The AER driver classifies these
events using pcie_is_cxl() and hands them off to cxl_core through the
AER-CXL kfifo.
The cxl_core driver dequeues each event, resolves the cxl_port topology,
and dispatches to the CE or UCE handler. RCD Endpoints are handled
slightly differently: the RCH Downstream Port's RAS state is processed
first, then the Endpoint's own RAS follows the common path.
PCIe AER errors remain a separate plane and are handled independently.
This series updates the CXL Endpoint AER UCE handler and removes the
Endpoint AER CE handler, which is now redundant since the AER driver
clears and logs CE status itself.
PCI_ERS_RESULT_PANIC, introduced in earlier revisions, has been dropped.
The panic decision is made directly in cxl_do_recovery(): the kernel
panics on any uncorrectable CXL RAS error reported by cxl_handle_ras(),
or earlier on link disconnect.
A fatal UCE on an Upstream Switch Port or Endpoint surfaces through the
AER path rather than the CXL RAS path. USP devices are bound to the PCIe
portdrv driver, so when a USP reports a fatal UCE, the PCIe error handler
provided by portdrv is invoked. PCI config reads to the source device are
expected to fail in this scenario, so the AER core never retrieves
UNCOR_STATUS, and the event cannot be classified as CXL. See the fatal
and non-fatal log excerpts for USP and EP below.
== Patch Details ==
Patch 1 - cxl/ras: Fix cxl_rch_get_aer_severity() wrong severity register
Fix RCH Downstream Port severity classification. Was using
PCI_ERR_ROOT_FATAL_RCV (a Root Error Status bit) instead of uncor_severity
to classify fatal vs non-fatal.
Patch 2 - acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks
Convert cxl_cper_work_lock and cxl_cper_prot_err_work_lock from spinlock_t
to raw_spinlock_t to avoid sleeping-in-hardirq deadlock on PREEMPT_RT kernels.
Patch 3 - cxl: Tighten CPER kfifo registration API and symbol visibility
Replace EXPORT_SYMBOL_NS_GPL() with EXPORT_SYMBOL_FOR_MODULES() for CPER
kfifo helpers. Simplify register/unregister return types to void.
Patch 4 - cxl: Rename find_cxl_port() to find_cxl_port_by_dport()
Renames find_cxl_port() to find_cxl_port_by_dport() to make the lookup
method explicit and consistent with the existing find_cxl_port_by_uport().
Patch 5 - PCI/AER: Introduce AER-CXL protocol error kfifo
Adds the AER-CXL kfifo in drivers/pci/pcie/aer_cxl_vh.c along with the
producer helper cxl_forward_error() and the consumer registration helpers
cxl_register_proto_err_work() and cxl_unregister_proto_err_work(). The
kfifo delivers CXL VH protocol errors from the AER driver to cxl_core.
Patch 6 - PCI: Establish common CXL Port protocol error flow
Dequeues work from the AER-CXL kfifo and establishes a common flow for all
CXL Port protocol error handling. Panics on any uncorrectable CXL RAS
error. The producer dispatch and consumer go live atomically.
Patch 7 - PCI/CXL: Add RCH support to CXL handlers
Folds Restricted CXL Host (RCH) error handling into the common Port flow. An
RCD uncorrectable CXL RAS error now panics, matching the policy applied to
all other CXL devices.
Patch 8 - cxl/pci: Thread port and dport through RAS handling helpers
Refactors cxl_handle_ras() and cxl_handle_cor_ras() to accept struct
cxl_port * and struct cxl_dport * directly, eliminating redundant bus walks on
the error path.
Patch 9 - cxl: Update CXL Endpoint AER handler
Replaces cxl_error_detected() with cxl_pci_error_detected(). Reads CXL RAS
unconditionally; panics on UCE regardless of channel state.
Patch 10 - cxl: Add port and dport identifiers to CXL AER trace events
Passes struct cxl_port * and struct cxl_dport * to trace events. Adds new
"port" and "dport" string fields for all CXL device classes.
Patch 11 - PCI: Cache PCI DSN into pci_dev->dsn during probe
Caches the PCI Device Serial Number at probe time so error handlers and
panic paths avoid live config-space reads.
Patch 12 - PCI/CXL: Mask/Unmask CXL protocol errors
Enables CXL Internal Error reporting on CXL Ports and Endpoints. The unmask
is paired with RAS register block mapping; the mask is registered as a devres
action.
Patch 13 - Documentation: cxl: Document CXL protocol error handling
Adds protocol-error-handling.rst describing the end-to-end CXL protocol
error path.
== Notes ==
- @Bjorn, I kindly request your review for the following patches. Many
of the changes are to CXL-specific files in the PCI tree:
Patch 5 - PCI/AER: Introduce AER-CXL protocol error kfifo
Patch 6 - PCI: Establish common CXL Port protocol error flow
Patch 7 - PCI/CXL: Add RCH support to CXL handlers
Patch 11 - PCI: Cache PCI DSN into pci_dev->dsn during probe
Patch 12 - PCI/CXL: Mask/Unmask CXL protocol errors
- USP/EP fatal UCE follows the AER path because of how the AER core collects
status. aer_get_device_error_info() only reads PCI_ERR_UNCOR_STATUS for
Root Ports/RCECs/Downstream Ports or non-fatal severities, where config
reads to the source are still expected to succeed. For a fatal UCE
signaled by an upstream component, config reads to that device are
expected to fail, so UNCOR_STATUS is never retrieved. Without the status
word, is_cxl_error() cannot classify the event as CXL and the AER path
handles it.
- Dan's related series addressing RAS setup has more details:
https://lore.kernel.org/linux-cxl/20260131000403.2135324-1-dan.j.williams@intel.com/
- TODOs for future series:
- Move aer_cxl_rch.c to cxl/core/ras_rch.c
- Move RCH traversing for handling from AER driver into CXL driver
- Support user-defined status masks
- Add CXL Port traversing in cxl_do_recovery()
== Testing ==
Testing included the following:
- cxl-test
- RCH/RCD AER error injection
- CPER GHES (firmware first)
- VH AER error injection
** The AER error injection is not included in this series but will be posted
as an RFC for review and for others to use. The error injection using AER
will be posted separately as ("cxl: Device protocol AER injection").
Below are the testing results.
=== cxl_test ===
The cxl_test CXL testsuite passed on QEMU with no issues.
This required changes in patch 12 ("PCI/CXL: Mask/Unmask CXL protocol errors").
__wrap_devm_cxl_dport_rch_ras_setup() is introduced to prevent cxl_test from
trying to map the RCH AER/RAS registers.
=== CPER Tests ===
CPER/firmware first error injection was run and passed on real HW using AMD
RAS tool for protocol error injection at the CXL Root Port.
==== Restricted CXL Host (RCH) ====
Error injection tests for RCH devices were run using CXL2.0 Endpoint that enumerate
as a RCiEP.
echo "0000:7f:00.0 CE 00000000 00000002 RCH" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:40:00.3: aer_inject: Injecting errors 00004000/00000000 into device 0000:40:00.3
pcieport 0000:40:00.3: AER: Correctable error message received from 0000:40:00.3
pcieport 0000:40:00.3: PCIe Bus Error: severity=Correctable, type=Transaction Layer, (Receiver ID)
pcieport 0000:40:00.3: device [1022:14a6] error status/mask=00004000/00002000
pcieport 0000:40:00.3: [14] CorrIntErr
cxl_aer_correctable_error: memdev= port=root0 dport=pci0000:7f host=ACPI0017:00 serial=0: status: 'Memory Data ECC Error'
echo "0000:7f:00.0 UCE 00000000 00000002 RCH" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:40:00.3: aer_inject: Injecting errors 00000000/00400000 into device 0000:40:00.3
pcieport 0000:40:00.3: AER: Uncorrectable (Non-Fatal) error message received from 0000:40:00.3
pcieport 0000:40:00.3: PCIe Bus Error: severity=Uncorrectable (Non-Fatal), type=Transaction Layer, (Receiver ID)
pcieport 0000:40:00.3: device [1022:14a6] error status/mask=00400000/00000000
pcieport 0000:40:00.3: [22] UncorrIntErr
cxl_aer_uncorrectable_error: memdev= port=root0 dport=pci0000:7f host=ACPI0017:00 serial=0: status: 'Cache Address Parity Error' first_error: 'Cache Address Parity Error'
Kernel panic - not syncing: CXL cachemem error
CPU: 26 UID: 0 PID: 396 Comm: kworker/26:1 Kdump: loaded Not tainted 7.2.0-rc3-tb-00014-g6346be30306a #1363 PREEMPT(lazy)
Hardware name: AMD Corporation ONYX/ONYX, BIOS TOX100HB 12/03/2025
Workqueue: events cxl_proto_err_work_fn [cxl_core]
Call Trace:
<TASK>
vpanic+0x453/0x4b0
panic+0x56/0x60
cxl_do_recovery+0x66/0x70 [cxl_core]
cxl_handle_rdport_errors+0x176/0x190 [cxl_core]
? srso_alias_return_thunk+0x5/0xfbef5
? update_load_avg+0x5c/0x2b0
? srso_alias_return_thunk+0x5/0xfbef5
? dequeue_entities+0x160/0xb40
? srso_alias_return_thunk+0x5/0xfbef5
? pick_task_fair+0x164/0x670
? __pfx___cxl_proto_err_work_fn+0x10/0x10 [cxl_core]
__cxl_proto_err_work_fn+0xea/0x1b0 [cxl_core]
? __pfx___cxl_proto_err_work_fn+0x10/0x10 [cxl_core]
for_each_cxl_proto_err+0x5a/0x80
cxl_proto_err_work_fn+0x26/0x50 [cxl_core]
process_one_work+0x16e/0x3a0
worker_thread+0x172/0x2e0
? __pfx_worker_thread+0x10/0x10
kthread+0xe5/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x1bd/0x220
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
==== Restricted CXL Device (RCD) ====
Error injection tests for RCD devices were run using CXL2.0 Endpoint that enumerate
as a RCiEP.
echo "0000:7f:00.0 CE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:40:00.3: aer_inject: Injecting errors 00004000/00000000 into device 0000:40:00.3
pcieport 0000:40:00.3: AER: Correctable error message received from 0000:40:00.3
pcieport 0000:40:00.3: PCIe Bus Error: severity=Correctable, type=Transaction Layer, (Receiver ID)
pcieport 0000:40:00.3: device [1022:14a6] error status/mask=00004000/00002000
pcieport 0000:40:00.3: [14] CorrIntErr
cxl_aer_correctable_error: memdev=mem0 port=endpoint1 dport= host=0000:7f:00.0 serial=0: status: 'Memory Data ECC Error'
echo "0000:7f:00.0 UCE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:40:00.3: aer_inject: Injecting errors 00000000/00400000 into device 0000:40:00.3
pcieport 0000:40:00.3: AER: Uncorrectable (Non-Fatal) error message received from 0000:40:00.3
pcieport 0000:40:00.3: PCIe Bus Error: severity=Uncorrectable (Non-Fatal), type=Transaction Layer, (Receiver ID)
pcieport 0000:40:00.3: device [1022:14a6] error status/mask=00400000/00000000
pcieport 0000:40:00.3: [22] UncorrIntErr
cxl_aer_uncorrectable_error: memdev=mem0 port=endpoint1 dport= host=0000:7f:00.0 serial=0: status: 'Cache Address Parity Error' first_error: 'Cache Address Parity Error'
Kernel panic - not syncing: CXL cachemem error
CPU: 26 UID: 0 PID: 394 Comm: kworker/26:1 Kdump: loaded Not tainted 7.2.0-rc3-tb-00014-g6346be30306a #1363 PREEMPT(lazy)
Hardware name: AMD Corporation ONYX/ONYX, BIOS TOX100HB 12/03/2025
Workqueue: events cxl_proto_err_work_fn [cxl_core]
Call Trace:
<TASK>
vpanic+0x453/0x4b0
panic+0x56/0x60
cxl_do_recovery+0x66/0x70 [cxl_core]
__cxl_proto_err_work_fn+0xa0/0x1b0 [cxl_core]
? __pfx___cxl_proto_err_work_fn+0x10/0x10 [cxl_core]
for_each_cxl_proto_err+0x5a/0x80
cxl_proto_err_work_fn+0x26/0x50 [cxl_core]
process_one_work+0x16e/0x3a0
worker_thread+0x172/0x2e0
? __pfx_worker_thread+0x10/0x10
kthread+0xe5/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x1bd/0x220
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
=== Virtual Hierarchy ===
Below are the VH error injection test results using QEMU with CXL AER error
injection via /sys/kernel/debug/cxl/aer_einj_inject on kernel 7.2.0-rc3 based
kernel.
The below QEMU testing uses a CXL Root Port, a CXL Upstream Switch Port, a
CXL Downstream Switch Port, and a CXL Type3 Endpoint as given below.
The sub-topology for the QEMU testing is:
---------------------
| CXL RP - 0C:00.0 |
---------------------
|
---------------------
| CXL USP - 0D:00.0 |
---------------------
|
--------------------
| CXL DSP - 0E:00.0 |
--------------------
|
---------------------
| CXL EP - 0F:00.0 |
---------------------
Error Injection Test Results Summary:
| # | Device Type | BDF | Test | Result | AER | RAS | Verdict |
|---|------------------|---------|------|-----------|-----|-----|------------------|
| 1 | Root Port | 0c:00.0 | CE | Recovered | OK | OK | PASS |
| 2 | Root Port | 0c:00.0 | UCE | Panic | OK | OK | PASS |
| 3 | Upstream Port | 0d:00.0 | CE | Recovered | OK | OK | PASS |
| 4 | Upstream Port | 0d:00.0 | UCE | Recovered | OK | -- | PASS (Known Lim) |
| 5 | Downstream Port | 0e:00.0 | CE | Recovered | OK | OK | PASS |
| 6 | Downstream Port | 0e:00.0 | UCE | Panic | OK | OK | PASS |
| 7 | Endpoint | 0f:00.0 | CE | Recovered | OK | OK | PASS |
| 8 | Endpoint | 0f:00.0 | UCE | Panic | OK | OK | PASS |
Overall: 8/8 PASS
=== Root Port - CE ===
echo "0000:0c:00.0 CE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00004000/00000000 into device 0000:0c:00.0
pcieport 0000:0c:00.0: AER: Correctable error message received from 0000:0c:00.0
pcieport 0000:0c:00.0: CXL Bus Error: severity=Correctable, type=Transaction Layer, (Receiver ID)
pcieport 0000:0c:00.0: device [8086:7075] error status/mask=00004000/0000a000
pcieport 0000:0c:00.0: [14] CorrIntErr
cxl_aer_correctable_error: memdev= port=port1 dport=0000:0c:00.0 host=pci0000:0c serial=0: status: 'Memory Data ECC Error'
=== Root Port - UCE ===
echo "0000:0c:00.0 UCE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00000000/00400000 into device 0000:0c:00.0
pcieport 0000:0c:00.0: AER: Uncorrectable (Fatal) error message received from 0000:0c:00.0
pcieport 0000:0c:00.0: CXL Bus Error: severity=Uncorrectable (Fatal), type=Transaction Layer, (Receiver ID)
pcieport 0000:0c:00.0: device [8086:7075] error status/mask=00400000/02000000
pcieport 0000:0c:00.0: [22] UncorrIntErr
cxl_aer_uncorrectable_error: memdev= port=port1 dport=0000:0c:00.0 host=pci0000:0c serial=0: status: 'Cache Address Parity Error' first_error: 'Cache Address Parity Error'
Kernel panic - not syncing: CXL cachemem error
CPU: 58 UID: 0 PID: 409 Comm: kworker/58:1 Not tainted 7.2.0-rc3-tb-00014-g23418142f421 #1291 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
Workqueue: events cxl_proto_err_work_fn [cxl_core]
Call Trace:
<TASK>
vpanic+0x453/0x4b0
panic+0x56/0x60
cxl_do_recovery+0x66/0x70 [cxl_core]
__cxl_proto_err_work_fn+0x9e/0x1b0 [cxl_core]
? __pfx___cxl_proto_err_work_fn+0x10/0x10 [cxl_core]
for_each_cxl_proto_err+0x5a/0x80
cxl_proto_err_work_fn+0x26/0x50 [cxl_core]
process_one_work+0x16e/0x3a0
worker_thread+0x172/0x2e0
? __pfx_worker_thread+0x10/0x10
kthread+0xe5/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x1bd/0x220
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Kernel Offset: disabled
---[ end Kernel panic - not syncing: CXL cachemem error ]---
=== Upstream Switch Port - CE ===
echo "0000:0d:00.0 CE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00004000/00000000 into device 0000:0d:00.0
pcieport 0000:0c:00.0: AER: Correctable error message received from 0000:0d:00.0
pcieport 0000:0d:00.0: CXL Bus Error: severity=Correctable, type=Transaction Layer, (Receiver ID)
pcieport 0000:0d:00.0: device [19e5:a128] error status/mask=00004000/0000a000
pcieport 0000:0d:00.0: [14] CorrIntErr
cxl_aer_correctable_error: memdev= port=port2 dport= host=0000:0d:00.0 serial=0: status: 'Memory Data ECC Error'
=== Upstream Switch Port - UCE (fatal - AER recovery, known limitation) ===
echo "0000:0d:00.0 UCE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00000000/00400000 into device 0000:0d:00.0
pcieport 0000:0c:00.0: AER: Uncorrectable (Fatal) error message received from 0000:0d:00.0
pcieport 0000:0d:00.0: AER: CXL Bus Error: severity=Uncorrectable (Fatal), type=Inaccessible, (Unregistered Agent ID)
cxl_pci 0000:0f:00.0: mem0: frozen state error detected, disable CXL.mem
pcieport 0000:0c:00.0: AER: Root Port link has been reset (0)
cxl_pci 0000:0f:00.0: mem0: restart CXL.mem after slot reset
cxl_pci 0000:0f:00.0: mem0: error resume successful
pcieport 0000:0c:00.0: AER: device recovery successful
=== Downstream Port - CE ===
echo "0000:0e:00.0 CE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00004000/00000000 into device 0000:0e:00.0
pcieport 0000:0c:00.0: AER: Correctable error message received from 0000:0e:00.0
pcieport 0000:0e:00.0: CXL Bus Error: severity=Correctable, type=Transaction Layer, (Receiver ID)
pcieport 0000:0e:00.0: device [19e5:a129] error status/mask=00004000/0000a000
pcieport 0000:0e:00.0: [14] CorrIntErr
cxl_aer_correctable_error: memdev= port=port2 dport=0000:0e:00.0 host=0000:0d:00.0 serial=0: status: 'Memory Data ECC Error'
=== Downstream Port - UCE ===
echo "0000:0e:00.0 UCE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00000000/00400000 into device 0000:0e:00.0
pcieport 0000:0c:00.0: AER: Uncorrectable (Fatal) error message received from 0000:0e:00.0
pcieport 0000:0e:00.0: CXL Bus Error: severity=Uncorrectable (Fatal), type=Transaction Layer, (Receiver ID)
pcieport 0000:0e:00.0: device [19e5:a129] error status/mask=00400000/02000000
pcieport 0000:0e:00.0: [22] UncorrIntErr
cxl_aer_uncorrectable_error: memdev= port=port2 dport=0000:0e:00.0 host=0000:0d:00.0 serial=0: status: 'Cache Address Parity Error' first_error: 'Cache Address Parity Error'
Kernel panic - not syncing: CXL cachemem error
CPU: 7 UID: 0 PID: 299 Comm: kworker/7:1 Not tainted 7.2.0-rc3-tb-00014-g832c50e87f10 #1364 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
Workqueue: events cxl_proto_err_work_fn [cxl_core]
Call Trace:
<TASK>
vpanic+0x453/0x4b0
panic+0x56/0x60
cxl_do_recovery+0x66/0x70 [cxl_core]
__cxl_proto_err_work_fn+0xa0/0x1b0 [cxl_core]
? __pfx___cxl_proto_err_work_fn+0x10/0x10 [cxl_core]
for_each_cxl_proto_err+0x5a/0x80
cxl_proto_err_work_fn+0x26/0x50 [cxl_core]
process_one_work+0x16e/0x3a0
worker_thread+0x172/0x2e0
? __pfx_worker_thread+0x10/0x10
kthread+0xe5/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x1bd/0x220
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Kernel Offset: disabled
---[ end Kernel panic - not syncing: CXL cachemem error ]---
=== Endpoint - CE ===
echo "0000:0f:00.0 CE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00004000/00000000 into device 0000:0f:00.0
pcieport 0000:0c:00.0: AER: Correctable error message received from 0000:0f:00.0
cxl_pci 0000:0f:00.0: CXL Bus Error: severity=Correctable, type=Transaction Layer, (Receiver ID)
cxl_pci 0000:0f:00.0: device [8086:0d93] error status/mask=00004000/0000a000
cxl_pci 0000:0f:00.0: [14] CorrIntErr
cxl_aer_correctable_error: memdev=mem1 port=endpoint4 dport= host=0000:0f:00.0 serial=0: status: 'Memory Data ECC Error'
=== Endpoint - UCE ===
echo "0000:0f:00.0 UCE 00000000 00000002" > /sys/kernel/debug/cxl/aer_einj_inject
pcieport 0000:0c:00.0: aer_inject: Injecting errors 00000000/00400000 into device 0000:0f:00.0
pcieport 0000:0c:00.0: AER: Uncorrectable (Fatal) error message received from 0000:0f:00.0
cxl_pci 0000:0f:00.0: AER: CXL Bus Error: severity=Uncorrectable (Fatal), type=Inaccessible, (Unregistered Agent ID)
cxl_aer_uncorrectable_error: memdev=mem1 port=endpoint4 dport= host=0000:0f:00.0 serial=0: status: 'Cache Address Parity Error' first_error: 'Cache Address Parity Error'
Kernel panic - not syncing: CXL cachemem error
CPU: 58 UID: 0 PID: 430 Comm: irq/24-aerdrv Not tainted 7.2.0-rc3-tb-00014-g23418142f421 #1291 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
Call Trace:
<TASK>
vpanic+0x453/0x4b0
panic+0x56/0x60
cxl_pci_error_detected+0x15c/0x160 [cxl_core]
report_error_detected+0xc7/0x1c0
? __pfx_report_frozen_detected+0x10/0x10
__pci_walk_bus+0x47/0x70
? __pfx_report_frozen_detected+0x10/0x10
pci_walk_bus+0x2c/0x40
? __pfx_aer_root_reset+0x10/0x10
pcie_do_recovery+0x234/0x330
? __pfx_irq_thread_fn+0x10/0x10
aer_isr_one_error_type+0x333/0x340
aer_isr_one_error+0x112/0x140
aer_isr+0x47/0x80
irq_thread_fn+0x1f/0x60
irq_thread+0x123/0x220
? __pfx_irq_thread_dtor+0x10/0x10
? __pfx_irq_thread+0x10/0x10
kthread+0xe5/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x1bd/0x220
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Kernel Offset: disabled
---[ end Kernel panic - not syncing: CXL cachemem error ]---
== Changes ==
Changes in v17->v18:
acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks
- New commit
- Convert cxl_cper_work_lock and cxl_cper_prot_err_work_lock from
spinlock_t to raw_spinlock_t; use guard(raw_spinlock_irqsave) at
all call sites to avoid sleeping-in-hardirq on PREEMPT_RT.
- Add kfifo_reset(&cxl_cper_fifo) to cxl_cper_unregister_work()
- Add WARN_ONCE to cxl_cper_register_work() for double-registration consistency
- Fix cxl_cper_unregister_work() to clear global pointer before cancel_work_sync()
- Remove redundant cancel_work_sync() from cxl_ras_exit()
cxl: Tighten CPER kfifo registration API and symbol visibility
- New commit (split/rework of v17 "Limit CXL-CPER kfifo registration functions scope")
cxl: Rename find_cxl_port() to find_cxl_port_by_dport()
- None
PCI/AER: Introduce AER-CXL protocol error kfifo
- Remove correctable status clear from cxl_forward_error(); the AER core
clears all status bits via pci_aer_handle_error() info->status writeback
- Schedule consumer on kfifo overflow so existing entries can be drained
PCI: Establish common CXL Port protocol error flow
- Fix handle_error_source() to call pci_aer_handle_error() unconditionally
so AER handling always runs after cxl_forward_error()
- Add cxl_proto_err_flush() call for CXL UCE to drain kfifo before AER
recovery tears down the device
- Fix NULL dereference of dport->dport_dev in cxl_handle_cor_ras() and
cxl_handle_ras() for UPSTREAM/ENDPOINT port types: use dport->dport_dev
when dport is non-NULL, else fall back to port->uport_dev
- Remove duplicate pcie_clear_device_status() call from
cxl_handle_proto_error() CE path; pci_aer_handle_error() already clears it
- Clarify panic policy: panic only on confirmed UCE via RAS status read
- Document kfifo consumer serialization against driver unbind via
guard(device)(&port->dev) and port->dev.driver check
PCI/CXL: Add RCH support to CXL handlers
- Pass &pdev->dev instead of dport->port->uport_dev in
cxl_handle_rdport_errors() to avoid dropping RCH trace events.
- Document trace event attribution change.
- Document removal of cxl_cor_error_detected() and cxlds->rcd branches.
- Capitalize Endpoint per PCI spec convention.
- Use to_ras_base() in cxl_handle_rdport_errors() to centralize RAS base
address lookup in preparation for error injection testing.
cxl/pci: Thread port and dport through RAS handling helpers
- New commit
cxl: Update CXL Endpoint AER handler
- Fix cxl_pci_error_detected() to use find_cxl_port_by_uport() and port->uport_dev
- Read CXL RAS unconditionally; panic on UCE regardless of channel state
- Document unconditional read policy and 0xFFFFFFFF behavior in comment
cxl: Add port and dport identifiers to CXL AER trace events
- Consolidate double find_cxl_port_by_dev() in cxl_cper_handle_prot_err()
- Add comment noting dport is NULL for endpoint and upstream port devices
PCI: Cache PCI DSN into pci_dev->dsn during probe
- New commit
PCI/CXL: Mask/Unmask CXL protocol errors
- Make cxl_unmask_proto_interrupts() and cxl_mask_proto_interrupts() static
- Remove dev_is_pci() guard from devm_cxl_dport_rch_ras_setup(); the guard
blocked real RCH hardware because pci_host_bridge is not on pci_bus_type
Documentation: cxl: Document CXL protocol error handling
- Simplify document for readability (Jonathan)
- Drop historical context that goes stale (Jonathan)
- Shorten ASCII flow diagram (Jonathan)
- Drop manual backtick markup, use automarkup (Jonathan)
- Clarify USP/DSP as single switch component (Dave)
- Fix line wrapping to 80 chars (Jonathan)
Changes in v16->v17:
PCI/AER: Introduce AER-CXL Kfifo
- Reword "kfifo semaphore" to "kfifo spinlock" to match fifo_lock.
- Defer the handle_error_source() is_cxl_error() switch to the patch that
registers the kfifo consumer to keep each commit bisect-safe.
- Rename rwsema to rwsem
- Change CPER exports to use EXPORT_SYMBOL_FOR_MODULES.
- Add work cancel function.
- Replace kfifo_put() with kfifo_in_spinlocked() for multiple producers
- Add fifo_lock spinlock for concurrent producer serialisation
- Initialize the embedded kfifo with INIT_KFIFO() in a subsys_initcall so
kfifo->mask, ->esize and ->data are set before first use.
- Clear PCI_ERR_COR_STATUS in cxl_forward_error() before enqueue so the
device is acked for correctable events even when the consumer drops the
event. Uncorrectable status is left for cxl_do_recovery() to clear after
recovery completes, mirroring the AER core convention.
- WARN on double-registration in cxl_register_proto_err_work() to make an
unintended second consumer visible at runtime.
- Add direct rwsem.h, cleanup.h and workqueue.h includes for symbols used
in aer_cxl_vh.c
- Add MAINTAINERS entries for drivers/pci/pcie/aer_cxl_*.c
- Update message
cxl/ras: Unify Endpoint and Port AER trace events
- Replace cxlds->serial with pci_get_dsn()
- Change 'memdev' to 'device' (Dan)
- Updated Commit message
cxl: Use common CPER handling for all CXL devices
- New commit
cxl: Rename find_cxl_port() to find_cxl_port_by_dport()
- New commit
- Drop the de-staticisation of find_cxl_port_by_uport() and the
core.h declarations from this prep patch; both move to the patch
that introduces the first cross-file caller.
cxl: Limit CXL-CPER kfifo registration functions scope
- Split from v16 02/10 ("Update unregistration for AER-CXL and
CPER-CXL kfifos"); AER-CXL half folded into v17 01/10.
- Convert exports to EXPORT_SYMBOL_FOR_MODULES("cxl_core").
- Change register/unregister return type from int to void.
- Drop work_struct argument from cxl_cper_unregister_prot_err_work();
it now cancels its own work.
- Remove now-redundant cancel_work_sync() from cxl_ras_exit().
- Add WARN_ONCE() in cxl_cper_register_prot_err_work() for
double-registration.
PCI: Establish common CXL Port protocol error flow
- get_cxl_port() -> find_cxl_port_by_dev()
- Simplified find_cxl_port_by_dev()
- Replace and remove cxl_serial_number() w/ pci_get_dsn()
- cxl_get_ras_base() -> to_ras_base()
- Drop dependency on PCI_ERS_RESULT_PANIC; cxl_do_recovery() panics
directly. (PANIC enum patch dropped from series.)
- Clarify panic semantics: panic on any uncorrectable CXL RAS error, not
only AER-FATAL severities.
- Drop the redundant PCI_ERR_COR_STATUS RMW in cxl_handle_proto_error();
cxl_forward_error() already acks the correctable AER status.
- Add is_cxl_error() switch in handle_error_source() here, paired with the
kfifo consumer registration, to keep each commit bisect-safe.
- Drop pcie_aer_is_native() guard in cxl_do_recovery() (always native).
- Swap order with the "Limit" patch for bisectability w/ cxl_ras_exit()
- Reword for "any uncorrectable" CXL RAS error panics.
- Restore log messages for port-not-found and port-unbound cases.
- Whitespace cleanup (Jonathan)
- Update to get_cxl_port() documentation (Terry)
- Fix __cxl_proto_err_work_fn() to return 0 for transient errors.
- Drop !port check in cxl_do_recovery(), caller already validated
- Fix kerneldoc @pdev -> @dev in find_cxl_port_by_dev()
- Fix missing space in pr_err_ratelimited()
- Add disconnect check before access
- Made pcie_clear_device_status() and pci_aer_clear_fatal_status()
EXPORT_SYMBOL_FOR_MODULES("cxl_core") (Dan)
- Move find_cxl_port_by_dport() and find_cxl_port_by_uport()
de-staticisation and core.h declarations from the rename patch to
here, where the first cross-file callers in find_cxl_port_by_dev()
land.
PCI/CXL: Add RCH support to CXL handlers
- Drop now-dead cxlds->rcd branches from cxl_{cor_,}error_detected().
- Drop duplicate subject line from commit body.
- Document panic-on-uncorrectable behavior change for RCD path.
- Document trace event device-name change (memN -> PCI BDF) for RCH path.
- Rewrite cxl_handle_proto_error() RC_END comment to clarify RCD/RCH shared
interrupt relationship
- Rewrite commit message
cxl: Remove Endpoint AER correctable handler
- Update commit message
- Add Reviewed-by from Jonathan and DaveJ
cxl: Update Endpoint AER uncorrectable handler
- Rename pci_error_handlers struct instance to cxl_pci_error_handlers to
avoid shadowing the struct type tag.
- Restore scoped_guard(device) and dev->driver check around AER read.
- NULL-check find_cxl_port_by_dev() before deref of port->uport_dev.
- Updated commit message. (Terry)
- Add scope cleanup for port variable in cxl_pci_error_detected() (Terry)
- Drop cxl_uncor_aer_present(), rely on AER state
PCI/CXL: Mask/Unmask CXL protocol errors
- Drop redundant cxl_mask_proto_interrupts() calls from unregister_port()
and cxl_dport_remove(); the devres action registered alongside the unmask
is the sole mask path.
- Update title
- Remove unnecessary check for aer_capabilities
- Gate cxl_unmask_proto_interrupts() on pcie_aer_is_native()
- Add pci_aer_mask_internal_errors() and cxl_mask_proto_interrupts()
- Only unmask on successful cxl_map_component_regs()
- NULL-check @dev in cxl_{un,}mask_proto_interrupts()
- Drop static and declare in core/core.h
Documentation: cxl: Document CXL protocol error handling
- New commit
Changes in v15->v16:
PCI/AER: Introduce AER-CXL Kfifo
- Add pci_dev_put() and comment at pci_dev_get() (Dan)
- /rw_sema/rwsema/ (Dan)
- Split validation checks in cxl_forward_error() to allow
for meaningful reason in log (Terry)
- Shortened commit title to remove wordiness (Terry)
PCI/CXL: Update unregistration for AER-CXL and CPER-CXL kfifos
- New commit
cxl: Update CXL Endpoint tracing
- Add Dan's review-by
- Incorporate Dan's comment into commit message:
"Add the serial number at the end to preserve compatibility with
libtraceevent parsing of the parameters."
PCI/ERR: Introduce PCI_ERS_RESULT_PANIC
- None
PCI: Establish common CXL Port protocol error flow
- get_ras_base(), initialize dport to NULL (Jonathan)
- Remove guard(device)(&cxlmd->dev) (Jonathan)
- Fix dev_warns() (Jonathan)
- Remove comment in cxl_port_error_detected() (Dan)
- Made pcie_clear_device_status() and pci_aer_clear_fatal_status()
"CXL" Export namespace (Dan)
- Update switch-case brackets to follow clang-format (Dan)
- Add PCI_EXP_TYPE_RC_END for cxl_get_ras_base() (Terry)
- Add NULL port check in cxl_serial_number() (Terry)
PCI/CXL: Add RCH support to CXL handlers
- New commit
cxl: Update error handlers to support CXL Port devices
- None
cxl: Update Endpoint AER uncorrectable handler
- Update commit message (DaveJ)
- s/cxl_handle_aer()/cxl_uncor_aer_present()/g (Jonathan)
- cxl_uncor_aer_present(): Leave original result calculation based on
if a UCE is present and the provided state (Terry)
- Add call to pci_print_aer(). AER fails to log because is upstream
link (Terry)
cxl: Remove Endpoint AER correctable handler
- None
cxl: Enable CXL protocol error reporting
- None
Changes in v14->v15:
PCI/AER: Introduce AER-CXL Kfifo in new file, pcie/aer_cxl_vh.c
- Move pci_dev_get() call to this patch (Dave)
cxl: Update CXL Endpoint tracing
- Update commit message
- Moved cxl_handle_ras/cxl_handle_cor_ras() changes to future patch (Terry)
PCI/ERR: Introduce PCI_ERS_RESULT_PANIC
- None
PCI/AER: Dequeue forwarded CXL error
- Move pci_dev_get() to cxl_forward_error() (Dave)
- Move in is_cxl_error() change from later patch (Terry)
PCI: Establish common CXL Port protocol error flow
- Update commit message and title. Added Bjorn's ack.
- Move CE and UCE handling logic here (Terry)
cxl: Update error handlers to support CXL Port protocol errors
- New commit (Terry)
cxl: Update Endpoint AER uncorrectable handler
- Title update (Terry)
- Change cxl_pci_error-detected() to handle & log AER (Terry)
- Update commit message (Terry)
- Moved cxl_handle_ras()/cxl_handle_cor_ras() to earlier patch (Terry)
cxl: Remove Endpoint AER correctable handler
- Remove cxl_pci_cor_error_detected(). Is not needed. AER is logged
in the AER driver. (Dan)
- Update commit message
Changes in v13->v14:
PCI: Move CXL DVSEC definitions into uapi/linux/pci_regs.h
- Add Jonathan's and Dan's review-by
- Update commit title prefix (Bjorn)
- Revert format fix for cxl_sbr_masked() (Jonathan)
- Update 'Compute Express Link' comment block (Jonathan)
- Move PCI_DVSEC_CXL_FLEXBUS definitions to later patch where
used (Jonathan)
- Removed stray change (Bjorn)
PCI: Update CXL DVSEC definitions
- New patch. Split from previous patch such that there is now a separate
move patch and a format fix patch.
- Formatting update requested (Bjorn)
- Remove PCI_DVSEC_HEADER1_LENGTH_MASK because it duplicates
PCI_DVSEC_HEADER1_LEN() (Bjorn)
- Add Dan's review-by
PCI: Introduce pcie_is_cxl()
- Move FLEXBUS_STATUS DVSEC here (Jonathan)
- Remove check for EP and USP (Dan)
- Update commit message (Bjorn)
- Fix writing past 80 columns (Bjorn)
- Add pci_is_pcie() parent bridge check at beginning of function (Bjorn)
PCI: Replace cxl_error_is_native() with pcie_aer_is_native()
- New commit
cxl/pci: Move CXL driver's RCH error handling into core/ras_rch.c
- Add sign-off for Dan and Jonathan
- Revert inadvertent formatting of cxl_dport_map_rch_aer() (Jonathan)
- Remove default value for CXL_RCH_RAS (Dan)
- Remove unnecessary pci.h include in core.h & ras_rch.c (Jonathan)
- Add linux/types.h include in ras_rch.c (Jonathan)
- Change CONFIG_CXL_RCH_RAS -> CONFIG_CXL_RAS (Dan)
PCI/AER: Export pci_aer_unmask_internal_errors
- New commit. Bjorn requested separating out and adding immediatetly
before being used. This is called from cxl_rch_enable_rcec() in
following patch.
PCI/AER: Update is_internal_error() to be non-static is_aer_internal_error()
- New commit
PCI/AER: Move CXL RCH error handling to aer_cxl_rch.c
- Add review-by and signed-off for Dan
- Commit message fixup (Dan)
- Update commit message with use-case description (Dan, Lukas)
- Make cxl_error_is_native() static (Dan)
- Make is_internal_error() non-static, non-export (Terry)
PCI/AER: Use guard() in cxl_rch_handle_error_iter()
- Add review-by for Jonathan, Dave Jiang, Dan WIlliams, and Bjorn
- Remove cleanup.h (Jonathan)
- Reverted comment removal (Bjorn)
- Move this patch after pci/pcie/aer_cxl_rch.c creation (Bjorn)
PCI/AER: Replace PCIEAER_CXL symbol with CXL_RAS
- New commit
PCI/AER: Report CXL or PCIe bus type in AER trace logging
- Merged with Dan's commit. Changes are moving bus_type the last
parameter in function calls (Dan)
- Removed all DCOs because of changes (Terry)
- Update commit message (Bjorn)
- Add Bjorn's ack-by
PCI/AER: Update struct aer_err_info with kernel-doc formatting
- New commit
cxl/mem: Clarify @host for devm_cxl_add_nvdimm()
- New commit
cxl/port: Remove "enumerate dports" helpers
- New commit
cxl/port: Fix devm resource leaks around with dport management
- New commit
cxl/port: Move dport operations to a driver event
- New commit
cxl/port: Move dport RAS reporting to a port resource
- New commit
cxl: Map CXL Endpoint Port and CXL Switch Port RAS registers
- Correct message spelling (Terry)
cxl/port: Move endpoint component register management to cxl_port
- Correct message spelling (Terry)
cxl/port: Map Port component registers before switchport init
- Updates to use cxl_port_setup_regs() (Dan)
cxl: Change CXL handlers to use guard() instead of scoped_guard()
- Add reviewed-by for Jonathan and Dave Jiang
PCI/ERR: Introduce PCI_ERS_RESULT_PANIC
- Add review-by for Dan
- Update Title prefix (Bjorn)
- Removed merge_result. Only logging error for device reporting the
error (Dan)
- Remove PCI_ERS_RESULT_PANIC paragraph in pci-error-recovery.rst (Bjorn)
PCI/AER: Move AER driver's CXL VH handling to pcie/aer_cxl_vh.c
- Replaced workqueue_types.h include with 'struct work_struct'
predeclaration (Bjorn)
- Update error message (Bjorn)
- Reordered 'struct cxl_proto_err_work_data' (Bjorn)
- Remove export of cxl_error_is_native() here (Bjorn)
cxl/port: Unify endpoint and switch port lookup
- New patch
PCI/AER: Dequeue forwarded CXL error
- Update commit title's prefix (Bjorn)
- Add pdev ref get in AER driver before enqueue and add pdev ref put in
CXL driver after dequeue and handling (Dan)
- Removed handling to simplify patch context (Terry)
PCI: Introduce CXL Port protocol error handlers
- Add Dave Jiang's review-by
- Update commit message & headline (Bjorn)
- Refactor cxl_port_error_detected()/cxl_port_cor_error_detected() to
one line (Jonathan)
- Remove cxl_walk_port(). Only log the erroring device. No port walking. (Dan)
- Remove cxl_pci_drv_bound(). Check for 'is_cxl' parent port is
sufficient (Dan)
- Remove device_lock_if()
- Combine CE and UCE here (Terry)
cxl: Update Endpoint uncorrectable protocol error handling
- Update commit headline (Bjorn)
- Rename pci_error_detected()/pci_cor_error_detected() ->
cxl_pci_error_detected/cxl_pci_cor_error_detected() (Jonathan)
- Remove now-invalid comment in cxl_error_detected() (Jonathan)
- Split into separate patches for UCE and CE (Terry)
cxl: Update Endpoint correctable protocol error handling
- New commit
- Change cxl_cor_error_detected() parameter to &pdev->dev device from
memdev device. (Terry)
cxl: Enable CXL protocol errors during CXL Port probe
- Update commit title's prefix (Bjorn)
Changes in v12->v13:
CXL/PCI: Move CXL DVSEC definitions into uapi/linux/pci_regs.h
- Add Dave Jiang's reviewed-by
- Remove changes to existing PCI_DVSEC_CXL_PORT* defines. Update commit
message. (Jonathan)
PCI/CXL: Introduce pcie_is_cxl()
- Add Ben's "reviewed-by"
cxl/pci: Remove unnecessary CXL Endpoint handling helper functions
- None
cxl/pci: Remove unnecessary CXL RCH handling helper functions
- None
cxl: Remove CXL VH handling in CONFIG_PCIEAER_CXL conditional blocks from core
- None
cxl: Move CXL driver's RCH error handling into core/ras_rch.c
- None
CXL/AER: Replace device_lock() in cxl_rch_handle_error_iter() with guard() lock
- New patch
CXL/AER: Move AER drivers RCH error handling into pcie/aer_cxl_rch.c
- Add forward declararation of 'struct aer_err_info' in pci/pci.h (Terry)
- Changed copyright date from 2025 to 2023 (Jonathan)
- Add David Jiang's, Jonathan's, and Ben's review-by
- Readd 'struct aer_err_info' (Bot)
PCI/AER: Report CXL or PCIe bus error type in trace logging
- Remove duplicated aer_err_info inline comments. Is already in the
kernel-doc header (Ben)
cxl/pci: Update RAS handler interfaces to also support CXL Ports
- None
cxl/pci: Log message if RAS registers are unmapped
- Added Bens review-by
cxl/pci: Unify CXL trace logging for CXL Endpoints and CXL Ports
- Added Dave Jiang's review-by
cxl/pci: Update cxl_handle_cor_ras() to return early if no RAS errors
- Add Ben's review-by
cxl/pci: Map CXL Endpoint Port and CXL Switch Port RAS registers
- Change as result of dport delay fix. No longer need switchport and
endport approach. Refactor. (Terry)
CXL/PCI: Introduce PCI_ERS_RESULT_PANIC
- Add Dave Jiang's, Jonathan's, Ben's review-by
- Typo fix (Ben)
CXL/AER: Introduce pcie/aer_cxl_vh.c in AER driver for forwarding CXL errors
- Add Dave Jiang's review-by
- Update error message (Ben)
cxl: Introduce cxl_pci_drv_bound() to check for bound driver
- Add Dave Jiang's review-by.
cxl: Change CXL handlers to use guard() instead of scoped_guard()
- New patch
cxl/pci: Introduce CXL protocol error handlers for endpoints
- Updated all the implemetnation and commit message. (Terry)
- Refactored cxl_cor_error_detected()/cxl_error_detected() to remove
pdev (Dave Jiang)
CXL/PCI: Introduce CXL Port protocol error handlers
- Move get_pci_cxl_host_dev() and cxl_handle_proto_error() to Dequeue
patch (Terry)
- Remove EP case in cxl_get_ras_base(), not used. (Terry)
- Remove check for dport->dport_dev (Dave)
- Remove whitespace (Terry)
PCI/AER: Dequeue forwarded CXL error
- Rewrite cxl_handle_proto_error() and cxl_proto_err_work_fn() (Terry)
- Rename get_cxl_host dev() to be get_cxl_port() (Terry)
- Remove exporting of unused function, pci_aer_clear_fatal_status() (Dave Jiang)
- Change pr_err() calls to ratelimited. (Terry)
- Update commit message. (Terry)
- Remove namespace qualifier from pcie_clear_device_status()
export (Dave Jiang)
- Move locks into cxl_proto_err_work_fn() (Dave)
- Update log messages in cxl_forward_error() (Ben)
CXL/PCI: Export and rename merge_result() to pci_ers_merge_result()
- Renamed pci_ers_merge_result() to pcie_ers_merge_result().
pci_ers_merge_result() is already used in eeh driver. (Bot)
CXL/PCI: Introduce CXL uncorrectable protocol error recovery
- Rewrite report_error_detected() and cxl_walk_port (Terry)
- Add guard() before calling cxl_pci_drv_bound() (Dave Jiang)
- Add guard() calls for EP (cxlds->cxlmd->dev & pdev->dev) and ports
(pdev->dev & parent cxl_port) in cxl_report_error_detected() and
cxl_handle_proto_error() (Terry)
- Remove unnecessary check for endpoint port. (Dave Jiang)
- Remove check for RCIEP EP in cxl_report_error_detected() (Terry)
CXL/PCI: Enable CXL protocol errors during CXL Port probe
- Add dev and dev_is_pci() NULL checks in cxl_unmask_proto_interrupts() (Terry)
- Add Dave Jiang's and Ben's review-by
CXL/PCI: Disable CXL protocol error interrupts during CXL Port cleanup
- Added dev and dev_is_pci() checks in cxl_mask_proto_interrupts() (Terry)
Changes in v11 -> v12:
cxl/pci: Remove unnecessary CXL Endpoint handling helper functions
- Added Dave Jiang's review by
- Moved to front of series
cxl/pci: Remove unnecessary CXL RCH handling helper functions
- Add reviewed-by for Alejandro & Dave Jiang
- Moved to front of series
cxl: Remove ifdef blocks of CONFIG_PCIEAER_CXL from core/pci.c
- Update CONFIG_CXL_RAS in CXL Kconfig to have CXL_PCI dependency (Terry)
CXL/AER: Remove CONFIG_PCIEAER_CXL and replace with CONFIG_CXL_RAS
- Added review-by for Sathyanarayanan
- Changed Kconfig dependency from PCIEAER_CXL to PCIEAER. Moved
this backwards into this patch.
cxl: Move CXL driver RCH error handling into CONFIG_CXL_RCH_RAS conditio
- Moved CXL_RCH_RAS Kconfig definition here from following commit
CXL/AER: Introduce aer_cxl_rch.c into AER driver for handling CXL RCH errors
- Rename drivers/pci/pcie/cxl_rch.c to drivers/pci/pcie/aer_cxl_rch.c (Lukas)
- Removed forward declararation of 'struct aer_err_info' in pci/pci.h (Terry)
CXL/PCI: Move CXL DVSEC definitions into uapi/linux/pci_regs.h
- Change formatting to be same as existing definitions
- Change GENMASK() -> __GENMASK() and BIT() to _BITUL()
PCI/CXL: Introduce pcie_is_cxl()
- Add review-by for Alejandro
- Add comment in set_pcie_cxl() explaining why updating parent status.
PCI/AER: Report CXL or PCIe bus error type in trace logging
- Change aer_err_info::is_cxl to be bool a bitfield. Update structure padding. (Lukas)
- Add kernel-doc for 'struct aer_err_info' (Lukas)
cxl/pci: Unify CXL trace logging for CXL Endpoints and CXL Ports
- Correct parameters to call trace_cxl_aer_correctable_error() (Shiju)
- Add reviewed-by for Jonathan and Shiju
cxl/pci: Map CXL Endpoint Port and CXL Switch Port RAS registers
- Add check for dport_parent->rch before calling cxl_dport_init_ras_reporting().
- RCH dports are initialized from cxl_dport_init_ras_reporting cxl_mem_probe().
CXL/PCI: Introduce PCI_ERS_RESULT_PANIC
- Documentation requested by (Lukas)
CXL/AER: Introduce aer_cxl_vh.c in AER driver for forwarding CXL errors
- Rename drivers/pci/pcie/cxl_aer.c to drivers/pci/pcie/aer_cxl_vh.c (Lukas)
cxl: Introduce cxl_pci_drv_bound() to check for bound driver
- New patch
PCI/AER: Dequeue forwarded CXL error
- Add guard for CE case in cxl_handle_proto_error() (Dave)
- Updated commit message (Terry)
CXL/PCI: Introduce CXL Port protocol error handlers
- Add call to cxl_pci_drv_bound() in cxl_handle_proto_error() and
pci_to_cxl_dev() (Lukas)
- Change cxl_error_detected() -> cxl_cor_error_detected() (Terry)
- Remove NULL variable assignments (Jonathan)
- Replace bus_find_device() with find_cxl_port_by_uport() for upstream
port searches. (Dave)
CXL/PCI: Export and rename merge_result() to pci_ers_merge_result()
- Remove static inline pci_ers_merge_result() definition for !CONFIG_PCIEAER.
Is not needed. (Lukas)
CXL/PCI: Introduce CXL uncorrectable protocol error recovery
- Clean up port discovery in cxl_do_recovery() (Dave)
- Add PCI_EXP_TYPE_RC_END to type check in cxl_report_error_detected()
Changes in v10 -> v11:
cxl: Remove ifdef blocks of CONFIG_PCIEAER_CXL from core/pci.c
- New patch
CXL/AER: Remove CONFIG_PCIEAER_CXL and replace with CONFIG_CXL_RAS
- New patch
cxl/pci: Remove unnecessary CXL RCH handling helper functions
- New patch
cxl: Move CXL driver RCH error handling into CONFIG_CXL_RCH_RAS conditional block
- New patch
CXL/AER: Introduce rch_aer.c into AER driver for handling CXL RCH errors
- Remove changes in code-split and move to earlier, new patch
- Add #include <linux/bitfield.h> to cxl_ras.c
- Move cxl_rch_handle_error() & cxl_rch_enable_rcec() declarations from pci.h
to aer.h, more localized.
- Introduce CONFIG_CXL_RCH_RAS, includes Makefile changes, ras.c ifdef changes
CXL/PCI: Move CXL DVSEC definitions into uapi/linux/pci_regs.h
- New patch
PCI/CXL: Introduce pcie_is_cxl()
- Amended set_pcie_cxl() to check for Upstream Port's and EP's parent
downstream port by calling set_pcie_cxl(). (Dan)
- Retitle patch: 'Add' -> 'Introduce'
- Add check for CXL.mem and CXL.cache (Alejandro, Dan)
PCI/AER: Report CXL or PCIe bus error type in trace logging
- Remove duplicate call to trace_aer_event() (Shiju)
- Added Dan William's and Dave Jiang's reviewed-by
CXL/AER: Update PCI class code check to use FIELD_GET()
- Add #include <linux/bitfield.h> to cxl_ras.c (Terry)
- Removed line wrapping at "(CXL 3.2, 8.1.12.1)". (Jonathan)
cxl/pci: Log message if RAS registers are unmapped
- Added Dave Jiang's review-by (Terry)
cxl/pci: Unify CXL trace logging for CXL Endpoints and CXL Ports
- Updated CE and UCE trace routines to maintian consistent TP_Struct ABI
and unchanged TP_printk() logging. (Shiju, Alison)
cxl/pci: Update cxl_handle_cor_ras() to return early if no RAS errors
- Added Dave Jiang and Jonathan Cameron's review-by
- Changes moved to core/ras.c
cxl/pci: Map CXL Endpoint Port and CXL Switch Port RAS registers
- Use local pointer for readability in cxl_switch_port_init_ras() (Jonathan Cameron)
- Rename port to be ep in cxl_endpoint_port_init_ras() (Dave Jiang)
- Rename dport to be parent_dport in cxl_endpoint_port_init_ras()
and cxl_switch_port_init_ras() (Dave Jiang)
- Port helper changes were in cxl/port.c, now in core/ras.c (Dave Jiang)
cxl/pci: Introduce CXL Endpoint protocol error handlers
- cxl_error_detected() - Change handlers' scoped_guard() to guard() (Jonathan)
- cxl_error_detected() - Remove extra line (Shiju)
- Changes moved to core/ras.c (Terry)
- cxl_error_detected(), remove 'ue' and return with function call. (Jonathan)
- Remove extra space in documentation for PCI_ERS_RESULT_PANIC definition
- Move #include "pci.h from cxl.h to core.h (Terry)
- Remove unnecessary includes of cxl.h and core.h in mem.c (Terry)
CXL/AER: Introduce cxl_aer.c into AER driver for forwarding CXL errors
- Move RCH implementation to cxl_rch.c and RCH declarations to pci/pci.h. (Terry)
- Introduce 'struct cxl_proto_err_kfifo' containing semaphore, fifo,
and work struct. (Dan)
- Remove embedded struct from cxl_proto_err_work (Dan)
- Make 'struct work_struct *cxl_proto_err_work' definition static (Jonathan)
- Add check for NULL cxl_proto_err_kfifo to determine if CXL driver is
not registered for workqueue. (Dan)
PCI/AER: Dequeue forwarded CXL error
- Reword patch commit message to remove RCiEP details (Jonathan)
- Add #include <linux/bitfield.h> (Terry)
- is_cxl_rcd() - Fix short comment message wrap (Jonathan)
- is_cxl_rcd() - Combine return calls into 1 (Jonathan)
- cxl_handle_proto_error() - Move comment earlier (Jonathan)
- Usse FIELD_GET() in discovering class code (Jonathan)
- Remove BDF from cxl_proto_err_work_data. Use 'struct pci_dev *' (Dan)
CXL/PCI: Introduce CXL Port protocol error handlers
- Removed check for PCI_EXP_TYPE_RC_END in cxl_report_error_detected() (Terry)
- Update is_cxl_error() to check for acceptable PCI EP and port types
CXL/PCI: Export and rename merge_result() to pci_ers_merge_result()
- pci_ers_merge_result() - Change export to non-namespace and rename
to be pci_ers_merge_result() (Jonathan)
- Move pci_ers_merge_result() definition to pci.h. Needs pci_ers_result (Terry)
CXL/PCI: Introduce CXL uncorrectable protocol error recovery
- pci_ers_merge_results() - Move to earlier patch
CXL/PCI: Disable CXL protocol error interrupts during CXL Port cleanup
- Remove guard() in cxl_mask_proto_interrupts(). Observed device lockup/block
during testing. (Terry)
Changes in v9 -> v10:
- Add drivers/pci/pcie/cxl_aer.c
- Add drivers/cxl/core/native_ras.c
- Change cxl_register_prot_err_work()/cxl_unregister_prot_err_work to return void
- Check for pcie_ports_native in cxl_do_recovery()
- Remove debug logging in cxl_do_recovery()
- Update PCI_ERS_RESULT_PANIC definition to indicate is CXL specific
- Revert trace logging changes: name,parent -> memdev,host.
- Use FIELD_GET() to check for EP class code (cxl_aer.c & native_ras.c).
- Change _prot_ to _proto_ everywhere
- cxl_rch_handle_error_iter(), check if driver is cxl_pci_driver
- Remove cxl_create_prot_error_info(). Move logic into forward_cxl_error()
- Remove sbdf_to_pci() and move logic into cxl_handle_proto_error()
- Simplify/refactor get_pci_cxl_host_dev()
- Simplify/refactor cxl_get_ras_base()
- Move patch 'Remove unnecessary CXL Endpoint handling helper functions' to front
- Update description for 'CXL/PCI: Introduce CXL Port protocol error
handlers' with why state is not used to determine handling
- Introduce cxl_pci_drv_bound() and call from cxl_rch_handle_error_iter()
Changes in v8 -> v9:
- Updated reference counting to use pci_get_device()/pci_put_device() in
cxl_disable_prot_errors()/cxl_enable_prot_errors
- Refactored cxl_create_prot_err_info() to fix reference counting
- Removed 'struct cxl_port' driver changes for error handler. Instead
check for CXL device type (EP or Port device) and call handler
- Make pcie_is_cxl() static inline in include/linux/linux.h
- Remove NULL check in create_prot_err_info()
- Change success return in cxl_ras_init() to use hardcoded 0
- Changed 'struct work_struct cxl_prot_err_work' declaration to static
- Change to use rate limited log with dev anchor in forward_cxl_error()
- Refactored forward-cxl_error() to remove severity auto variable
- Changed pci_aer_clear_nonfatal_status() to be static inline for
!(CONFIG_PCIEAER)
- Renamed merge_result() to be cxl_merge_result()
- Removed 'ue' condition in cxl_error_detected()
- Updated 2nd parameter in call to __cxl_handle_cor_ras()/__cxl_handle_ras()
in unify patch
- Added log message for failure while assigning interrupt disable callback
- Updated pci_aer_mask_internal_errors() to use pci_clear_and_set_config_dword()
- Simplified patch titles for clarity
- Moved CXL error interrupt disabling into cxl/core/port.c with CXL Port
teardown
- Updated 'struct cxl_port_err_info' to only contain sbdf and severity
Removed everything else.
- Added pdev and CXL device get_device()/put_device() before calling handlers
Changes in v7 -> v8:
[Dan] Use kfifo. Move handling to CXL driver. AER forwards error to CXL
driver
[Dan] Add device reference incrementors where needed throughout
[Dan] Initiate CXL Port RAS init from Switch Port and Endpoint Port init
[Dan] Combine CXL Port and CXL Endpoint trace routine
[Dan] Introduce aer_info::is_cxl. Use to indicate CXL or PCI errors
[Jonathan] Add serial number for all devices in trace
[DaveJ] Move find_cxl_port() change into patch using it
[Terry] Move CXL Port RAS init into cxl/port.c
[Terry] Moved kfifo functions into cxl/core/ras.c
Changes in v6 -> v7:
[Terry] Move updated trace routine call to later patch. Was causing build
error.
Changes in v5 -> v6:
[Ira] Move pcie_is_cxl(dev) define to a inline function
[Ira] Update returning value from pcie_is_cxl_port() to bool w/o cast
[Ira] Change cxl_report_error_detected() cleanup to return correct bool
[Ira] Introduce and use PCI_ERS_RESULT_PANIC
[Ira] Reuse comment for PCIe and CXL recovery paths
[Jonathan] Add type check in for cxl_handle_cor_ras() and cxl_handle_ras()
[Jonathan] cxl_uport/dport_init_ras_reporting(), added a mutex.
[Jonathan] Add logging example to patches updating trace output
[Jonathan] Make parameter 'const' to eliminate for cast in match_uport()
[Jonathan] Use __free() in cxl_pci_port_ras()
[Terry] Add patch to log the PCIe SBDF along with CXL device name
[Terry] Add patch to handle CXL endpoint and RCH DP errors as CXL errors
[Terry] Remove patch w USP UCE fatal support @ aer_get_device_error_info()
[Terry] Rebase to cxl/next commit 5585e342e8d3 ("cxl/memdev: Remove unused partition values")
[Gregory] Pre-initialize pointer to NULL in cxl_pci_port_ras()
[Gregory] Move AER driver bus name detection to a static function
Changes in v4 -> v5:
[Alejandro] Refactor cxl_walk_bridge to simplify 'status' variable usage
[Alejandro] Add WARN_ONCE() in __cxl_handle_ras() and cxl_handle_cor_ras()
[Ming] Remove unnecessary NULL check in cxl_pci_port_ras()
[Terry] Add failure check for call to to_cxl_port() in cxl_pci_port_ras()
[Ming] Use port->dev for call to devm_add_action_or_reset() in
cxl_dport_init_ras_reporting() and cxl_uport_init_ras_reporting()
[Jonathan] Use get_device()/put_device() to prevent race condition in
cxl_clear_port_error_handlers() and cxl_clear_port_error_handlers()
[Terry] Commit message cleanup. Capitalize keywords from CXL and PCI
specifications
Changes in v3 -> v4:
[Lukas] Capitalize PCIe and CXL device names as in specifications
[Lukas] Move call to pcie_is_cxl() into cxl_port_devsec()
[Lukas] Correct namespace spelling
[Lukas] Removed export from pcie_is_cxl_port()
[Lukas] Simplify 'if' blocks in cxl_handle_error()
[Lukas] Change panic message to remove redundant 'panic' text
[Ming] Update to call cxl_dport_init_ras_reporting() in RCH case
[lkp@intel] 'host' parameter is already removed. Remove parameter description too.
[Terry] Added field description for cxl_err_handlers in pci.h comment block
Changes in v1 -> v2:
[Jonathan] Remove extra NULL check and cleanup in cxl_pci_port_ras()
[Jonathan] Update description to DSP map patch description
[Jonathan] Update cxl_pci_port_ras() to check for NULL port
[Jonathan] Dont call handler before handler port changes are present (patch order)
[Bjorn] Fix linebreak in cover sheet URL
[Bjorn] Remove timestamps from test logs in cover sheet
[Bjorn] Retitle AER commits to use "PCI/AER:"
[Bjorn] Retitle patch#3 to use renaming instead of refactoring
[Bjorn] Fix base commit-id on cover sheet
[Bjorn] Add VH spec reference/citation
[Terry] Removed last 2 patches to enable internal errors. Is not needed
because internal errors are enabled in AER driver.
[Dan] Create cxl_do_recovery() and pci_driver::cxl_err_handlers.
[Dan] Use kernel panic in CXL recovery
[Dan] cxl_port_hndlrs -> cxl_port_error_handlers
Dan Williams (4):
cxl: Tighten CPER kfifo registration API and symbol visibility
cxl: Rename find_cxl_port() to find_cxl_port_by_dport()
cxl/pci: Thread port and dport through RAS handling helpers
cxl: Add port and dport identifiers to CXL AER trace events
Terry Bowman (9):
cxl/ras: Fix cxl_rch_get_aer_severity() wrong severity register
acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks
PCI/AER: Introduce AER-CXL protocol error kfifo
PCI: Establish common CXL Port protocol error flow
PCI/CXL: Add RCH support to CXL handlers
cxl: Update CXL Endpoint AER handler
PCI: Cache PCI DSN into pci_dev->dsn during probe
PCI/CXL: Mask/Unmask CXL protocol errors
Documentation: cxl: Document CXL protocol error handling
Documentation/driver-api/cxl/index.rst | 1 +
.../cxl/linux/protocol-error-handling.rst | 222 ++++++++++
MAINTAINERS | 2 +
drivers/acpi/apei/ghes.c | 66 +--
drivers/cxl/core/core.h | 36 +-
drivers/cxl/core/port.c | 28 +-
drivers/cxl/core/ras.c | 395 ++++++++++++------
drivers/cxl/core/ras_rch.c | 20 +-
drivers/cxl/core/trace.c | 35 ++
drivers/cxl/core/trace.h | 91 ++--
drivers/cxl/cxlmem.h | 7 +
drivers/cxl/cxlpci.h | 11 +-
drivers/cxl/pci.c | 16 +-
drivers/pci/pci.h | 1 -
drivers/pci/pcie/Makefile | 1 +
drivers/pci/pcie/aer.c | 45 +-
drivers/pci/pcie/aer_cxl_rch.c | 39 +-
drivers/pci/pcie/aer_cxl_vh.c | 235 +++++++++++
drivers/pci/pcie/portdrv.h | 10 +-
drivers/pci/probe.c | 14 +
include/cxl/event.h | 17 +-
include/linux/aer.h | 26 ++
include/linux/pci.h | 1 +
tools/testing/cxl/Kbuild | 1 +
tools/testing/cxl/test/mock.c | 12 +
25 files changed, 1013 insertions(+), 319 deletions(-)
create mode 100644 Documentation/driver-api/cxl/linux/protocol-error-handling.rst
create mode 100644 drivers/pci/pcie/aer_cxl_vh.c
base-commit: a13c140cc289c0b7b3770bce5b3ad42ab35074aa
--
2.34.1
^ permalink raw reply
* Re: [PATCH v7 08/12] PCI: liveupdate: Inherit ACS flags in incoming preserved devices
From: Pasha Tatashin @ 2026-07-17 22:08 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-9-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:11 +0000, David Matlack <dmatlack@google.com> wrote:
> Inherit Access Control Services (ACS) flags on all incoming preserved
> devices (endpoints and upstream bridges) during a Live Update.
>
> Inheriting ACS flags avoids changing routing rules while memory
> transactions are in flight from preserved devices. This is also strictly
> necessary to ensure that IOMMU group assignments do not change across
> a Live Update for preserved devices, as changing ACS configurations can
> split or merge IOMMU groups.
>
> [...]
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 07/12] PCI: Refactor matching logic for pci_dev_acs_ops
From: Pasha Tatashin @ 2026-07-17 22:02 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-8-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:10 +0000, David Matlack <dmatlack@google.com> wrote:
> Refactor the logic to match devices to pci_dev_acs_ops by factoring out
> the loop and device matching into its own routine. This eliminates some
> duplicate code between pci_dev_specific_enable_acs() and
> pci_dev_specific_disable_acs_redir(), and will also be used in a
> subsequent commit to check if a device requires device-specific
> enable_acs() during a Live Update.
>
> [...]
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 06/12] PCI: liveupdate: Auto-preserve upstream bridges across Live Update
From: Pasha Tatashin @ 2026-07-17 22:00 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-7-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:09 +0000, David Matlack <dmatlack@google.com> wrote:
> When a PCI device is preserved across a Live Update, all of its upstream
> bridges up to the root port must also be preserved. This enables the PCI
> core and any drivers bound to the bridges to manage bridges correctly
> across a Live Update.
>
> Notably, this will be used in subsequent commits to ensure that
> preserved devices can continue performing memory transactions without a
> disruption or change in routing.
>
> [...]
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 05/12] PCI: liveupdate: Keep bus numbers constant during Live Update
From: Pasha Tatashin @ 2026-07-17 21:48 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-6-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:08 +0000, David Matlack <dmatlack@google.com> wrote:
> During a Live Update, preserved devices must be allowed to continue
> performing memory transactions so the kernel cannot change the fabric
> topology, including bus numbers, since that would require disabling
> and flushing any memory transactions first.
>
> To keep bus numbers constant, always inherit the secondary and
> subordinate bus numbers assigned to bridges during scanning, instead of
> assigning new ones, if any PCI devices are being preserved. Note that
> the kernel inherits bus numbers even on bridges without any downstream
> endpoints that were preserved. This avoids accidentally assigning a
> bridge a new window that overlaps with a preserved device that is
> downstream of a different bridge.
>
> [...]
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 03/12] PCI: liveupdate: Track incoming preserved PCI devices
From: Pasha Tatashin @ 2026-07-17 21:46 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-4-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:06 +0000, David Matlack <dmatlack@google.com> wrote:
> diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> index 03075ce06ac9..df6a02240aa4 100644
> --- a/drivers/pci/liveupdate.c
> +++ b/drivers/pci/liveupdate.c
> @@ -298,6 +377,87 @@ void pci_liveupdate_unpreserve(struct pci_dev *dev)
> [ ... skip 76 lines ... ]
> + /*
> + * Hold the ref on the incoming FLB until pci_liveupdate_finish() so
> + * that dev->liveupdate.incoming cannot get freed while the PCI core
> + * has a pointer to it. It's better to leak the incoming FLB than do a
> + * use-after-free if driver does not call pci_liveupdate_finish().
> + */
I am confused by this. Each preserved PCI device must have an associated
FD preserved with it via LUO. I.e., vfiofd would need to be preserved. If
the vfiofd was not reclaimed, and finish is not possible, that vfiofd
would still be owned by LUO, and therefore PCI FLB refcount would stay
positive.
However, if finish is possible, and this is the last vfiofd that is
finished, FLB will be freed as soon as the reference count reaches zero,
which I would think is the expected behavior.
What is the point of holding a reference here, instead of only for the
duration of FLB access, i.e. to make sure we are accessing a valid data?
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 2/3] iommu/arm-smmu-v3: Introduce CFGI/TLBI-repeat workaround infrastructure
From: Nicolin Chen @ 2026-07-17 21:16 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Ashish Mhetre, catalin.marinas, will, corbet, skhan, robin.murphy,
joro, linux-arm-kernel, linux-doc, linux-kernel, iommu,
linux-tegra
In-Reply-To: <20260717201841.GC701389@ziepe.ca>
On Fri, Jul 17, 2026 at 05:18:41PM -0300, Jason Gunthorpe wrote:
> On Tue, Jul 14, 2026 at 10:42:01AM +0000, Ashish Mhetre wrote:
> Because the VM has access to VCMDQ/etc it can issue commands directly
> (maybe not on this chip, but as a general comment), thus invalidation
> errata need to be made visible to the VM and we need to expect the VM
> will generate invalidations to properly deal with any errata.
>
> Ie I'd expect the VM to see a "nvidia,tegra264-smmu" compatible string
> to activate the errata fix.
>
> If so then we will already get duplicated invalidations here and then
> we will duplicate them again. That's not great.
Oh, that's a good point.
> On the other hand if you want to emulate a generic and actually
> functional SMMU device that has nothing like VCMDQ/etc then you must
> do something like this in this patch.
Tegra264 has virtualization use case. And It's built with VCMDQ,
which should be the default case than the generic vSMMU case.
> I was imagining a general direction that we would expose the errata
> information to the guest and the guest would have to deal with it.
>
> Given this is the opposite I wonder if we want to do it. It does make
> sense for a chip that probably doesn't have vCMDQ and I don't think
> qemu can even create a DT description to trigger the errata anyhow.
I don't have the source code of the VMM used on Tegra264, but I
believe the guest kernel can be the same copy of kernel as the
host. So, its VMM is likely to use the "nvidia,tegra264-smmu" DT
compatible string, to trigger the errata at the guest level.
> But it starts to become confusing down the road if we decide other
> invalidation errata (like the CONT must be RIL thing) must be delt
> with by the guest.
>
> So.. Maybe add a comment why this one is different, or maybe just
> disable FEAT_NESTING if there isn't a use case?
Given the use cases on Tegra264, instead of patching the iommufd
path as this patch does, perhaps we should simply spit a WARN in
arm_vsmmu_init():
if (static_branch_unlikely(&arm_smmu_erratum_repeat_tlbi_cfgi_key))
dev_warn(smmu->dev,
"guest must WAR the repeat_tlbi_cfgi erratum\n");
?
Thanks
Nicolin
^ permalink raw reply
* [PATCH 2/2] x86/resctrl: Fix ABMC counter programming for extended counter ranges
From: Babu Moger @ 2026-07-17 21:13 UTC (permalink / raw)
To: babu.moger, tony.luck, reinette.chatre, bp
Cc: x86, Dave.Martin, james.morse, corbet, skhan, tglx, mingo,
dave.hansen, hpa, linux-kernel, linux-doc, eranian, peternewman
In-Reply-To: <8cb66e18e32e4087a9712c1e68ee6da614efe244.1784322818.git.babu.moger@amd.com>
Memory Bandwidth Monitoring (MBM) can report incorrect values when ABMC is
enabled on systems supporting more than 32 ABMC counters. As the number of
active monitoring groups increases beyond the range supported by the
existing counter ID encoding, programming an ABMC counter may inadvertently
affect a different counter, resulting in unexpected counter resets and
abnormally large MBM readings.
The issue originates from the ABMC counter programming interface in the
L3_QOS_ABMC_CFG MSR. The counter ID field is currently defined as 5 bits,
which limits the addressable counter range to 32 counters. On systems
implementing more than 32 ABMC counters, counter IDs above 31 cannot be
encoded correctly. Consequently, programming a counter ID beyond the
supported range may target an unintended counter and reset bandwidth
statistics associated with another monitoring group.
While updating this logic, it was also observed that the bw_src field,
which encodes the RMID, is currently at its 12-bit limit with support for
4096 RMIDs. This field also needs to be updated for future expansion.
Also found one more pre-existing issue. This union structure can truncate
data on 32-bit x86 systems when unsigned long is used.
Fix the issues with the following changes:
1. Update the cntr_id field handling to support the full hardware ABMC
counter range and ensure that counter programming does not interfere with
unrelated counters.
2. Expand the bw_src field to 15 bits.
3. Change "unsigned long" to u64 to fix truncation on 32-bit x86.
The AMD64 Architecture Programmer's Manual [1] available at [2] will be
updated accordingly in a future revision to document the expanded cntr_id
and bw_src field definitions.
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming,
Publication #24593, Revision 3.41, Section 19.3.3.3 "Assignable
Bandwidth Monitoring (ABMC)"
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537
Fixes: 84ecefb76674 ("x86/resctrl: Add data structures and definitions for ABMC assignment")
Signed-off-by: Babu Moger <babu.moger@amd.com>
---
arch/x86/kernel/cpu/resctrl/internal.h | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index e3cfa0c10e92..b3d780eda8a7 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -192,7 +192,6 @@ union cpuid_0x10_x_edx {
* @bw_type : Event configuration that represents the memory
* transactions being tracked by the @cntr_id.
* @bw_src : Bandwidth source (RMID or CLOSID).
- * @reserved1 : Reserved.
* @is_clos : @bw_src field is a CLOSID (not an RMID).
* @cntr_id : Counter identifier.
* @reserved : Reserved.
@@ -210,16 +209,15 @@ union cpuid_0x10_x_edx {
*/
union l3_qos_abmc_cfg {
struct {
- unsigned long bw_type :32,
- bw_src :12,
- reserved1: 3,
- is_clos : 1,
- cntr_id : 5,
- reserved : 9,
- cntr_en : 1,
- cfg_en : 1;
+ u64 bw_type :32,
+ bw_src :15,
+ is_clos : 1,
+ cntr_id :12,
+ reserved : 2,
+ cntr_en : 1,
+ cfg_en : 1;
} split;
- unsigned long full;
+ u64 full;
};
void rdt_ctrl_update(void *arg);
--
2.43.0
^ permalink raw reply related
* [PATCH 1/2] x86/resctrl, Documentation: Keep mbm_assign_mode "default" on boot
From: Babu Moger @ 2026-07-17 21:13 UTC (permalink / raw)
To: babu.moger, tony.luck, reinette.chatre, bp
Cc: x86, Dave.Martin, james.morse, corbet, skhan, tglx, mingo,
dave.hansen, hpa, linux-kernel, linux-doc, eranian, peternewman
The kernel currently enables the ABMC-based "mbm_event" mode by default on
hardware that supports it. However, this can cause bandwidth monitoring
failures with existing userspace tools such as pqos.
The pqos tool mounts the resctrl filesystem and creates 16 or more resctrl
groups by default. On systems with 32 or fewer ABMC counters, this default
configuration can consume all available counters, since each group requires
one counter for local MBM and another for total MBM. If additional
monitoring groups are created, counter resources are exhausted and pqos
tool reports memory bandwidth counters as zero for those groups.
Avoid this compatibility issue by leaving mbm_assign_mode in the "default"
mode during initialization. Users who want to use ABMC can continue to
enable it explicitly:
echo mbm_event > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
Update the resctrl documentation to reflect the new boot-time default and
adjust the mbm_assign_mode examples accordingly.
Signed-off-by: Babu Moger <babu.moger@amd.com>
---
There are plans to enable "mbm_event" by default once additional counters
are available. For now, keep the default mode to maintain compatibility
with existing tools.
---
Documentation/filesystems/resctrl.rst | 71 ++++++++++++++++-----------
arch/x86/kernel/cpu/resctrl/monitor.c | 1 -
2 files changed, 42 insertions(+), 30 deletions(-)
diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index e4b66af55ffb..e38bfd15fc3d 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -355,8 +355,8 @@ with the following files:
::
# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
- [mbm_event]
- default
+ [default]
+ mbm_event
"mbm_event":
@@ -375,19 +375,23 @@ with the following files:
to the events. Otherwise, the MBM event counters will return 'Unassigned' when read.
The mode is beneficial for AMD platforms that support more CTRL_MON
- and MON groups than available hardware counters. By default, this
- feature is enabled on AMD platforms with the ABMC (Assignable Bandwidth
- Monitoring Counters) capability, ensuring counters remain assigned even
- when the corresponding RMID is not actively used by any processor.
+ and MON groups than available hardware counters. On platforms with the
+ ABMC (Assignable Bandwidth Monitoring Counters) capability, mbm_event
+ mode ensures counters remain assigned even when the corresponding RMID
+ is not actively used by any processor.
"default":
In default mode, resctrl assumes there is a hardware counter for each
- event within every CTRL_MON and MON group. On AMD platforms, it is
- recommended to use the mbm_event mode, if supported, to prevent reset of MBM
- events between reads resulting from hardware re-allocating counters. This can
- result in misleading values or display "Unavailable" if no counter is assigned
- to the event.
+ event within every CTRL_MON and MON group. This mode is enabled by default.
+
+ On AMD platforms with more CTRL_MON and MON groups than the available
+ hardware counters, hardware may re-allocate counters between reads
+ while in default mode. This can result in misleading memory bandwidth values
+ or display "Unavailable" if no counter is allocated to the event. In such
+ cases, it is recommended to use the mbm_event mode, if supported, to prevent
+ reset of MBM events between reads resulting from hardware re-allocating
+ counters.
* To enable "mbm_event" counter assignment mode:
::
@@ -471,8 +475,8 @@ with the following files:
Determines if a counter will automatically be assigned to an RMID, MBM event
pair when its associated monitor group is created via mkdir. Enabled by default
- on boot, also when switched from "default" mode to "mbm_event" counter assignment
- mode. Users can disable this capability by writing to the interface.
+ when switched to "mbm_event" counter assignment mode. Users can disable this
+ capability by writing to the interface.
"0":
Auto assignment is disabled.
@@ -1788,32 +1792,41 @@ a. Check if MBM counter assignment mode is supported.
# mount -t resctrl resctrl /sys/fs/resctrl/
+ # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
+ [default]
+ mbm_event
+
+The "mbm_event" and "default" modes are supported. The "default" mode
+is enabled by default.
+
+b. Enable "mbm_event" counter assignment mode.
+::
+
+ # echo "mbm_event" > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
[mbm_event]
default
-The "mbm_event" mode is detected and enabled.
-
-b. Check how many assignable counters are supported.
+c. Check how many assignable counters are supported.
::
# cat /sys/fs/resctrl/info/L3_MON/num_mbm_cntrs
0=32;1=32
-c. Check how many assignable counters are available for assignment in each domain.
+d. Check how many assignable counters are available for assignment in each domain.
::
# cat /sys/fs/resctrl/info/L3_MON/available_mbm_cntrs
0=30;1=30
-d. To list the default group's assign states.
+e. To list the default group's assign states.
::
# cat /sys/fs/resctrl/mbm_L3_assignments
mbm_total_bytes:0=e;1=e
mbm_local_bytes:0=e;1=e
-e. To unassign the counter associated with the mbm_total_bytes event on domain 0.
+f. To unassign the counter associated with the mbm_total_bytes event on domain 0.
::
# echo "mbm_total_bytes:0=_" > /sys/fs/resctrl/mbm_L3_assignments
@@ -1821,7 +1834,7 @@ e. To unassign the counter associated with the mbm_total_bytes event on domain
mbm_total_bytes:0=_;1=e
mbm_local_bytes:0=e;1=e
-f. To unassign the counter associated with the mbm_total_bytes event on all domains.
+g. To unassign the counter associated with the mbm_total_bytes event on all domains.
::
# echo "mbm_total_bytes:*=_" > /sys/fs/resctrl/mbm_L3_assignments
@@ -1829,7 +1842,7 @@ f. To unassign the counter associated with the mbm_total_bytes event on all doma
mbm_total_bytes:0=_;1=_
mbm_local_bytes:0=e;1=e
-g. To assign a counter associated with the mbm_total_bytes event on all domains in
+h. To assign a counter associated with the mbm_total_bytes event on all domains in
exclusive mode.
::
@@ -1838,7 +1851,7 @@ exclusive mode.
mbm_total_bytes:0=e;1=e
mbm_local_bytes:0=e;1=e
-h. Read the events mbm_total_bytes and mbm_local_bytes of the default group. There is
+i. Read the events mbm_total_bytes and mbm_local_bytes of the default group. There is
no change in reading the events with the assignment.
::
@@ -1851,7 +1864,7 @@ no change in reading the events with the assignment.
# cat /sys/fs/resctrl/mon_data/mon_L3_01/mbm_local_bytes
121212144
-i. Check the event configurations.
+j. Check the event configurations.
::
# cat /sys/fs/resctrl/info/L3_MON/event_configs/mbm_total_bytes/event_filter
@@ -1861,7 +1874,7 @@ i. Check the event configurations.
# cat /sys/fs/resctrl/info/L3_MON/event_configs/mbm_local_bytes/event_filter
local_reads,local_non_temporal_writes,local_reads_slow_memory
-j. Change the event configuration for mbm_local_bytes.
+k. Change the event configuration for mbm_local_bytes.
::
# echo "local_reads, local_non_temporal_writes, local_reads_slow_memory, remote_reads" >
@@ -1870,7 +1883,7 @@ j. Change the event configuration for mbm_local_bytes.
# cat /sys/fs/resctrl/info/L3_MON/event_configs/mbm_local_bytes/event_filter
local_reads,local_non_temporal_writes,local_reads_slow_memory,remote_reads
-k. Now read the local events again. The first read may come back with "Unavailable"
+l. Now read the local events again. The first read may come back with "Unavailable"
status. The subsequent read of mbm_local_bytes will display the current value.
::
@@ -1883,9 +1896,9 @@ status. The subsequent read of mbm_local_bytes will display the current value.
# cat /sys/fs/resctrl/mon_data/mon_L3_01/mbm_local_bytes
1566565
-l. Users have the option to go back to 'default' mbm_assign_mode if required. This can be
-done using the following command. Note that switching the mbm_assign_mode may reset all
-the MBM counters (and thus all MBM events) of all the resctrl groups.
+m. Users have the option to switch back to 'default' mbm_assign_mode if required. This
+can be done using the following command. Note that switching the mbm_assign_mode may
+reset all the MBM counters (and thus all MBM events) of all the resctrl groups.
::
# echo "default" > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
@@ -1893,7 +1906,7 @@ the MBM counters (and thus all MBM events) of all the resctrl groups.
mbm_event
[default]
-m. Unmount the resctrl filesystem.
+n. Unmount the resctrl filesystem.
::
# umount /sys/fs/resctrl/
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 3838e0a13d36..8a0d6086518b 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -471,7 +471,6 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
r->mon.mbm_cntr_configurable = true;
cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1;
- hw_res->mbm_cntr_assign_enabled = true;
}
r->mon_capable = true;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v7 3/3] iommu/arm-smmu-v3: Enable CFGI/TLBI-repeat workaround on Tegra264
From: Jason Gunthorpe @ 2026-07-17 20:19 UTC (permalink / raw)
To: Ashish Mhetre
Cc: catalin.marinas, will, corbet, skhan, robin.murphy, joro,
nicolinc, linux-arm-kernel, linux-doc, linux-kernel, iommu,
linux-tegra
In-Reply-To: <20260714104202.1664187-4-amhetre@nvidia.com>
On Tue, Jul 14, 2026 at 10:42:02AM +0000, Ashish Mhetre wrote:
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -5357,8 +5357,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
> if (of_dma_is_coherent(dev->of_node))
> smmu->features |= ARM_SMMU_FEAT_COHERENCY;
>
> - if (of_device_is_compatible(dev->of_node, "nvidia,tegra264-smmu"))
> + if (of_device_is_compatible(dev->of_node, "nvidia,tegra264-smmu")) {
> tegra_cmdqv_dt_probe(dev->of_node, smmu);
> + static_branch_enable(&arm_smmu_erratum_repeat_tlbi_cfgi_key);
> + }
It is a bit of a big hammer to not have the per-instance FEAT but it
probably doesn't matter
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply
* Re: [PATCH v7 2/3] iommu/arm-smmu-v3: Introduce CFGI/TLBI-repeat workaround infrastructure
From: Jason Gunthorpe @ 2026-07-17 20:18 UTC (permalink / raw)
To: Ashish Mhetre
Cc: catalin.marinas, will, corbet, skhan, robin.murphy, joro,
nicolinc, linux-arm-kernel, linux-doc, linux-kernel, iommu,
linux-tegra
In-Reply-To: <20260714104202.1664187-3-amhetre@nvidia.com>
On Tue, Jul 14, 2026 at 10:42:01AM +0000, Ashish Mhetre wrote:
> Tegra264 SMMU instances need every CFGI/TLBI command sequence issued
> twice, with the second issue executing only after the first issue's
> CMD_SYNC has completed:
>
> TLBI/CFGI ... CMD_SYNC TLBI/CFGI ... CMD_SYNC
>
> ATC_INV is not affected and must never be doubled.
>
> Add arm_smmu_erratum_repeat_tlbi_cfgi_key and an
> arm_smmu_erratum_cmd_needs_repeating() helper that gates on the static
> key first and then range-checks the opcode (CFGI_STE .. ATC_INV), so
> subsequent changes wiring the workaround into the CMDQ submission and
> iommufd batching paths can share a single predicate.
>
> Rename the existing arm_smmu_cmdq_issue_cmdlist() to
> __arm_smmu_cmdq_issue_cmdlist() and add a thin wrapper that re-issues
> the same cmdlist a second time when the predicate fires. Register the
> new condition with arm_smmu_cmdq_batch_force_sync() and add
> arm_vsmmu_can_batch_cmd() so iommufd batches split at every "needs
> repeating" transition.
>
> No callers enable the static key yet, so there is no functional change.
> A subsequent change will enable the key on affected instances.
>
> Suggested-by: Nicolin Chen <nicolinc@nvidia.com>
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
> ---
> .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 14 ++++-
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 57 +++++++++++++++++--
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 +
> 3 files changed, 67 insertions(+), 5 deletions(-)
Because the VM has access to VCMDQ/etc it can issue commands directly
(maybe not on this chip, but as a general comment), thus invalidation
errata need to be made visible to the VM and we need to expect the VM
will generate invalidations to properly deal with any errata.
Ie I'd expect the VM to see a "nvidia,tegra264-smmu" compatible string
to activate the errata fix.
If so then we will already get duplicated invalidations here and then
we will duplicate them again. That's not great.
On the other hand if you want to emulate a generic and actually
functional SMMU device that has nothing like VCMDQ/etc then you must
do something like this in this patch.
I was imagining a general direction that we would expose the errata
information to the guest and the guest would have to deal with it.
Given this is the opposite I wonder if we want to do it. It does make
sense for a chip that probably doesn't have vCMDQ and I don't think
qemu can even create a DT description to trigger the errata anyhow.
But it starts to become confusing down the road if we decide other
invalidation errata (like the CONT must be RIL thing) must be delt
with by the guest.
So.. Maybe add a comment why this one is different, or maybe just
disable FEAT_NESTING if there isn't a use case?
Otherwise the rest is fine
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply
* Re: [RFC PATCH v1 8/8] misc/arm-cla: Add userspace interface
From: Arnd Bergmann @ 2026-07-17 20:11 UTC (permalink / raw)
To: Ryan Roberts, Greg Kroah-Hartman, Catalin Marinas, Will Deacon,
Mark Rutland, Jean-Philippe Brucker, Oded Gabbay, Jonathan Corbet
Cc: linux-kernel, linux-arm-kernel, dri-devel, linux-doc
In-Reply-To: <2a69d96e-d37e-4e3d-8eaa-3ea31caf3893@arm.com>
On Fri, Jul 17, 2026, at 18:21, Ryan Roberts wrote:
> On 17/07/2026 16:31, Arnd Bergmann wrote:
>>
>> Without concrete implementation examples, I find it hard to imagine
>> how granular the CLA and accelerator blocks are. What I'm interested
>> in is separating things into special character devices when they
>> refer to units that you want to manage separately in userspace.
>>
>> If you have e.g. one accelerator for tensor operations and one for
>> handling gzip, I would very much want to see those have a separate
>> chardev nodes so a local administrator can give permissions to each
>> one separately, and have device names that are sensible to the
>> functionality underneath.
>
> Unfortunately this doesn't map well to the HW: the MMIO is for the
> CLA interface (each CPU has 1 CLA).
I'm sure you mentioned it in the documentation, but I missed that
there are never multiple CLA instances.
If the CLA is defined only in terms of its MMIO/DMA interface
and listening to TLB broadcast operations, is having a single
instance actually required by the design, or just an implementation
choice?
> Once you have access to that interface, you can
> communicate with all of the accelerators that are connected to the CLA. We could
> potentially use the availability masking control to only expose a single
> accelerator for a given context (which would be chosen based on which file you
> opened), but it wouldn't be possible for (e.g.) 2 different processes to access
> the different accelerators concurrently - they would have to be subject to the
> time slice model.
Right, that sounds a bit awkward. It sounds like this would also get
simpler with a model that ensures the current CLA ttbr0 matches the
CPU ttbr0 and the iotlb_mm setting, since you would never have concurrent
uses of a single CLA from multipel tasks. On the other hand, that
model would make it harder to use multiple accelerators from a
single task, if they have to go through multiple file descriptors
but could be accessed on a single mapping.
>> If you have separate accelerators for AES encryption and decryption,
>> or a large set of identical accelerators that can run concurrently,
>> those would of course get managed as a single device file.
>>
>> Most importantly, I don't think a global /dev/cla device node
>> is a sensible interface from a management perspective as that
>> would give unprivileged userspace direct control to something
>> that is essentially arbitrary (or buggy) vendor firmware
>> with DMA permissions.
>
> OK I see your point.
>
> While the interface supports up to 8 connected accelerators, we anticpate there
> only being a single compute accelerator in practice. We decided to keep the
> driver interface generic given the CLA spec, but perhaps it would be more
> straightforward to limit the driver implementation to only permitting a single
> accelerator?
Probably, yes. From a kernel perspective, I think we're a bit better
off with an abstraction like
- One CLA MMIO range per /type/ of accelerator on a given CPU
- One firmware node per CLA, possibly spanning multiple CPUs
if the accelerators behind them are shared.
- One character device per firmware node, named according to the
type of CLA
- Possibly multiple CLA nodes on a given CPU if multiple
unrelated accelerators are present
- optionally multiple related accelerators on the eight ports of
a CLA, if that makes sense for that device type
Not sure how far that is off from what you currently have in
the hardware design.
Arnd
^ permalink raw reply
* Re: [PATCH v7 1/3] iommu/arm-smmu-v3: Factor out CMDQ batch force-sync conditions
From: Jason Gunthorpe @ 2026-07-17 19:59 UTC (permalink / raw)
To: Ashish Mhetre
Cc: catalin.marinas, will, corbet, skhan, robin.murphy, joro,
nicolinc, linux-arm-kernel, linux-doc, linux-kernel, iommu,
linux-tegra
In-Reply-To: <20260714104202.1664187-2-amhetre@nvidia.com>
On Tue, Jul 14, 2026 at 10:42:00AM +0000, Ashish Mhetre wrote:
> From: Nicolin Chen <nicolinc@nvidia.com>
>
> arm_smmu_cmdq_batch_add_cmd_p() carries two distinct reasons for
> flushing the current batch with a CMD_SYNC before appending the
> new command:
>
> - The batch's pre-assigned cmdq does not support the new command.
> - The Arm erratum 2812531 workaround (ARM_SMMU_OPT_CMDQ_FORCE_SYNC)
> forces a SYNC at one entry before the batch is full.
>
> Lift those checks into a new arm_smmu_cmdq_batch_force_sync() helper
> so that adding another force-sync condition becomes a one-line
> addition. No functional change.
>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 +++++++++++++++------
> 1 file changed, 17 insertions(+), 6 deletions(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply
* [PATCH 2/2] USB: hub: Split announce_device() to log device identity before enumeration
From: Nikhil Solanke @ 2026-07-17 19:53 UTC (permalink / raw)
To: linux-usb
Cc: gregkh, linux-kernel, stern, michal.pecio, corbet, skhan,
linux-doc, stable, Nikhil Solanke
In-Reply-To: <20260717195336.98500-1-nikhilsolanke5@gmail.com>
announce_device() currently logs the device VID:PID and string
descriptors only after successful enumeration. This means that if
enumeration fails, no identifying information about the device appears
in the kernel log, making it difficult to diagnose failures.
Split announce_device() into announce_device_ids(), which logs the
VID:PID and bcdDevice immediately after the device descriptor is read,
and announce_device_strings(), which logs the product, manufacturer,
and serial number strings after successful enumeration. This ensures
that a device's identity is always visible in the log regardless of
whether enumeration succeeds or fails.
Suggested-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Nikhil Solanke <nikhilsolanke5@gmail.com>
---
drivers/usb/core/hub.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5262e11c12cd..d92bf887739d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2401,7 +2401,7 @@ static void show_string(struct usb_device *udev, char *id, char *string)
dev_info(&udev->dev, "%s: %s\n", id, string);
}
-static void announce_device(struct usb_device *udev)
+static void announce_device_ids(struct usb_device *udev)
{
u16 bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
@@ -2410,6 +2410,10 @@ static void announce_device(struct usb_device *udev)
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
bcdDevice >> 8, bcdDevice & 0xff);
+}
+
+static void announce_device_strings(struct usb_device *udev)
+{
dev_info(&udev->dev,
"New USB device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
udev->descriptor.iManufacturer,
@@ -2420,7 +2424,8 @@ static void announce_device(struct usb_device *udev)
show_string(udev, "SerialNumber", udev->serial);
}
#else
-static inline void announce_device(struct usb_device *udev) { }
+static inline void announce_device_ids(struct usb_device *udev) { }
+static inline void announce_device_strings(struct usb_device *udev) { }
#endif
@@ -2651,6 +2656,9 @@ int usb_new_device(struct usb_device *udev)
device_init_wakeup(&udev->dev, 0);
}
+ /* Announce the device identity */
+ announce_device_ids(udev);
+
/* Tell the runtime-PM framework the device is active */
pm_runtime_set_active(&udev->dev);
pm_runtime_get_noresume(&udev->dev);
@@ -2672,8 +2680,8 @@ int usb_new_device(struct usb_device *udev)
udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
- /* Tell the world! */
- announce_device(udev);
+ /* Announce the device's product, manufacturer and serial number */
+ announce_device_strings(udev);
if (udev->serial)
add_device_randomness(udev->serial, strlen(udev->serial));
--
2.55.0
^ permalink raw reply related
* [PATCH 1/2] usbcore: Add quirk for 255-bytes initial config read
From: Nikhil Solanke @ 2026-07-17 19:53 UTC (permalink / raw)
To: linux-usb
Cc: gregkh, linux-kernel, stern, michal.pecio, corbet, skhan,
linux-doc, stable, Nikhil Solanke
In-Reply-To: <20260717195336.98500-1-nikhilsolanke5@gmail.com>
Certain third-party USB game controllers exposing (or spoofing) an Xbox
360-compatible interface (VID:PID 045e:028e) fail to enumerate under Linux.
The device disconnects from the bus without responding to the initial
GET_DESCRIPTOR(CONFIGURATION) request, and the kernel logs 'unable to read
config index 0 descriptor/start: -71'.
The device then falls back to a secondary Android HID mode (with a
different VID:PID), losing XInput functionality including rumble support.
The failure reproduces across multiple machines, host controller types, and
kernel versions including current mainline and LTS. The device enumerates
correctly and remains in XInput mode under Windows. Notably, the device
enumerates correctly in Android mode when the same 9-byte request
is issued for that mode's configuration descriptor, confirming the firmware
bug is specific to the XInput mode.
usbmon traces from Linux and Wireshark/USBPcap traces from Windows are
identical up to the point of failure, with no visible protocol-level
difference explaining the divergence. The root cause was identified when
Michal Pecio discovered via a QEMU bus-level capture that Windows does not
use wLength=9 for the initial config descriptor request; it uses
wLength=255. Alan Stern subsequently confirmed this with a bus
analyzer on a different USB 2.0 device, and Michal verified the behavior
goes back to Windows 95 OSR2.1.
So, add a new quirk flag USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE which causes
usb_get_configuration() to issue a 255 byte sized configuration request
instead of USB_DT_CONFIG_SIZE (9) for the initial
GET_DESCRIPTOR(CONFIGURATION) request, mimicking long-standing Windows
behavior.
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Suggested-by: Michal Pecio <michal.pecio@gmail.com>
Closes: https://lore.kernel.org/linux-usb/CAFgddh+JWdT4LLwMc5qjM8q_pBu-fRo2qADR5ovAKoGHWMQrRw@mail.gmail.com/
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Nikhil Solanke <nikhilsolanke5@gmail.com>
---
.../admin-guide/kernel-parameters.txt | 10 +++++
drivers/usb/core/config.c | 39 +++++++++++++++----
drivers/usb/core/quirks.c | 4 ++
include/linux/usb/quirks.h | 3 ++
4 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index b5493a7f8f22..14121458a0c0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -8169,6 +8169,16 @@ Kernel parameters
q = USB_QUIRK_FORCE_ONE_CONFIG (Device
claims zero configurations,
forcing to 1);
+ r = USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE (Device
+ fails during initialization when asked for
+ 9-bytes configuration descriptor request.
+ Ask for 255-bytes request instead to mirror
+ Windows' behavior. This quirk is originally
+ meant to fix some quirky gamepads that refuse
+ to connect in their XInput mode. But it can
+ also potentially fix issues with other USB
+ devices that work on Windows but not on
+ Linux);
Example: quirks=0781:5580:bk,0a5c:5834:gij
usbhid.mousepoll=
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 45e20c6d76c0..442c15f92ccd 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -912,6 +912,17 @@ int usb_get_configuration(struct usb_device *dev)
unsigned char *bigbuffer;
struct usb_config_descriptor *desc;
int result;
+ size_t usb_config_req_size;
+
+ /*
+ * Devices with quirky firmware will stall or reset when the initial
+ * config descriptor request uses wLength=9. If the quirk is set, use
+ * 255 instead, mirroring the behavior of Windows.
+ */
+ if (dev->quirks & USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE)
+ usb_config_req_size = 255;
+ else
+ usb_config_req_size = USB_DT_CONFIG_SIZE;
if (ncfg > USB_MAXCONFIG) {
dev_notice(ddev, "too many configurations: %d, "
@@ -938,15 +949,19 @@ int usb_get_configuration(struct usb_device *dev)
if (!dev->rawdescriptors)
return -ENOMEM;
- desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
+ desc = kmalloc(usb_config_req_size, GFP_KERNEL);
if (!desc)
return -ENOMEM;
for (cfgno = 0; cfgno < ncfg; cfgno++) {
- /* We grab just the first descriptor so we know how long
- * the whole configuration is */
+ /*
+ * Normally we request only the configuration descriptor header
+ * so we can determine the total configuration length. For
+ * devices with USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE set, try to
+ * grab the full descriptor set instead.
+ */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
- desc, USB_DT_CONFIG_SIZE);
+ desc, usb_config_req_size);
if (result < 0) {
dev_err(ddev, "unable to read config index %d "
"descriptor/%s: %d\n", cfgno, "start", result);
@@ -956,9 +971,8 @@ int usb_get_configuration(struct usb_device *dev)
dev->descriptor.bNumConfigurations = cfgno;
break;
} else if (result < 4) {
- dev_err(ddev, "config index %d descriptor too short "
- "(expected %i, got %i)\n", cfgno,
- USB_DT_CONFIG_SIZE, result);
+ dev_err(ddev, "config index %d descriptor too short (asked for %zu, got %i, need at least %i)\n",
+ cfgno, usb_config_req_size, result, 4);
result = -EINVAL;
goto err;
}
@@ -972,6 +986,16 @@ int usb_get_configuration(struct usb_device *dev)
goto err;
}
+ /*
+ * If the device returns the full configuration descriptor set,
+ * skip the second read. Otherwise, send a second request
+ * asking for the full set.
+ */
+ if (result >= length) {
+ memcpy(bigbuffer, desc, length);
+ goto store_and_parse;
+ }
+
if (dev->quirks & USB_QUIRK_DELAY_INIT)
msleep(200);
@@ -989,6 +1013,7 @@ int usb_get_configuration(struct usb_device *dev)
length = result;
}
+store_and_parse:
dev->rawdescriptors[cfgno] = bigbuffer;
result = usb_parse_configuration(dev, cfgno,
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 87ee2d938bc0..f5a60ccf21d3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -142,6 +142,10 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
break;
case 'q':
flags |= USB_QUIRK_FORCE_ONE_CONFIG;
+ break;
+ case 'r':
+ flags |= USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE;
+ break;
/* Ignore unrecognized flag characters */
}
}
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index b3cc7beab4a3..a4043b33c2c2 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -81,4 +81,7 @@
/* Device claims zero configurations, forcing to 1 */
#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18)
+/* Use a 255 bytes config descriptor request mirroring windows behavior */
+#define USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE BIT(19)
+
#endif /* __LINUX_USB_QUIRKS_H */
--
2.55.0
^ permalink raw reply related
* [PATCH 0/2] usbcore: Add quirk for 255-byte initial config read
From: Nikhil Solanke @ 2026-07-17 19:53 UTC (permalink / raw)
To: linux-usb
Cc: gregkh, linux-kernel, stern, michal.pecio, corbet, skhan,
linux-doc, stable, Nikhil Solanke
This series adds a quirk for USB devices that fail enumeration when
the initial GET_DESCRIPTOR(CONFIGURATION) request uses wLength=9.
Patch 1 adds USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE which causes
usb_get_configuration() to use wLength=255 for the initial config
descriptor request, mirroring long-standing Windows behavior.
Patch 2 splits announce_device() to log device identity before
enumeration, improving failure diagnosis.
Nikhil Solanke (2):
usbcore: Add quirk for 255-bytes initial config read
USB: hub: Split announce_device() to log device identity before
enumeration
.../admin-guide/kernel-parameters.txt | 10 +++++
drivers/usb/core/config.c | 39 +++++++++++++++----
drivers/usb/core/hub.c | 16 ++++++--
drivers/usb/core/quirks.c | 4 ++
include/linux/usb/quirks.h | 3 ++
5 files changed, 61 insertions(+), 11 deletions(-)
--
2.55.0
^ permalink raw reply
* Re: [PATCH v7 01/12] PCI: liveupdate: Set up FLB handler for the PCI core
From: Pasha Tatashin @ 2026-07-17 19:42 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <178431652443.189683.17611165218179620081.b4-review@b4>
On 07-17 19:28, Pasha Tatashin wrote:
> On Fri, 10 Jul 2026 21:26:04 +0000, David Matlack <dmatlack@google.com> wrote:
> > diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> > new file mode 100644
> > index 000000000000..899758883dd5
> > --- /dev/null
> > +++ b/drivers/pci/liveupdate.c
> > @@ -0,0 +1,155 @@
> > [ ... skip 50 lines ... ]
> > +#include <linux/slab.h>
> > +
> > +/**
> > + * struct pci_flb_outgoing - Outgoing PCI FLB object
> > + * @ser: Pointer to the preserved struct pci_ser.
> > + * @block_set: The KHO block set holding the outgoing devices.
>
> AFAIK, these should be aligned after column:
> @ser: Pointer to ...
> @block_set: The KHO block ...
>
> > [ ... skip 26 lines ... ]
> > + ser->devices = 0;
> > +
> > + outgoing->ser = ser;
> > + kho_block_set_init(&outgoing->block_set, sizeof(struct pci_dev_ser));
> > +
> > + args->obj = outgoing;
>
> Nit:
> You could re-write the above:
>
> args->obj = no_free_ptr(outgoing);
>
> And declare outgoing like this:
> struct pci_flb_outgoing *outgoing __free(kfree) = kzalloc_obj(*outgoing);
>
> Also, remove kfree(outgoing) call.
>
> >
> > diff --git a/include/linux/kho/abi/pci.h b/include/linux/kho/abi/pci.h
> > new file mode 100644
> > index 000000000000..de549016807a
> > --- /dev/null
> > +++ b/include/linux/kho/abi/pci.h
> > @@ -0,0 +1,58 @@
> > [ ... skip 30 lines ... ]
> > + * @domain: The device's PCI domain number (segment).
> > + * @bdf: The device's PCI bus, device, and function number.
> > + * @refcount: Reference count used by the PCI core to keep track of whether it
> > + * is done using a device's struct pci_dev_ser. The value of the
> > + * refcount is equal to 1 when the struct pci_dev_ser is in use, and
> > + * 0 otherwise.
>
> I believe descriptions must be aligned.
>
> > + */
> > +struct pci_dev_ser {
> > + u32 domain;
> > + u16 bdf;
> > + u16 refcount;
> > +} __packed;
> > +
> > +/**
> > + * struct pci_ser - PCI Subsystem Live Update State
> > + *
> > + * This struct tracks state about all devices that are being preserved across
> > + * a Live Update for the next kernel.
> > + *
> > + * @nr_devices: The number of devices that were preserved.
> > + * @devices: Physical address of the first KHO block containing pci_dev_ser.
>
> I believe descriptions must be aligned.
>
> Nit: Please order the included headers alphabetically.
>
> Nit: Please order the included headers alphabetically.
The above was supposed to be right after #include, but b4 had a mind
of its own.
>
> --
> Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 01/12] PCI: liveupdate: Set up FLB handler for the PCI core
From: Pasha Tatashin @ 2026-07-17 19:40 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Pasha Tatashin, David Matlack, kexec, linux-doc, linux-kernel,
linux-mm, linux-pci, Adithya Jayachandran, Alexander Graf,
Alex Williamson, Bjorn Helgaas, Chris Li, David Rientjes,
Jacob Pan, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pranjal Shrivastava,
Pratyush Yadav, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260717193055.GD699082@nvidia.com>
On 07-17 16:30, Jason Gunthorpe wrote:
> On Fri, Jul 17, 2026 at 07:28:44PM +0000, Pasha Tatashin wrote:
> > On Fri, 10 Jul 2026 21:26:04 +0000, David Matlack <dmatlack@google.com> wrote:
> > > diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> > > new file mode 100644
> > > index 000000000000..899758883dd5
> > > --- /dev/null
> > > +++ b/drivers/pci/liveupdate.c
> > > @@ -0,0 +1,155 @@
> > > [ ... skip 50 lines ... ]
> > > +#include <linux/slab.h>
> > > +
> > > +/**
> > > + * struct pci_flb_outgoing - Outgoing PCI FLB object
> > > + * @ser: Pointer to the preserved struct pci_ser.
> > > + * @block_set: The KHO block set holding the outgoing devices.
> >
> > AFAIK, these should be aligned after column:
> > @ser: Pointer to ...
> > @block_set: The KHO block ...
>
> Gosh I hope not, I never do that. The horizontal alignment is such a
> PITA to maintain.
Agreed. I just see that everywhere, so I thought it was the rule. If
not, that is great; I hate them myself.
>
> Jason
^ permalink raw reply
* Re: [PATCH v7 02/12] PCI: liveupdate: Track outgoing preserved PCI devices
From: Pasha Tatashin @ 2026-07-17 19:38 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-3-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:05 +0000, David Matlack <dmatlack@google.com> wrote:
> diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> index 899758883dd5..03075ce06ac9 100644
> --- a/drivers/pci/liveupdate.c
> +++ b/drivers/pci/liveupdate.c
> @@ -125,6 +160,157 @@ static struct liveupdate_flb pci_liveupdate_flb = {
> [ ... skip 18 lines ... ]
> +static struct pci_dev_ser *pci_get_empty_or_append(struct pci_flb_outgoing *outgoing)
> +{
> + struct pci_dev_ser *dev_ser, *found = NULL;
> + struct kho_block_set_it it;
> + int err;
> + u32 count = 0;
Nit, please move count above err, to follow reverse-christmas-tree order
for declarations.
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
* Re: [PATCH v7 01/12] PCI: liveupdate: Set up FLB handler for the PCI core
From: Jason Gunthorpe @ 2026-07-17 19:30 UTC (permalink / raw)
To: Pasha Tatashin
Cc: David Matlack, kexec, linux-doc, linux-kernel, linux-mm,
linux-pci, Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jonathan Corbet, Josh Hilke, Leon Romanovsky, Lukas Wunner,
Mike Rapoport, Parav Pandit, Pranjal Shrivastava, Pratyush Yadav,
Saeed Mahameed, Samiullah Khawaja, Shuah Khan, Vipin Sharma,
William Tu, Yi Liu
In-Reply-To: <178431652443.189683.17611165218179620081.b4-review@b4>
On Fri, Jul 17, 2026 at 07:28:44PM +0000, Pasha Tatashin wrote:
> On Fri, 10 Jul 2026 21:26:04 +0000, David Matlack <dmatlack@google.com> wrote:
> > diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> > new file mode 100644
> > index 000000000000..899758883dd5
> > --- /dev/null
> > +++ b/drivers/pci/liveupdate.c
> > @@ -0,0 +1,155 @@
> > [ ... skip 50 lines ... ]
> > +#include <linux/slab.h>
> > +
> > +/**
> > + * struct pci_flb_outgoing - Outgoing PCI FLB object
> > + * @ser: Pointer to the preserved struct pci_ser.
> > + * @block_set: The KHO block set holding the outgoing devices.
>
> AFAIK, these should be aligned after column:
> @ser: Pointer to ...
> @block_set: The KHO block ...
Gosh I hope not, I never do that. The horizontal alignment is such a
PITA to maintain.
Jason
^ permalink raw reply
* Re: [PATCH v7 01/12] PCI: liveupdate: Set up FLB handler for the PCI core
From: Pasha Tatashin @ 2026-07-17 19:28 UTC (permalink / raw)
To: David Matlack
Cc: kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260710212616.1351130-2-dmatlack@google.com>
On Fri, 10 Jul 2026 21:26:04 +0000, David Matlack <dmatlack@google.com> wrote:
> diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> new file mode 100644
> index 000000000000..899758883dd5
> --- /dev/null
> +++ b/drivers/pci/liveupdate.c
> @@ -0,0 +1,155 @@
> [ ... skip 50 lines ... ]
> +#include <linux/slab.h>
> +
> +/**
> + * struct pci_flb_outgoing - Outgoing PCI FLB object
> + * @ser: Pointer to the preserved struct pci_ser.
> + * @block_set: The KHO block set holding the outgoing devices.
AFAIK, these should be aligned after column:
@ser: Pointer to ...
@block_set: The KHO block ...
> [ ... skip 26 lines ... ]
> + ser->devices = 0;
> +
> + outgoing->ser = ser;
> + kho_block_set_init(&outgoing->block_set, sizeof(struct pci_dev_ser));
> +
> + args->obj = outgoing;
Nit:
You could re-write the above:
args->obj = no_free_ptr(outgoing);
And declare outgoing like this:
struct pci_flb_outgoing *outgoing __free(kfree) = kzalloc_obj(*outgoing);
Also, remove kfree(outgoing) call.
>
> diff --git a/include/linux/kho/abi/pci.h b/include/linux/kho/abi/pci.h
> new file mode 100644
> index 000000000000..de549016807a
> --- /dev/null
> +++ b/include/linux/kho/abi/pci.h
> @@ -0,0 +1,58 @@
> [ ... skip 30 lines ... ]
> + * @domain: The device's PCI domain number (segment).
> + * @bdf: The device's PCI bus, device, and function number.
> + * @refcount: Reference count used by the PCI core to keep track of whether it
> + * is done using a device's struct pci_dev_ser. The value of the
> + * refcount is equal to 1 when the struct pci_dev_ser is in use, and
> + * 0 otherwise.
I believe descriptions must be aligned.
> + */
> +struct pci_dev_ser {
> + u32 domain;
> + u16 bdf;
> + u16 refcount;
> +} __packed;
> +
> +/**
> + * struct pci_ser - PCI Subsystem Live Update State
> + *
> + * This struct tracks state about all devices that are being preserved across
> + * a Live Update for the next kernel.
> + *
> + * @nr_devices: The number of devices that were preserved.
> + * @devices: Physical address of the first KHO block containing pci_dev_ser.
I believe descriptions must be aligned.
Nit: Please order the included headers alphabetically.
Nit: Please order the included headers alphabetically.
--
Pasha Tatashin <pasha.tatashin@soleen.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox