Skip to content

Commit b69e0dc

Browse files
James Morsectmarinas
authored andcommitted
arm64: smp: Add function to determine if cpus are stuck in the kernel
kernel/smp.c has a fancy counter that keeps track of the number of CPUs it marked as not-present and left in cpu_park_loop(). If there are any CPUs spinning in here, features like kexec or hibernate may release them by overwriting this memory. This problem also occurs on machines using spin-tables to release secondary cores. After commit 44dbcc9 ("arm64: Fix behavior of maxcpus=N") we bring all known cpus into the secondary holding pen, meaning this memory can't be re-used by kexec or hibernate. Add a function cpus_are_stuck_in_kernel() to determine if either of these cases have occurred. Signed-off-by: James Morse <james.morse@arm.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> [catalin.marinas@arm.com: cherry-picked from mainline for kexec dependency] Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent d770b5a commit b69e0dc

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

arch/arm64/include/asm/smp.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ static inline void cpu_panic_kernel(void)
124124
cpu_park_loop();
125125
}
126126

127+
/*
128+
* If a secondary CPU enters the kernel but fails to come online,
129+
* (e.g. due to mismatched features), and cannot exit the kernel,
130+
* we increment cpus_stuck_in_kernel and leave the CPU in a
131+
* quiesecent loop within the kernel text. The memory containing
132+
* this loop must not be re-used for anything else as the 'stuck'
133+
* core is executing it.
134+
*
135+
* This function is used to inhibit features like kexec and hibernate.
136+
*/
137+
bool cpus_are_stuck_in_kernel(void);
138+
127139
#endif /* ifndef __ASSEMBLY__ */
128140

129141
#endif /* ifndef __ASM_SMP_H */

arch/arm64/kernel/smp.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,3 +909,21 @@ int setup_profiling_timer(unsigned int multiplier)
909909
{
910910
return -EINVAL;
911911
}
912+
913+
static bool have_cpu_die(void)
914+
{
915+
#ifdef CONFIG_HOTPLUG_CPU
916+
int any_cpu = raw_smp_processor_id();
917+
918+
if (cpu_ops[any_cpu]->cpu_die)
919+
return true;
920+
#endif
921+
return false;
922+
}
923+
924+
bool cpus_are_stuck_in_kernel(void)
925+
{
926+
bool smp_spin_tables = (num_possible_cpus() > 1 && !have_cpu_die());
927+
928+
return !!cpus_stuck_in_kernel || smp_spin_tables;
929+
}

0 commit comments

Comments
 (0)