The following commit has been merged into the irq/urgent branch of tip: Commit-ID: a98a0f050ced4bd4ecb59e92412916012b7c2917 Gitweb: https://git.kernel.org/tip/a98a0f050ced4bd4ecb59e92412916012b7c2917 Author: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> AuthorDate: Mon, 14 Oct 2024 12:27:39 +05:30 Committer: Thomas Gleixner <tglx@xxxxxxxxxxxxx> CommitterDate: Tue, 15 Oct 2024 23:14:25 +02:00 irqchip/riscv-intc: Fix SMP=n boot with ACPI When CONFIG_SMP is disabled, the static array rintc_acpi_data with size NR_CPUS is not sufficient to hold all RINTC structures passed from the firmware. All RINTC structures are required to configure IMSIC/APLIC/PLIC properly irrespective of SMP in the OS. So, allocate dynamic memory based on the number of RINTC structures in MADT to fix this issue. Fixes: f8619b66bdb1 ("irqchip/riscv-intc: Add ACPI support for AIA") Reported-by: Björn Töpel <bjorn@xxxxxxxxxx> Signed-off-by: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Tested-by: Alexandre Ghiti <alexghiti@xxxxxxxxxxxx> Reviewed-by: Anup Patel <anup@xxxxxxxxxxxxxx> Link: https://lore.kernel.org/all/20241014065739.656959-1-sunilvl@xxxxxxxxxxxxxxxx Closes: https://github.com/linux-riscv/linux-riscv/actions/runs/11280997511/job/31375229012 --- drivers/irqchip/irq-riscv-intc.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c index 8c54113..f653c13 100644 --- a/drivers/irqchip/irq-riscv-intc.c +++ b/drivers/irqchip/irq-riscv-intc.c @@ -265,7 +265,7 @@ struct rintc_data { }; static u32 nr_rintc; -static struct rintc_data *rintc_acpi_data[NR_CPUS]; +static struct rintc_data **rintc_acpi_data; #define for_each_matching_plic(_plic_id) \ unsigned int _plic; \ @@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res) return 0; } +static int __init riscv_intc_acpi_match(union acpi_subtable_headers *header, + const unsigned long end) +{ + return 0; +} + static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_rintc *rintc; struct fwnode_handle *fn; + int count; int rc; + if (!rintc_acpi_data) { + count = acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, riscv_intc_acpi_match, 0); + if (count <= 0) + return -EINVAL; + + rintc_acpi_data = kcalloc(count, sizeof(*rintc_acpi_data), GFP_KERNEL); + if (!rintc_acpi_data) + return -ENOMEM; + } + rintc = (struct acpi_madt_rintc *)header; rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); if (!rintc_acpi_data[nr_rintc])