diff options
-rw-r--r-- | arch/sparc64/kernel/entry.S | 30 | ||||
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 4 | ||||
-rw-r--r-- | include/asm-sparc64/stacktrace.h | 6 |
3 files changed, 39 insertions, 1 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 6be4d2d2904e..49eca4b1cf25 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -1705,6 +1705,36 @@ __flushw_user: | |||
1705 | 2: retl | 1705 | 2: retl |
1706 | nop | 1706 | nop |
1707 | 1707 | ||
1708 | /* Flush %fp and %i7 to the stack for all register | ||
1709 | * windows active inside of the cpu. This allows | ||
1710 | * show_stack_trace() to avoid using an expensive | ||
1711 | * 'flushw'. | ||
1712 | */ | ||
1713 | .globl stack_trace_flush | ||
1714 | .type stack_trace_flush,#function | ||
1715 | stack_trace_flush: | ||
1716 | rdpr %pstate, %o0 | ||
1717 | wrpr %o0, PSTATE_IE, %pstate | ||
1718 | |||
1719 | rdpr %cwp, %g1 | ||
1720 | rdpr %canrestore, %g2 | ||
1721 | sub %g1, 1, %g3 | ||
1722 | |||
1723 | 1: brz,pn %g2, 2f | ||
1724 | sub %g2, 1, %g2 | ||
1725 | wrpr %g3, %cwp | ||
1726 | stx %fp, [%sp + STACK_BIAS + RW_V9_I6] | ||
1727 | stx %i7, [%sp + STACK_BIAS + RW_V9_I7] | ||
1728 | ba,pt %xcc, 1b | ||
1729 | sub %g3, 1, %g3 | ||
1730 | |||
1731 | 2: wrpr %g1, %cwp | ||
1732 | wrpr %o0, %pstate | ||
1733 | |||
1734 | retl | ||
1735 | nop | ||
1736 | .size stack_trace_flush,.-stack_trace_flush | ||
1737 | |||
1708 | #ifdef CONFIG_SMP | 1738 | #ifdef CONFIG_SMP |
1709 | .globl hard_smp_processor_id | 1739 | .globl hard_smp_processor_id |
1710 | hard_smp_processor_id: | 1740 | hard_smp_processor_id: |
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index 47f92a59be18..84d39e873e88 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c | |||
@@ -2,13 +2,15 @@ | |||
2 | #include <linux/stacktrace.h> | 2 | #include <linux/stacktrace.h> |
3 | #include <linux/thread_info.h> | 3 | #include <linux/thread_info.h> |
4 | #include <asm/ptrace.h> | 4 | #include <asm/ptrace.h> |
5 | #include <asm/stacktrace.h> | ||
5 | 6 | ||
6 | void save_stack_trace(struct stack_trace *trace) | 7 | void save_stack_trace(struct stack_trace *trace) |
7 | { | 8 | { |
8 | unsigned long ksp, fp, thread_base; | 9 | unsigned long ksp, fp, thread_base; |
9 | struct thread_info *tp = task_thread_info(current); | 10 | struct thread_info *tp = task_thread_info(current); |
10 | 11 | ||
11 | flushw_all(); | 12 | stack_trace_flush(); |
13 | |||
12 | __asm__ __volatile__( | 14 | __asm__ __volatile__( |
13 | "mov %%fp, %0" | 15 | "mov %%fp, %0" |
14 | : "=r" (ksp) | 16 | : "=r" (ksp) |
diff --git a/include/asm-sparc64/stacktrace.h b/include/asm-sparc64/stacktrace.h new file mode 100644 index 000000000000..6cee39adf6d6 --- /dev/null +++ b/include/asm-sparc64/stacktrace.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _SPARC64_STACKTRACE_H | ||
2 | #define _SPARC64_STACKTRACE_H | ||
3 | |||
4 | extern void stack_trace_flush(void); | ||
5 | |||
6 | #endif /* _SPARC64_STACKTRACE_H */ | ||