From feb891713837277edd3592ddafd859bb1f21aa9c Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Tue, 10 May 2011 19:28:37 +0000 Subject: [PATCH] powerpc: Don't search for paca in freed memory Starting with 0ba00dd5f05fef8b3b1ef2de853fcc708ebb140f (powerpc: Dynamically allocate pacas) we free the memory for pacas beyond cpu_possible, but we failed to update the loop the secondary cpus use to find their paca. If the system has running cpu threads for which the kernel did not allocate a paca for they will search the memory that was freed. For instance this could happen when the device tree for a kdump kernel was not updated after a cpu hotplug, or the kernel is running with more cpus than the kernel was configured. Since 7896e4f4dd4ce85e11edf1dc3946d86ce0a84d6e (powerpc: Set nr_cpu_ids early and use it to free PACAs) we set nr_cpu_ids before telling the cpus to advance, so use that to limit the search. We can't reference nr_cpu_ids without CONFIG_SMP because it is defined as 1 instead of a memory location, but any extra threads should be sent to kexec_wait in that case anyways, so make that explicit and remove the search loop for UP. Note to stable: The fix also requires 7896e4f4dd4ce85e11edf1dc3946d86ce0a84d6e (powerpc: Set nr_cpu_ids early and use it to free PACAs) to function. Also 856548164958aed43b349cbd943ff7b55242232c (Properly handshake CPUs going out of boot spin loop) affects the second chunk, specifically the branch target was 3b before and is 4b after that patch, and there was a blank line before the #ifdef CONFIG_SMP that was removed Cc: # .34.x: 7896e4f4dd powerpc: Set nr_cpu_ids early Cc: # .34.x Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_64.S | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 73d6e9afcdf14..ba504099844a1 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -218,13 +218,19 @@ generic_secondary_common_init: */ LOAD_REG_ADDR(r13, paca) /* Load paca pointer */ ld r13,0(r13) /* Get base vaddr of paca array */ +#ifndef CONFIG_SMP + addi r13,r13,PACA_SIZE /* know r13 if used accidentally */ + b .kexec_wait /* wait for next kernel if !SMP */ +#else + LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */ + lwz r7,0(r7) /* also the max paca allocated */ li r5,0 /* logical cpu id */ 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ cmpw r6,r24 /* Compare to our id */ beq 2f addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */ addi r5,r5,1 - cmpwi r5,NR_CPUS + cmpw r5,r7 /* Check if more pacas exist */ blt 1b mr r3,r24 /* not found, copy phys to r3 */ @@ -259,9 +265,6 @@ generic_secondary_common_init: 4: HMT_LOW lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ /* start. */ -#ifndef CONFIG_SMP - b 4b /* Never go on non-SMP */ -#else cmpwi 0,r23,0 beq 4b /* Loop until told to go */ @@ -273,7 +276,7 @@ generic_secondary_common_init: subi r1,r1,STACK_FRAME_OVERHEAD b __secondary_start -#endif +#endif /* SMP */ /* * Turn the MMU off. -- 2.39.5