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

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
...@@ -76,10 +76,9 @@ END_FTR_SECTION(0, 1) ...@@ -76,10 +76,9 @@ END_FTR_SECTION(0, 1)
/* Catch branch to 0 in real mode */ /* Catch branch to 0 in real mode */
trap trap
/* Secondary processors spin on this value until it becomes nonzero. /* Secondary processors spin on this value until it becomes non-zero.
* When it does it contains the real address of the descriptor * When non-zero, it contains the real address of the function the cpu
* of the function that the cpu should jump to to continue * should jump to.
* initialization.
*/ */
.balign 8 .balign 8
.globl __secondary_hold_spinloop .globl __secondary_hold_spinloop
...@@ -147,9 +146,6 @@ __secondary_hold: ...@@ -147,9 +146,6 @@ __secondary_hold:
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
#ifdef CONFIG_PPC_BOOK3E #ifdef CONFIG_PPC_BOOK3E
tovirt(r12,r12) tovirt(r12,r12)
#endif
#if !defined(_CALL_ELF) || _CALL_ELF != 2
ld r12,0(r12) /* deref function descriptor */
#endif #endif
mtctr r12 mtctr r12
mr r3,r24 mr r3,r24
...@@ -266,10 +262,12 @@ generic_secondary_common_init: ...@@ -266,10 +262,12 @@ generic_secondary_common_init:
/* See if we need to call a cpu state restore handler */ /* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec) LOAD_REG_ADDR(r23, cur_cpu_spec)
ld r23,0(r23) ld r23,0(r23)
ld r23,CPU_SPEC_RESTORE(r23) ld r12,CPU_SPEC_RESTORE(r23)
cmpdi 0,r23,0 cmpdi 0,r12,0
beq 3f beq 3f
ld r12,0(r23) #if !defined(_CALL_ELF) || _CALL_ELF != 2
ld r12,0(r12)
#endif
mtctr r12 mtctr r12
bctrl bctrl
......
...@@ -341,7 +341,7 @@ void smp_release_cpus(void) ...@@ -341,7 +341,7 @@ void smp_release_cpus(void)
ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
- PHYSICAL_START); - 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 */ /* And wait a bit for them to catch up */
for (i = 0; i < 100000; i++) { for (i = 0; i < 100000; i++) {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/dbell.h> #include <asm/dbell.h>
#include <asm/fsl_guts.h> #include <asm/fsl_guts.h>
#include <asm/code-patching.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/mpic.h> #include <sysdev/mpic.h>
...@@ -267,7 +268,7 @@ static int smp_85xx_kick_cpu(int nr) ...@@ -267,7 +268,7 @@ static int smp_85xx_kick_cpu(int nr)
flush_spin_table(spin_table); flush_spin_table(spin_table);
out_be32(&spin_table->pir, hw_cpu); out_be32(&spin_table->pir, hw_cpu);
out_be64((u64 *)(&spin_table->addr_h), 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); flush_spin_table(spin_table);
#endif #endif
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/cputhreads.h> #include <asm/cputhreads.h>
#include <asm/code-patching.h>
#include "interrupt.h" #include "interrupt.h"
#include <asm/udbg.h> #include <asm/udbg.h>
...@@ -70,8 +71,8 @@ static cpumask_t of_spin_map; ...@@ -70,8 +71,8 @@ static cpumask_t of_spin_map;
static inline int smp_startup_cpu(unsigned int lcpu) static inline int smp_startup_cpu(unsigned int lcpu)
{ {
int status; int status;
unsigned long start_here = __pa((u32)*((unsigned long *) unsigned long start_here =
generic_secondary_smp_init)); __pa(ppc_function_entry(generic_secondary_smp_init));
unsigned int pcpu; unsigned int pcpu;
int start_cpu; int start_cpu;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <asm/cputhreads.h> #include <asm/cputhreads.h>
#include <asm/xics.h> #include <asm/xics.h>
#include <asm/opal.h> #include <asm/opal.h>
#include <asm/code-patching.h>
#include "powernv.h" #include "powernv.h"
...@@ -49,8 +50,8 @@ static void pnv_smp_setup_cpu(int cpu) ...@@ -49,8 +50,8 @@ static void pnv_smp_setup_cpu(int cpu)
int pnv_smp_kick_cpu(int nr) int pnv_smp_kick_cpu(int nr)
{ {
unsigned int pcpu = get_hard_smp_processor_id(nr); unsigned int pcpu = get_hard_smp_processor_id(nr);
unsigned long start_here = __pa(*((unsigned long *) unsigned long start_here =
generic_secondary_smp_init)); __pa(ppc_function_entry(generic_secondary_smp_init));
long rc; long rc;
BUG_ON(nr < 0 || nr >= NR_CPUS); BUG_ON(nr < 0 || nr >= NR_CPUS);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/xics.h> #include <asm/xics.h>
#include <asm/dbell.h> #include <asm/dbell.h>
#include <asm/plpar_wrappers.h> #include <asm/plpar_wrappers.h>
#include <asm/code-patching.h>
#include "pseries.h" #include "pseries.h"
#include "offline_states.h" #include "offline_states.h"
...@@ -96,8 +97,8 @@ int smp_query_cpu_stopped(unsigned int pcpu) ...@@ -96,8 +97,8 @@ int smp_query_cpu_stopped(unsigned int pcpu)
static inline int smp_startup_cpu(unsigned int lcpu) static inline int smp_startup_cpu(unsigned int lcpu)
{ {
int status; int status;
unsigned long start_here = __pa((u32)*((unsigned long *) unsigned long start_here =
generic_secondary_smp_init)); __pa(ppc_function_entry(generic_secondary_smp_init));
unsigned int pcpu; unsigned int pcpu;
int start_cpu; int start_cpu;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <asm/reg_a2.h> #include <asm/reg_a2.h>
#include <asm/scom.h> #include <asm/scom.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/code-patching.h>
#include "wsp.h" #include "wsp.h"
...@@ -405,7 +406,7 @@ int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np) ...@@ -405,7 +406,7 @@ int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np)
goto fail; goto fail;
} }
start_here = *(unsigned long *)(core_setup ? generic_secondary_smp_init start_here = ppc_function_entry(core_setup ? generic_secondary_smp_init
: generic_secondary_thread_init); : generic_secondary_thread_init);
pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here); pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here);
......
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