Commit 66f16a24 authored by Will Deacon's avatar Will Deacon

arm64: smp: Rework early feature mismatched detection

Rather than add additional variables to detect specific early feature
mismatches with secondary CPUs, we can instead dedicate the upper bits
of the CPU boot status word to flag specific mismatches.

This allows us to communicate both granule and VA-size mismatches back
to the primary CPU without the need for additional book-keeping.
Tested-by: default avatarSteve Capper <steve.capper@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 68d23da4
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define __ASM_SMP_H #define __ASM_SMP_H
/* Values for secondary_data.status */ /* Values for secondary_data.status */
#define CPU_STUCK_REASON_SHIFT (8)
#define CPU_BOOT_STATUS_MASK ((1U << CPU_STUCK_REASON_SHIFT) - 1)
#define CPU_MMU_OFF (-1) #define CPU_MMU_OFF (-1)
#define CPU_BOOT_SUCCESS (0) #define CPU_BOOT_SUCCESS (0)
...@@ -27,6 +29,9 @@ ...@@ -27,6 +29,9 @@
/* Fatal system error detected by secondary CPU, crash the system */ /* Fatal system error detected by secondary CPU, crash the system */
#define CPU_PANIC_KERNEL (3) #define CPU_PANIC_KERNEL (3)
#define CPU_STUCK_REASON_52_BIT_VA (1U << CPU_STUCK_REASON_SHIFT)
#define CPU_STUCK_REASON_NO_GRAN (2U << CPU_STUCK_REASON_SHIFT)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/percpu.h> #include <asm/percpu.h>
......
...@@ -809,13 +809,8 @@ ENTRY(__cpu_secondary_check52bitva) ...@@ -809,13 +809,8 @@ ENTRY(__cpu_secondary_check52bitva)
and x0, x0, #(0xf << ID_AA64MMFR2_LVA_SHIFT) and x0, x0, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
cbnz x0, 2f cbnz x0, 2f
adr_l x0, va52mismatch update_early_cpu_boot_status \
mov w1, #1 CPU_STUCK_IN_KERNEL | CPU_STUCK_REASON_52_BIT_VA, x0, x1
strb w1, [x0]
dmb sy
dc ivac, x0 // Invalidate potentially stale cache line
update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x0, x1
1: wfe 1: wfe
wfi wfi
b 1b b 1b
...@@ -826,7 +821,8 @@ ENDPROC(__cpu_secondary_check52bitva) ...@@ -826,7 +821,8 @@ ENDPROC(__cpu_secondary_check52bitva)
__no_granule_support: __no_granule_support:
/* Indicate that this CPU can't boot and is stuck in the kernel */ /* Indicate that this CPU can't boot and is stuck in the kernel */
update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x1, x2 update_early_cpu_boot_status \
CPU_STUCK_IN_KERNEL | CPU_STUCK_REASON_NO_GRAN, x1, x2
1: 1:
wfe wfe
wfi wfi
......
...@@ -108,7 +108,6 @@ static int boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -108,7 +108,6 @@ static int boot_secondary(unsigned int cpu, struct task_struct *idle)
} }
static DECLARE_COMPLETION(cpu_running); static DECLARE_COMPLETION(cpu_running);
bool va52mismatch __ro_after_init;
int __cpu_up(unsigned int cpu, struct task_struct *idle) int __cpu_up(unsigned int cpu, struct task_struct *idle)
{ {
...@@ -138,10 +137,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) ...@@ -138,10 +137,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (!cpu_online(cpu)) { if (!cpu_online(cpu)) {
pr_crit("CPU%u: failed to come online\n", cpu); pr_crit("CPU%u: failed to come online\n", cpu);
if (IS_ENABLED(CONFIG_ARM64_USER_VA_BITS_52) && va52mismatch)
pr_crit("CPU%u: does not support 52-bit VAs\n", cpu);
ret = -EIO; ret = -EIO;
} }
} else { } else {
...@@ -156,7 +151,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) ...@@ -156,7 +151,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (status == CPU_MMU_OFF) if (status == CPU_MMU_OFF)
status = READ_ONCE(__early_cpu_boot_status); status = READ_ONCE(__early_cpu_boot_status);
switch (status) { switch (status & CPU_BOOT_STATUS_MASK) {
default: default:
pr_err("CPU%u: failed in unknown state : 0x%lx\n", pr_err("CPU%u: failed in unknown state : 0x%lx\n",
cpu, status); cpu, status);
...@@ -170,6 +165,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) ...@@ -170,6 +165,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
pr_crit("CPU%u: may not have shut down cleanly\n", cpu); pr_crit("CPU%u: may not have shut down cleanly\n", cpu);
case CPU_STUCK_IN_KERNEL: case CPU_STUCK_IN_KERNEL:
pr_crit("CPU%u: is stuck in kernel\n", cpu); pr_crit("CPU%u: is stuck in kernel\n", cpu);
if (status & CPU_STUCK_REASON_52_BIT_VA)
pr_crit("CPU%u: does not support 52-bit VAs\n", cpu);
if (status & CPU_STUCK_REASON_NO_GRAN)
pr_crit("CPU%u: does not support %luK granule \n", cpu, PAGE_SIZE / SZ_1K);
cpus_stuck_in_kernel++; cpus_stuck_in_kernel++;
break; break;
case CPU_PANIC_KERNEL: case CPU_PANIC_KERNEL:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment