On Fri, Mar 03, 2023 at 07:06:37PM +0530, Sunil V L wrote: > Enable SMP boot on ACPI based platforms by using the RINTC > structures in the MADT table. > > Signed-off-by: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > Reviewed-by: Conor Dooley <conor.dooley@xxxxxxxxxxxxx> > --- > arch/riscv/kernel/smpboot.c | 72 ++++++++++++++++++++++++++++++++++++- > 1 file changed, 71 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c > index 26214ddefaa4..27047322d3bb 100644 > --- a/arch/riscv/kernel/smpboot.c > +++ b/arch/riscv/kernel/smpboot.c > @@ -8,6 +8,7 @@ > * Copyright (C) 2017 SiFive > */ > > +#include <linux/acpi.h> > #include <linux/arch_topology.h> > #include <linux/module.h> > #include <linux/init.h> > @@ -70,6 +71,72 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > } > } > > +#ifdef CONFIG_ACPI > +static unsigned int cpu_count = 1; > + > +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end) > +{ > + unsigned long hart; > + static bool found_boot_cpu; > + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header; > + > + /* > + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED > + * bit in the flag is not enabled, it means OS should not try to enable > + * the cpu to which RINTC belongs. > + */ > + if (!(processor->flags & ACPI_MADT_ENABLED)) > + return 0; > + > + if (BAD_MADT_ENTRY(processor, end)) > + return -EINVAL; > + > + acpi_table_print_madt_entry(&header->common); > + > + hart = processor->hart_id; > + if (hart == INVALID_HARTID) { > + pr_warn("Invalid hartid\n"); > + return 0; > + } > + > + if (hart == cpuid_to_hartid_map(0)) { > + BUG_ON(found_boot_cpu); > + found_boot_cpu = true; > + early_map_cpu_to_node(0, NUMA_NO_NODE); We should have kept static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; } and only dropped the #ifdef CONFIG_ACPI_NUMA int acpi_numa_get_nid(unsigned int cpu); #else ... #endif > + return 0; > + } > + > + if (cpu_count >= NR_CPUS) { > + pr_warn("NR_CPUS is too small for the number of ACPI tables.\n"); > + return 0; > + } > + > + cpuid_to_hartid_map(cpu_count) = hart; > + early_map_cpu_to_node(cpu_count, NUMA_NO_NODE); > + cpu_count++; > + > + return 0; > +} > + > +static void __init acpi_parse_and_init_cpus(void) > +{ > + int cpuid; > + > + cpu_set_ops(0); > + > + acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0); > + > + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) { > + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) { > + cpu_set_ops(cpuid); > + set_cpu_possible(cpuid, true); > + } > + } > +} > +#else > +#define acpi_parse_and_init_cpus(...) do { } while (0) > +#endif > + > static void __init of_parse_and_init_cpus(void) > { > struct device_node *dn; > @@ -118,7 +185,10 @@ static void __init of_parse_and_init_cpus(void) > > void __init setup_smp(void) > { > - of_parse_and_init_cpus(); > + if (acpi_disabled) > + of_parse_and_init_cpus(); > + else > + acpi_parse_and_init_cpus(); > } > > static int start_secondary_cpu(int cpu, struct task_struct *tidle) > -- > 2.34.1 > Thanks, drew