[PATCH v3 08/12] arm64: cpu_ops: Introduce get_secondary_cpu_ops()

From: Jinjie Ruan

Date: Wed Jun 24 2026 - 05:28:41 EST


From: Will Deacon <will@xxxxxxxxxx>

Introduce get_secondary_cpu_ops() to retrieve a pointer to the
'cpu_operations' structure for the non-boot CPUs and use it instead of
get_cpu_ops() where we are dealing with secondary CPUs.

This is a pre-requisite for enabling parallel CPU bring-up.

Signed-off-by: Will Deacon <will@xxxxxxxxxx>
Signed-off-by: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>
---
arch/arm64/include/asm/cpu_ops.h | 1 +
arch/arm64/kernel/cpu_ops.c | 5 +++++
arch/arm64/kernel/smp.c | 19 +++++++------------
3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index a444c8915e88..cd298a8710d8 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -48,6 +48,7 @@ struct cpu_operations {

int __init init_cpu_ops(int cpu);
extern const struct cpu_operations *get_cpu_ops(int cpu);
+extern const struct cpu_operations *get_secondary_cpu_ops(void);

static inline void __init init_bootcpu_ops(void)
{
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index eacfb88a0c0c..7d183ca31dc8 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -127,3 +127,8 @@ const struct cpu_operations *get_cpu_ops(int cpu)

return NULL;
}
+
+const struct cpu_operations *get_secondary_cpu_ops(void)
+{
+ return cpu_ops;
+}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 9482e8d38b98..6b9586a69429 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -99,7 +99,7 @@ static inline int op_cpu_kill(unsigned int cpu)
*/
static int boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- const struct cpu_operations *ops = get_cpu_ops(cpu);
+ const struct cpu_operations *ops = get_secondary_cpu_ops();

if (ops->cpu_boot)
return ops->cpu_boot(cpu);
@@ -234,7 +234,7 @@ asmlinkage notrace void secondary_start_kernel(void)
rcutree_report_cpu_starting(cpu);
trace_hardirqs_off_finish();

- ops = get_cpu_ops(cpu);
+ ops = get_secondary_cpu_ops();
if (ops->cpu_postboot)
ops->cpu_postboot();

@@ -334,7 +334,7 @@ int __cpu_disable(void)

static int op_cpu_kill(unsigned int cpu)
{
- const struct cpu_operations *ops = get_cpu_ops(cpu);
+ const struct cpu_operations *ops = get_secondary_cpu_ops();

/*
* If we have no means of synchronising with the dying CPU, then assume
@@ -375,7 +375,7 @@ void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu)
void __noreturn cpu_die(void)
{
unsigned int cpu = smp_processor_id();
- const struct cpu_operations *ops = get_cpu_ops(cpu);
+ const struct cpu_operations *ops = get_secondary_cpu_ops();

idle_task_exit();

@@ -501,7 +501,7 @@ static int __init smp_cpu_setup(int cpu)
if (init_cpu_ops(cpu))
return -ENODEV;

- ops = get_cpu_ops(cpu);
+ ops = get_secondary_cpu_ops();
if (ops->cpu_init(cpu))
return -ENODEV;

@@ -780,7 +780,7 @@ void __init smp_init_cpus(void)

void __init smp_prepare_cpus(unsigned int max_cpus)
{
- const struct cpu_operations *ops;
+ const struct cpu_operations *ops = get_secondary_cpu_ops();
unsigned int cpu;
int err;

@@ -806,10 +806,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (cpu == 0)
continue;

- ops = get_cpu_ops(cpu);
- if (!ops)
- continue;
-
err = ops->cpu_prepare(cpu);
if (err)
continue;
@@ -1299,8 +1295,7 @@ bool smp_crash_stop_failed(void)
static bool have_cpu_die(void)
{
#ifdef CONFIG_HOTPLUG_CPU
- int any_cpu = raw_smp_processor_id();
- const struct cpu_operations *ops = get_cpu_ops(any_cpu);
+ const struct cpu_operations *ops = get_secondary_cpu_ops();

if (ops && ops->cpu_die)
return true;
--
2.34.1