summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2024-02-15 00:14:05 +1100
committerMichael Ellerman <mpe@ellerman.id.au>2024-02-15 00:14:05 +1100
commit0875f1ceba974042069f04946aa8f1d4d1e688da (patch)
tree1b835900acc1bae2de2eef1fd5230bc307263840 /arch/powerpc/kernel/prom.c
parent9832de654499f0bf797a3719c4d4c5bd401f18f5 (diff)
powerpc/smp: Remap boot CPU onto core 0 if >= nr_cpu_ids
If nr_cpu_ids is too low to include the boot CPU, remap the boot CPU onto logical core 0. This is achieved in two stages. In early_init_dt_scan_cpus() the boot CPU is renumbered to be on logical core 0, and the original boot core's hardware ID is recorded. Later in smp_setup_cpu_maps(), if the original boot core ID is set, the logical CPU numbers on the 0th core are skipped in the normal device tree search over CPU device tree nodes. Then the search is continued until the device tree node matching the boot core is found, and those CPUs are assigned the CPU numbers starting at 0. This allows kdump kernels to be booted with low values for nr_cpu_ids to conserve memory, while also allowing the crashing/boot CPU to be any CPU. Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Tested-by: Wen Xiong <wenxiong@us.ibm.com> Link: https://msgid.link/20231229120107.2281153-5-mpe@ellerman.id.au
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 77364729a1b6..f2c2f79ea477 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -368,8 +368,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
if (found < 0)
return 0;
- DBG("boot cpu: logical %d physical %d\n", found,
- be32_to_cpu(intserv[found_thread]));
boot_cpuid = found;
if (IS_ENABLED(CONFIG_PPC64))
@@ -382,11 +380,19 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
}
if (boot_cpuid >= nr_cpu_ids) {
- set_nr_cpu_ids(min(CONFIG_NR_CPUS, ALIGN(boot_cpuid + 1, nthreads)));
- pr_warn("Boot CPU %d >= nr_cpu_ids, adjusted nr_cpu_ids to %d\n",
- boot_cpuid, nr_cpu_ids);
+ // Remember boot core for smp_setup_cpu_maps()
+ boot_core_hwid = be32_to_cpu(intserv[0]);
+
+ pr_warn("Boot CPU %d (core hwid %d) >= nr_cpu_ids, adjusted boot CPU to %d\n",
+ boot_cpuid, boot_core_hwid, found_thread);
+
+ // Adjust boot CPU to appear on logical core 0
+ boot_cpuid = found_thread;
}
+ DBG("boot cpu: logical %d physical %d\n", boot_cpuid,
+ be32_to_cpu(intserv[found_thread]));
+
/*
* PAPR defines "logical" PVR values for cpus that
* meet various levels of the architecture: