Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 768d18ad authored by Milton Miller's avatar Milton Miller Committed by Benjamin Herrenschmidt
Browse files

powerpc: Don't search for paca in freed memory



Starting with 1426d5a3 (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 c1854e00 (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
c1854e00 (powerpc: Set
nr_cpu_ids early and use it to free PACAs) to function.  Also
9d07bc84 (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: <stable@kernel.org> # .34.x: c1854e00 powerpc: Set nr_cpu_ids early
Cc: <stable@kernel.org> # .34.x
Signed-off-by: default avatarMilton Miller <miltonm@bga.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 3d2cea73
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -218,13 +218,19 @@ generic_secondary_common_init:
	 */
	 */
	LOAD_REG_ADDR(r13, paca)	/* Load paca pointer		 */
	LOAD_REG_ADDR(r13, paca)	/* Load paca pointer		 */
	ld	r13,0(r13)		/* Get base vaddr of paca array	 */
	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                */
	li	r5,0			/* logical cpu id                */
1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
	cmpw	r6,r24			/* Compare to our id             */
	cmpw	r6,r24			/* Compare to our id             */
	beq	2f
	beq	2f
	addi	r13,r13,PACA_SIZE	/* Loop to next PACA on miss     */
	addi	r13,r13,PACA_SIZE	/* Loop to next PACA on miss     */
	addi	r5,r5,1
	addi	r5,r5,1
	cmpwi	r5,NR_CPUS
	cmpw	r5,r7			/* Check if more pacas exist     */
	blt	1b
	blt	1b


	mr	r3,r24			/* not found, copy phys to r3	 */
	mr	r3,r24			/* not found, copy phys to r3	 */
@@ -259,9 +265,6 @@ generic_secondary_common_init:
4:	HMT_LOW
4:	HMT_LOW
	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
					/* start.			 */
					/* start.			 */
#ifndef CONFIG_SMP
	b	4b			/* Never go on non-SMP		 */
#else
	cmpwi	0,r23,0
	cmpwi	0,r23,0
	beq	4b			/* Loop until told to go	 */
	beq	4b			/* Loop until told to go	 */


@@ -273,7 +276,7 @@ generic_secondary_common_init:
	subi	r1,r1,STACK_FRAME_OVERHEAD
	subi	r1,r1,STACK_FRAME_OVERHEAD


	b	__secondary_start
	b	__secondary_start
#endif
#endif /* SMP */


/*
/*
 * Turn the MMU off.
 * Turn the MMU off.