On Fri, Mar 03, 2023 at 04:49:20PM +0100, Andrew Jones wrote: > 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 > Okay, I thought we better add it when we enable NUMA with ACPI. > > + 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