[PATCH v5 2/2] irqchip/riscv-aplic: force synchronous probing

Anup Patel anup at brainfault.org
Tue Nov 10 00:07:14 PST 2026


On Tue, Oct 20, 2026 at 9:09 PM Vladimir Kondratiev
<vladimir.kondratiev at 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 at 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



More information about the linux-riscv mailing list