summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/trace/ftrace_64_mprofile.S13
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
index f9fd5f743eba..da2ca0c6c2c4 100644
--- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
+++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
@@ -36,6 +36,9 @@ _GLOBAL(ftrace_regs_caller)
/* Save the original return address in A's stack frame */
std r0,LRSAVE(r1)
+ /* Create a minimal stack frame for representing B */
+ stdu r1, -STACK_FRAME_MIN_SIZE(r1)
+
/* Create our stack frame + pt_regs */
stdu r1,-SWITCH_FRAME_SIZE(r1)
@@ -65,6 +68,8 @@ _GLOBAL(ftrace_regs_caller)
mflr r7
/* Save it as pt_regs->nip */
std r7, _NIP(r1)
+ /* Also save it in B's stackframe header for proper unwind */
+ std r7, LRSAVE+SWITCH_FRAME_SIZE(r1)
/* Save the read LR in pt_regs->link */
std r0, _LINK(r1)
@@ -121,7 +126,7 @@ ftrace_regs_call:
ld r2, 24(r1)
/* Pop our stack frame */
- addi r1, r1, SWITCH_FRAME_SIZE
+ addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE
#ifdef CONFIG_LIVEPATCH
/* Based on the cmpd above, if the NIP was altered handle livepatch */
@@ -153,6 +158,9 @@ _GLOBAL(ftrace_caller)
/* Save the original return address in A's stack frame */
std r0, LRSAVE(r1)
+ /* Create a minimal stack frame for representing B */
+ stdu r1, -STACK_FRAME_MIN_SIZE(r1)
+
/* Create our stack frame + pt_regs */
stdu r1, -SWITCH_FRAME_SIZE(r1)
@@ -166,6 +174,7 @@ _GLOBAL(ftrace_caller)
/* Get the _mcount() call site out of LR */
mflr r7
std r7, _NIP(r1)
+ std r7, LRSAVE+SWITCH_FRAME_SIZE(r1)
/* Save callee's TOC in the ABI compliant location */
std r2, 24(r1)
@@ -200,7 +209,7 @@ ftrace_call:
ld r2, 24(r1)
/* Pop our stack frame */
- addi r1, r1, SWITCH_FRAME_SIZE
+ addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE
/* Reload original LR */
ld r0, LRSAVE(r1)