* [PATCH v5 0/2] irqchip/riscv-aplic: fix probing of multiple APLIC instances
@ 2026-10-20 15:38 Vladimir Kondratiev
2026-10-20 15:38 ` [PATCH v5 1/2] irqchip/riscv-aplic: do not mark the syscore registered flag ro_after_init Vladimir Kondratiev
2026-10-20 15:38 ` [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing Vladimir Kondratiev
0 siblings, 2 replies; 7+ messages in thread
From: Vladimir Kondratiev @ 2026-10-20 15:38 UTC (permalink / raw)
To: Anup Patel, Thomas Gleixner, Radu Rendec, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
Jessica Liu
Cc: linux-riscv, linux-kernel, linux-rt-devel, Vladimir Kondratiev
The APLIC driver does not set probe_type, so it follows
PROBE_DEFAULT_STRATEGY and gets probed asynchronously when the command
line asks for it (driver_async_probe=). The probe path of an APLIC
instance modifies state shared by all instances without any locking,
for example the registration of the syscore operations. On a system with
several APLIC instances this triggers a "list_add double add" report from
CHECK_DATA_CORRUPTION, because two instances both call register_syscore()
for the same node.
Looking at the problem showed a second, unrelated issue: the flag guarding
the syscore registration is marked __ro_after_init, but with MSI the probe
can be deferred until the IMSIC is available, and then writes the flag
after init memory was made read-only.
Patch 1 fixes the latter and is independent of asynchronous probing.
Patch 2 marks the driver PROBE_FORCE_SYNCHRONOUS. The shared state also
includes the global aplics list, aplic_direct_parent_irq (together with
the CPU hotplug state registered for it) and the per-CPU IDC structures,
so making probes mutually exclusive is simpler and less error-prone than
adding a lock for each of them. An interrupt controller is needed early
and gains nothing from probing in parallel.
Reproduced by booting with "driver_async_probe=riscv-aplic" on the
not yet upstreamed "Mobileye eyeq7h" platform with 3 APLIC instances.
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
Changes in v5:
- split the __ro_after_init fix out into its own patch
- drop atomic_t/atomic_cmpxchg() for the registration flag
- mark the driver PROBE_FORCE_SYNCHRONOUS instead of protecting each piece
of shared state separately
- Link to v4: https://patch.msgid.link/20261020-aplic-async-probe-v4-1-68bc35e0ece1@mobileye.com
Changes in v4:
- rework commit message
- rebase onto v7.3
- Link to v3: https://lore.kernel.org/r/20261012-aplic-async-probe-v3-1-5cf52dc28690@mobileye.com
Changes in v3:
- drop __ro_after_init attribute due to write to read-only page concern
- Link to v2: https://lore.kernel.org/r/20261012-aplic-async-probe-v2-1-868d7684c9d6@mobileye.com
Changes in v2:
- fixed potential access to read-only page
- Link to v1: https://lore.kernel.org/r/20261012-aplic-async-probe-v1-1-4c2c4f5b0916@mobileye.com
To: Anup Patel <anup@brainfault.org>
To: Thomas Gleixner <tglx@kernel.org>
To: Radu Rendec <radu@rendec.net>
To: Paul Walmsley <pjw@kernel.org>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
To: Alexandre Ghiti <alex@ghiti.fr>
To: Jessica Liu <liu.xuemei1@zte.com.cn>
Cc: linux-riscv@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
Vladimir Kondratiev (2):
irqchip/riscv-aplic: do not mark the syscore registered flag ro_after_init
irqchip/riscv-aplic: force synchronous probing
drivers/irqchip/irq-riscv-aplic-main.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
---
base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
change-id: 20261012-aplic-async-probe-81624e035607
Best regards,
--
Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/2] irqchip/riscv-aplic: do not mark the syscore registered flag ro_after_init
2026-10-20 15:38 [PATCH v5 0/2] irqchip/riscv-aplic: fix probing of multiple APLIC instances Vladimir Kondratiev
@ 2026-10-20 15:38 ` Vladimir Kondratiev
2026-11-09 9:22 ` [tip: irq/drivers] irqchip/riscv-aplic: Do " tip-bot2 for Vladimir Kondratiev
2026-10-20 15:38 ` [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing Vladimir Kondratiev
1 sibling, 1 reply; 7+ messages in thread
From: Vladimir Kondratiev @ 2026-10-20 15:38 UTC (permalink / raw)
To: Anup Patel, Thomas Gleixner, Radu Rendec, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
Jessica Liu
Cc: linux-riscv, linux-kernel, linux-rt-devel, Vladimir Kondratiev
aplic_syscore_registered is marked __ro_after_init, but it is written
from aplic_probe(), which can run after init. With MSI, aplic_msi_setup()
returns -EPROBE_DEFER while the MSI parent (IMSIC) is not ready, so the
later successful probe writes the flag after it has been made read-only.
That write faults.
Drop the __ro_after_init annotation so the flag stays writable.
Fixes: b330fbfd34d7 ("irqchip/riscv-aplic: Register syscore operations only once")
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
drivers/irqchip/irq-riscv-aplic-main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index d9afb6ae98cf..5369078f3d00 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -116,7 +116,11 @@ static struct syscore aplic_syscore = {
.ops = &aplic_syscore_ops,
};
-static bool aplic_syscore_registered __ro_after_init;
+/*
+ * Not __ro_after_init: probe can be deferred (e.g. MSI mode waiting for the
+ * IMSIC) and complete after the init memory is made read-only.
+ */
+static bool aplic_syscore_registered;
static void aplic_syscore_init(void)
{
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing
2026-10-20 15:38 [PATCH v5 0/2] irqchip/riscv-aplic: fix probing of multiple APLIC instances Vladimir Kondratiev
2026-10-20 15:38 ` [PATCH v5 1/2] irqchip/riscv-aplic: do not mark the syscore registered flag ro_after_init Vladimir Kondratiev
@ 2026-10-20 15:38 ` Vladimir Kondratiev
2026-11-09 9:22 ` [tip: irq/drivers] irqchip/riscv-aplic: Force " tip-bot2 for Vladimir Kondratiev
2026-11-10 8:07 ` [PATCH v5 2/2] irqchip/riscv-aplic: force " Anup Patel
1 sibling, 2 replies; 7+ messages in thread
From: Vladimir Kondratiev @ 2026-10-20 15:38 UTC (permalink / raw)
To: Anup Patel, Thomas Gleixner, Radu Rendec, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
Jessica Liu
Cc: linux-riscv, linux-kernel, linux-rt-devel, Vladimir Kondratiev
The APLIC driver leaves probe_type unset, so it follows
PROBE_DEFAULT_STRATEGY and is probed asynchronously when the command line
requests it (driver_async_probe=). The probe of an APLIC instance updates
state shared by all instances without any locking:
- the check-then-set of aplic_syscore_registered; two instances can both
observe it as false and both call register_syscore(), inserting the same
list node twice and tripping CHECK_DATA_CORRUPTION ("list_add double
add") in __list_add_valid_or_report();
- the global aplics list, modified by aplic_pm_add()/aplic_pm_remove();
- aplic_direct_parent_irq, where more than one instance can pass the check
and register its own CPU hotplug state;
Interrupt controllers are required early and have no benefit from
parallel probing, so rather than adding locks around each of them mark the
driver PROBE_FORCE_SYNCHRONOUS. Probes then run one after another from
driver registration, and deferred probe retries are serialized by the
single deferred probe work item, so the shared state is never accessed
concurrently. Probing is also blocked across suspend, so it cannot overlap
with the syscore callbacks either.
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
drivers/irqchip/irq-riscv-aplic-main.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index 5369078f3d00..3c10dbf3b492 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -118,7 +118,8 @@ static struct syscore aplic_syscore = {
/*
* Not __ro_after_init: probe can be deferred (e.g. MSI mode waiting for the
- * IMSIC) and complete after the init memory is made read-only.
+ * IMSIC) and complete after the init memory is made read-only. Probing is
+ * synchronous (see aplic_driver), so no further serialization is needed.
*/
static bool aplic_syscore_registered;
@@ -413,6 +414,12 @@ static struct platform_driver aplic_driver = {
.name = "riscv-aplic",
.of_match_table = aplic_match,
.acpi_match_table = ACPI_PTR(aplic_acpi_match),
+ /*
+ * Probes of multiple APLIC instances share global state (the
+ * syscore registration and the parent interrupt of the
+ * direct mode) and must not run concurrently.
+ */
+ .probe_type = PROBE_FORCE_SYNCHRONOUS,
},
.probe = aplic_probe,
};
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [tip: irq/drivers] irqchip/riscv-aplic: Force synchronous probing
2026-10-20 15:38 ` [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing Vladimir Kondratiev
@ 2026-11-09 9:22 ` tip-bot2 for Vladimir Kondratiev
2026-11-10 8:07 ` [PATCH v5 2/2] irqchip/riscv-aplic: force " Anup Patel
1 sibling, 0 replies; 7+ messages in thread
From: tip-bot2 for Vladimir Kondratiev @ 2026-11-09 9:22 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Vladimir Kondratiev, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 4657a03b8427864c5605147e0a9d01e2a09bfff2
Gitweb: https://git.kernel.org/tip/4657a03b8427864c5605147e0a9d01e2a09bfff2
Author: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
AuthorDate: Tue, 20 Oct 2026 18:38:49 +03:00
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Mon, 09 Nov 2026 10:20:17 +01:00
irqchip/riscv-aplic: Force synchronous probing
The APLIC driver leaves probe_type unset, so it follows
PROBE_DEFAULT_STRATEGY and is probed asynchronously when the command line
requests it (driver_async_probe=). The probe of an APLIC instance updates
state shared by all instances without any locking:
- the check-then-set of aplic_syscore_registered; two instances can both
observe it as false and both call register_syscore(), inserting the same
list node twice and tripping CHECK_DATA_CORRUPTION ("list_add double
add") in __list_add_valid_or_report();
- the global aplics list, modified by aplic_pm_add()/aplic_pm_remove();
- aplic_direct_parent_irq, where more than one instance can pass the check
and register its own CPU hotplug state;
Interrupt controllers are required early and have no benefit from
parallel probing, so rather than adding locks around each of them mark the
driver PROBE_FORCE_SYNCHRONOUS. Probes then run one after another from
driver registration, and deferred probe retries are serialized by the
single deferred probe work item, so the shared state is never accessed
concurrently. Probing is also blocked across suspend, so it cannot overlap
with the syscore callbacks either.
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20261020-aplic-async-probe-v5-2-c4861c2aafca@mobileye.com
---
drivers/irqchip/irq-riscv-aplic-main.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index a2c4d14..7e3d647 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -118,7 +118,8 @@ static struct syscore aplic_syscore = {
/*
* Not __ro_after_init: probe can be deferred (e.g. MSI mode waiting for the
- * IMSIC) and complete after the init memory is made read-only.
+ * IMSIC) and complete after the init memory is made read-only. Probing is
+ * synchronous (see aplic_driver), so no further serialization is needed.
*/
static bool aplic_syscore_registered;
@@ -413,6 +414,12 @@ static struct platform_driver aplic_driver = {
.name = "riscv-aplic",
.of_match_table = aplic_match,
.acpi_match_table = ACPI_PTR(aplic_acpi_match),
+ /*
+ * Probes of multiple APLIC instances share global state (the
+ * syscore registration and the parent interrupt of the
+ * direct mode) and must not run concurrently.
+ */
+ .probe_type = PROBE_FORCE_SYNCHRONOUS,
},
.probe = aplic_probe,
};
^ permalink raw reply [flat|nested] 7+ messages in thread
* [tip: irq/drivers] irqchip/riscv-aplic: Do not mark the syscore registered flag ro_after_init
2026-10-20 15:38 ` [PATCH v5 1/2] irqchip/riscv-aplic: do not mark the syscore registered flag ro_after_init Vladimir Kondratiev
@ 2026-11-09 9:22 ` tip-bot2 for Vladimir Kondratiev
0 siblings, 0 replies; 7+ messages in thread
From: tip-bot2 for Vladimir Kondratiev @ 2026-11-09 9:22 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Vladimir Kondratiev, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 401632b77cc38bb6de44a2e83ed7c777e540119c
Gitweb: https://git.kernel.org/tip/401632b77cc38bb6de44a2e83ed7c777e540119c
Author: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
AuthorDate: Tue, 20 Oct 2026 18:38:48 +03:00
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Mon, 09 Nov 2026 10:20:17 +01:00
irqchip/riscv-aplic: Do not mark the syscore registered flag ro_after_init
aplic_syscore_registered is marked __ro_after_init, but it is written
from aplic_probe(), which can run after init. With MSI, aplic_msi_setup()
returns -EPROBE_DEFER while the MSI parent (IMSIC) is not ready, so the
later successful probe writes the flag after it has been made read-only.
That write faults.
Drop the __ro_after_init annotation so the flag stays writable.
Fixes: b330fbfd34d7 ("irqchip/riscv-aplic: Register syscore operations only once")
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20261020-aplic-async-probe-v5-1-c4861c2aafca@mobileye.com
---
drivers/irqchip/irq-riscv-aplic-main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index 1676d64..a2c4d14 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -116,7 +116,11 @@ static struct syscore aplic_syscore = {
.ops = &aplic_syscore_ops,
};
-static bool aplic_syscore_registered __ro_after_init;
+/*
+ * Not __ro_after_init: probe can be deferred (e.g. MSI mode waiting for the
+ * IMSIC) and complete after the init memory is made read-only.
+ */
+static bool aplic_syscore_registered;
static void aplic_syscore_init(void)
{
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing
2026-10-20 15:38 ` [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing Vladimir Kondratiev
2026-11-09 9:22 ` [tip: irq/drivers] irqchip/riscv-aplic: Force " tip-bot2 for Vladimir Kondratiev
@ 2026-11-10 8:07 ` Anup Patel
2026-11-12 12:11 ` Vladimir Kondratiev
1 sibling, 1 reply; 7+ messages in thread
From: Anup Patel @ 2026-11-10 8:07 UTC (permalink / raw)
To: Vladimir Kondratiev
Cc: Thomas Gleixner, Radu Rendec, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Jessica Liu, linux-riscv,
linux-kernel, linux-rt-devel
On Tue, Oct 20, 2026 at 9:09 PM Vladimir Kondratiev
<vladimir.kondratiev@mobileye.com> wrote:
>
> The APLIC driver leaves probe_type unset, so it follows
> PROBE_DEFAULT_STRATEGY and is probed asynchronously when the command line
> requests it (driver_async_probe=). The probe of an APLIC instance updates
> state shared by all instances without any locking:
>
> - the check-then-set of aplic_syscore_registered; two instances can both
> observe it as false and both call register_syscore(), inserting the same
> list node twice and tripping CHECK_DATA_CORRUPTION ("list_add double
> add") in __list_add_valid_or_report();
> - the global aplics list, modified by aplic_pm_add()/aplic_pm_remove();
> - aplic_direct_parent_irq, where more than one instance can pass the check
> and register its own CPU hotplug state;
>
> Interrupt controllers are required early and have no benefit from
> parallel probing, so rather than adding locks around each of them mark the
> driver PROBE_FORCE_SYNCHRONOUS. Probes then run one after another from
> driver registration, and deferred probe retries are serialized by the
> single deferred probe work item, so the shared state is never accessed
> concurrently. Probing is also blocked across suspend, so it cannot overlap
> with the syscore callbacks either.
>
> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
> ---
> drivers/irqchip/irq-riscv-aplic-main.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
> index 5369078f3d00..3c10dbf3b492 100644
> --- a/drivers/irqchip/irq-riscv-aplic-main.c
> +++ b/drivers/irqchip/irq-riscv-aplic-main.c
> @@ -118,7 +118,8 @@ static struct syscore aplic_syscore = {
>
> /*
> * Not __ro_after_init: probe can be deferred (e.g. MSI mode waiting for the
> - * IMSIC) and complete after the init memory is made read-only.
> + * IMSIC) and complete after the init memory is made read-only. Probing is
> + * synchronous (see aplic_driver), so no further serialization is needed.
> */
> static bool aplic_syscore_registered;
>
> @@ -413,6 +414,12 @@ static struct platform_driver aplic_driver = {
> .name = "riscv-aplic",
> .of_match_table = aplic_match,
> .acpi_match_table = ACPI_PTR(aplic_acpi_match),
> + /*
> + * Probes of multiple APLIC instances share global state (the
> + * syscore registration and the parent interrupt of the
> + * direct mode) and must not run concurrently.
> + */
> + .probe_type = PROBE_FORCE_SYNCHRONOUS,
Making the whole driver synchronously probe is a conservative work-around.
Your original direction was good. How about the following:
1) Convert aplic_syscore_registered as atomic variable
2) Add another atomic variable aplic_direct_parent_irq_count and use
"if (!atomic_inc_return(&aplic_direct_parent_irq_count) && domain) {"
in aplic_direct_setup().
Regards,
Anup
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing
2026-11-10 8:07 ` [PATCH v5 2/2] irqchip/riscv-aplic: force " Anup Patel
@ 2026-11-12 12:11 ` Vladimir Kondratiev
0 siblings, 0 replies; 7+ messages in thread
From: Vladimir Kondratiev @ 2026-11-12 12:11 UTC (permalink / raw)
To: Anup Patel
Cc: Thomas Gleixner, Radu Rendec, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Jessica Liu, linux-riscv,
linux-kernel, linux-rt-devel
On 11/10/26 10:07, Anup Patel wrote:
> Making the whole driver synchronously probe is a conservative work-around.
>
> Your original direction was good. How about the following:
> 1) Convert aplic_syscore_registered as atomic variable
> 2) Add another atomic variable aplic_direct_parent_irq_count and use
> "if (!atomic_inc_return(&aplic_direct_parent_irq_count) && domain) {"
> in aplic_direct_setup().
I will get to it some day. For now, forcing synchronous probing is the
easiest way to get things functionally correct, even not most flexible.
Thanks, Vladimir
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-12 12:11 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-20 15:38 [PATCH v5 0/2] irqchip/riscv-aplic: fix probing of multiple APLIC instances Vladimir Kondratiev
2026-10-20 15:38 ` [PATCH v5 1/2] irqchip/riscv-aplic: do not mark the syscore registered flag ro_after_init Vladimir Kondratiev
2026-11-09 9:22 ` [tip: irq/drivers] irqchip/riscv-aplic: Do " tip-bot2 for Vladimir Kondratiev
2026-10-20 15:38 ` [PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing Vladimir Kondratiev
2026-11-09 9:22 ` [tip: irq/drivers] irqchip/riscv-aplic: Force " tip-bot2 for Vladimir Kondratiev
2026-11-10 8:07 ` [PATCH v5 2/2] irqchip/riscv-aplic: force " Anup Patel
2026-11-12 12:11 ` Vladimir Kondratiev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®