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

Commit 2751b628 authored by Anton Blanchard's avatar Anton Blanchard
Browse files

powerpc: Fix SMP issues with ppc64le ABIv2



There is no need to put a function descriptor in
__secondary_hold_spinloop. Use ppc_function_entry to get the
instruction address and put it in __secondary_hold_spinloop instead.

Also fix an issue where we assumed cur_cpu_spec held a function
descriptor.

Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
parent d51959d7
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -76,10 +76,9 @@ END_FTR_SECTION(0, 1)
	/* Catch branch to 0 in real mode */
	trap

	/* Secondary processors spin on this value until it becomes nonzero.
	 * When it does it contains the real address of the descriptor
	 * of the function that the cpu should jump to to continue
	 * initialization.
	/* Secondary processors spin on this value until it becomes non-zero.
	 * When non-zero, it contains the real address of the function the cpu
	 * should jump to.
	 */
	.balign 8
	.globl  __secondary_hold_spinloop
@@ -147,9 +146,6 @@ __secondary_hold:
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
#ifdef CONFIG_PPC_BOOK3E
	tovirt(r12,r12)
#endif
#if !defined(_CALL_ELF) || _CALL_ELF != 2
	ld	r12,0(r12)		/* deref function descriptor */
#endif
	mtctr	r12
	mr	r3,r24
@@ -266,10 +262,12 @@ generic_secondary_common_init:
	/* See if we need to call a cpu state restore handler */
	LOAD_REG_ADDR(r23, cur_cpu_spec)
	ld	r23,0(r23)
	ld	r23,CPU_SPEC_RESTORE(r23)
	cmpdi	0,r23,0
	ld	r12,CPU_SPEC_RESTORE(r23)
	cmpdi	0,r12,0
	beq	3f
	ld	r12,0(r23)
#if !defined(_CALL_ELF) || _CALL_ELF != 2
	ld	r12,0(r12)
#endif
	mtctr	r12
	bctrl

+1 −1
Original line number Diff line number Diff line
@@ -341,7 +341,7 @@ void smp_release_cpus(void)

	ptr  = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
			- PHYSICAL_START);
	*ptr = __pa(generic_secondary_smp_init);
	*ptr = ppc_function_entry(generic_secondary_smp_init);

	/* And wait a bit for them to catch up */
	for (i = 0; i < 100000; i++) {
+2 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <asm/cacheflush.h>
#include <asm/dbell.h>
#include <asm/fsl_guts.h>
#include <asm/code-patching.h>

#include <sysdev/fsl_soc.h>
#include <sysdev/mpic.h>
@@ -267,7 +268,7 @@ out:
	flush_spin_table(spin_table);
	out_be32(&spin_table->pir, hw_cpu);
	out_be64((u64 *)(&spin_table->addr_h),
	  __pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
		__pa(ppc_function_entry(generic_secondary_smp_init)));
	flush_spin_table(spin_table);
#endif

+3 −2
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <asm/firmware.h>
#include <asm/rtas.h>
#include <asm/cputhreads.h>
#include <asm/code-patching.h>

#include "interrupt.h"
#include <asm/udbg.h>
@@ -70,8 +71,8 @@ static cpumask_t of_spin_map;
static inline int smp_startup_cpu(unsigned int lcpu)
{
	int status;
	unsigned long start_here = __pa((u32)*((unsigned long *)
					       generic_secondary_smp_init));
	unsigned long start_here =
			__pa(ppc_function_entry(generic_secondary_smp_init));
	unsigned int pcpu;
	int start_cpu;

+3 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <asm/cputhreads.h>
#include <asm/xics.h>
#include <asm/opal.h>
#include <asm/code-patching.h>

#include "powernv.h"

@@ -49,8 +50,8 @@ static void pnv_smp_setup_cpu(int cpu)
int pnv_smp_kick_cpu(int nr)
{
	unsigned int pcpu = get_hard_smp_processor_id(nr);
	unsigned long start_here = __pa(*((unsigned long *)
					  generic_secondary_smp_init));
	unsigned long start_here =
			__pa(ppc_function_entry(generic_secondary_smp_init));
	long rc;

	BUG_ON(nr < 0 || nr >= NR_CPUS);
Loading