aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/entry_64.S27
-rw-r--r--arch/powerpc/kernel/ftrace.c13
2 files changed, 37 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 9f61fd61f277..abfc32330479 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -971,6 +971,28 @@ _GLOBAL(ftrace_graph_caller)
971 971
972_GLOBAL(return_to_handler) 972_GLOBAL(return_to_handler)
973 /* need to save return values */ 973 /* need to save return values */
974 std r4, -24(r1)
975 std r3, -16(r1)
976 std r31, -8(r1)
977 mr r31, r1
978 stdu r1, -112(r1)
979
980 bl .ftrace_return_to_handler
981 nop
982
983 /* return value has real return address */
984 mtlr r3
985
986 ld r1, 0(r1)
987 ld r4, -24(r1)
988 ld r3, -16(r1)
989 ld r31, -8(r1)
990
991 /* Jump back to real return address */
992 blr
993
994_GLOBAL(mod_return_to_handler)
995 /* need to save return values */
974 std r4, -32(r1) 996 std r4, -32(r1)
975 std r3, -24(r1) 997 std r3, -24(r1)
976 /* save TOC */ 998 /* save TOC */
@@ -979,7 +1001,10 @@ _GLOBAL(return_to_handler)
979 mr r31, r1 1001 mr r31, r1
980 stdu r1, -112(r1) 1002 stdu r1, -112(r1)
981 1003
982 /* update the TOC */ 1004 /*
1005 * We are in a module using the module's TOC.
1006 * Switch to our TOC to run inside the core kernel.
1007 */
983 LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler) 1008 LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
984 ld r2, 8(r4) 1009 ld r2, 8(r4)
985 1010
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 7538b944fa52..5c6dfa97e838 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -567,6 +567,10 @@ int ftrace_disable_ftrace_graph_caller(void)
567} 567}
568#endif /* CONFIG_DYNAMIC_FTRACE */ 568#endif /* CONFIG_DYNAMIC_FTRACE */
569 569
570#ifdef CONFIG_PPC64
571extern void mod_return_to_handler(void);
572#endif
573
570/* 574/*
571 * Hook the return address and push it in the stack of return addrs 575 * Hook the return address and push it in the stack of return addrs
572 * in current thread info. 576 * in current thread info.
@@ -577,12 +581,17 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
577 unsigned long long calltime; 581 unsigned long long calltime;
578 int faulted; 582 int faulted;
579 struct ftrace_graph_ent trace; 583 struct ftrace_graph_ent trace;
580 unsigned long return_hooker = (unsigned long) 584 unsigned long return_hooker = (unsigned long)&return_to_handler;
581 &return_to_handler;
582 585
583 if (unlikely(atomic_read(&current->tracing_graph_pause))) 586 if (unlikely(atomic_read(&current->tracing_graph_pause)))
584 return; 587 return;
585 588
589#if CONFIG_PPC64
590 /* non core kernel code needs to save and restore the TOC */
591 if (REGION_ID(self_addr) != KERNEL_REGION_ID)
592 return_hooker = (unsigned long)&mod_return_to_handler;
593#endif
594
586 return_hooker = GET_ADDR(return_hooker); 595 return_hooker = GET_ADDR(return_hooker);
587 596
588 /* 597 /*