Commit fb9d4325 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Fix __get_SP()

From: Anton Blanchard <anton@samba.org>

__get_SP used to be a function call which meant we allocated a stack
frame before calling it. This meant the SP it returned was one frame
below the current function. Lets call that bogusSP (and the real one
SP).

The new dump_stack was being tail call optimised so it remained one
frame above bogusSP. dump_stack would then store below SP (as the ABI
allows us to) and would stomp over the back link that bogusSP pointed
to (__get_SP had set the back link up so it worked sometimes, just not
all the time).

Fix this by just making __get_SP an inline that returns the current SP.
parent ebcfac4e
......@@ -579,7 +579,7 @@ int do_IRQ(struct pt_regs *regs)
{
long sp;
sp = (unsigned long)_get_SP() & (THREAD_SIZE-1);
sp = __get_SP() & (THREAD_SIZE-1);
if (unlikely(sp < (sizeof(struct thread_info) + 8192))) {
printk("do_IRQ: stack overflow: %ld\n",
......
......@@ -383,10 +383,6 @@ _GLOBAL(abs)
neg r3,r3
10: blr
_GLOBAL(_get_SP)
mr r3,r1 /* Close enough */
blr
_GLOBAL(_get_PVR)
mfspr r3,PVR
blr
......
......@@ -162,7 +162,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
* for that first.
*/
if ((cur_cpu_spec->cpu_features & CPU_FTR_SLB) &&
GET_ESID((unsigned long)_get_SP()) != GET_ESID(PAGE_OFFSET)) {
GET_ESID(__get_SP()) != GET_ESID(PAGE_OFFSET)) {
union {
unsigned long word0;
slb_dword0 data;
......@@ -171,7 +171,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
esid_data.word0 = 0;
/* class bit is in valid field for slbie instruction */
esid_data.data.v = 1;
esid_data.data.esid = GET_ESID((unsigned long)_get_SP());
esid_data.data.esid = GET_ESID(__get_SP());
asm volatile("isync; slbie %0; isync" : : "r" (esid_data));
}
local_irq_restore(flags);
......@@ -528,7 +528,7 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
if (p) {
sp = p->thread.ksp;
} else {
sp = (unsigned long)_get_SP();
sp = __get_SP();
p = current;
}
}
......@@ -549,7 +549,7 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
void dump_stack(void)
{
show_stack(current, (unsigned long *)_get_SP());
show_stack(current, (unsigned long *)__get_SP());
}
EXPORT_SYMBOL(dump_stack);
......
......@@ -324,7 +324,7 @@ static void make_slbe(unsigned long esid, unsigned long vsid, int large,
castout_entry = 1;
asm volatile("slbmfee %0,%1" : "=r" (esid_data) : "r" (entry));
} while (esid_data.data.v &&
esid_data.data.esid == GET_ESID((unsigned long)_get_SP()));
esid_data.data.esid == GET_ESID(__get_SP()));
get_paca()->xStab_data.next_round_robin = castout_entry;
......
......@@ -475,7 +475,8 @@ static inline void set_tb(unsigned int upper, unsigned int lower)
mttbl(lower);
}
extern unsigned long *_get_SP(void);
#define __get_SP() ({unsigned long sp; \
asm volatile("mr %0,1": "=r" (sp)); sp;})
extern int have_of;
......
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