diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-02 12:14:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-02 12:14:23 -0400 |
commit | d9c566198bfdf72a041322a093fdc1a2dc231170 (patch) | |
tree | 908acd901d8deb0c6ff54323c96cf61d2f005faf /arch | |
parent | 17263849c7ad2279667dd298083eceefcd1b5845 (diff) | |
parent | 0a4949c4414af2eb91414bcd8e2a8ac3706f7dde (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
sparc64: Do not clobber %g7 in setcontext() trap.
sparc64: Kill __show_regs().
sparc: Add __KERNEL__ ifdef protection to pt_regs helpers.
sparc64: Kill smp_report_regs().
sparc64: Kill VERBOSE_SHOWREGS code.
sparc64: Hook up trigger_all_cpu_backtrace().
sparc64: Make global reg dumping even more useful.
sparc: Ignore drivers/video/console/promcon_tbl.c conmakehash generated file
sparc64: FUTEX_OP_ANDN fix
sparc: merge of_platform_{32,64}.h
sparc64: Kill isa_bus_type.
sparc64: Fix global reg snapshotting on self-cpu.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/include/asm/futex_64.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/asm/irq_64.h | 3 | ||||
-rw-r--r-- | arch/sparc/include/asm/of_platform.h | 26 | ||||
-rw-r--r-- | arch/sparc/include/asm/of_platform_32.h | 24 | ||||
-rw-r--r-- | arch/sparc/include/asm/of_platform_64.h | 25 | ||||
-rw-r--r-- | arch/sparc/include/asm/ptrace_32.h | 20 | ||||
-rw-r--r-- | arch/sparc/include/asm/ptrace_64.h | 39 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 5 | ||||
-rw-r--r-- | arch/sparc64/kernel/process.c | 110 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/traps.c | 10 | ||||
-rw-r--r-- | arch/sparc64/mm/ultra.S | 42 |
14 files changed, 102 insertions, 217 deletions
diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h index d8378935ae90..47f95839dc69 100644 --- a/arch/sparc/include/asm/futex_64.h +++ b/arch/sparc/include/asm/futex_64.h | |||
@@ -59,7 +59,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | |||
59 | __futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg); | 59 | __futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg); |
60 | break; | 60 | break; |
61 | case FUTEX_OP_ANDN: | 61 | case FUTEX_OP_ANDN: |
62 | __futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg); | 62 | __futex_cas_op("andn\t%2, %4, %1", ret, oldval, uaddr, oparg); |
63 | break; | 63 | break; |
64 | case FUTEX_OP_XOR: | 64 | case FUTEX_OP_XOR: |
65 | __futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg); | 65 | __futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg); |
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index 0bb9bf531745..3473e25231d9 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h | |||
@@ -90,4 +90,7 @@ static inline unsigned long get_softint(void) | |||
90 | return retval; | 90 | return retval; |
91 | } | 91 | } |
92 | 92 | ||
93 | void __trigger_all_cpu_backtrace(void); | ||
94 | #define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() | ||
95 | |||
93 | #endif | 96 | #endif |
diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h index aa699775ffba..93a262c44022 100644 --- a/arch/sparc/include/asm/of_platform.h +++ b/arch/sparc/include/asm/of_platform.h | |||
@@ -1,8 +1,24 @@ | |||
1 | #ifndef ___ASM_SPARC_OF_PLATFORM_H | 1 | #ifndef ___ASM_SPARC_OF_PLATFORM_H |
2 | #define ___ASM_SPARC_OF_PLATFORM_H | 2 | #define ___ASM_SPARC_OF_PLATFORM_H |
3 | #if defined(__sparc__) && defined(__arch64__) | 3 | /* |
4 | #include <asm/of_platform_64.h> | 4 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. |
5 | #else | 5 | * <benh@kernel.crashing.org> |
6 | #include <asm/of_platform_32.h> | 6 | * Modified for Sparc by merging parts of asm/of_device.h |
7 | #endif | 7 | * by Stephen Rothwell |
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | /* This is just here during the transition */ | ||
17 | #include <linux/of_platform.h> | ||
18 | |||
19 | extern struct bus_type ebus_bus_type; | ||
20 | extern struct bus_type sbus_bus_type; | ||
21 | |||
22 | #define of_bus_type of_platform_bus_type /* for compatibility */ | ||
23 | |||
8 | #endif | 24 | #endif |
diff --git a/arch/sparc/include/asm/of_platform_32.h b/arch/sparc/include/asm/of_platform_32.h deleted file mode 100644 index 723f7c9b7411..000000000000 --- a/arch/sparc/include/asm/of_platform_32.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef _ASM_SPARC_OF_PLATFORM_H | ||
2 | #define _ASM_SPARC_OF_PLATFORM_H | ||
3 | /* | ||
4 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
5 | * <benh@kernel.crashing.org> | ||
6 | * Modified for Sparc by merging parts of asm/of_device.h | ||
7 | * by Stephen Rothwell | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | /* This is just here during the transition */ | ||
17 | #include <linux/of_platform.h> | ||
18 | |||
19 | extern struct bus_type ebus_bus_type; | ||
20 | extern struct bus_type sbus_bus_type; | ||
21 | |||
22 | #define of_bus_type of_platform_bus_type /* for compatibility */ | ||
23 | |||
24 | #endif /* _ASM_SPARC_OF_PLATFORM_H */ | ||
diff --git a/arch/sparc/include/asm/of_platform_64.h b/arch/sparc/include/asm/of_platform_64.h deleted file mode 100644 index 4f66a5f6342d..000000000000 --- a/arch/sparc/include/asm/of_platform_64.h +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | #ifndef _ASM_SPARC64_OF_PLATFORM_H | ||
2 | #define _ASM_SPARC64_OF_PLATFORM_H | ||
3 | /* | ||
4 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
5 | * <benh@kernel.crashing.org> | ||
6 | * Modified for Sparc by merging parts of asm/of_device.h | ||
7 | * by Stephen Rothwell | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | /* This is just here during the transition */ | ||
17 | #include <linux/of_platform.h> | ||
18 | |||
19 | extern struct bus_type isa_bus_type; | ||
20 | extern struct bus_type ebus_bus_type; | ||
21 | extern struct bus_type sbus_bus_type; | ||
22 | |||
23 | #define of_bus_type of_platform_bus_type /* for compatibility */ | ||
24 | |||
25 | #endif /* _ASM_SPARC64_OF_PLATFORM_H */ | ||
diff --git a/arch/sparc/include/asm/ptrace_32.h b/arch/sparc/include/asm/ptrace_32.h index d43c88b86834..d409c4f21a5c 100644 --- a/arch/sparc/include/asm/ptrace_32.h +++ b/arch/sparc/include/asm/ptrace_32.h | |||
@@ -40,16 +40,6 @@ struct pt_regs { | |||
40 | #define UREG_FP UREG_I6 | 40 | #define UREG_FP UREG_I6 |
41 | #define UREG_RETPC UREG_I7 | 41 | #define UREG_RETPC UREG_I7 |
42 | 42 | ||
43 | static inline bool pt_regs_is_syscall(struct pt_regs *regs) | ||
44 | { | ||
45 | return (regs->psr & PSR_SYSCALL); | ||
46 | } | ||
47 | |||
48 | static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | ||
49 | { | ||
50 | return (regs->psr &= ~PSR_SYSCALL); | ||
51 | } | ||
52 | |||
53 | /* A register window */ | 43 | /* A register window */ |
54 | struct reg_window { | 44 | struct reg_window { |
55 | unsigned long locals[8]; | 45 | unsigned long locals[8]; |
@@ -72,6 +62,16 @@ struct sparc_stackf { | |||
72 | 62 | ||
73 | #ifdef __KERNEL__ | 63 | #ifdef __KERNEL__ |
74 | 64 | ||
65 | static inline bool pt_regs_is_syscall(struct pt_regs *regs) | ||
66 | { | ||
67 | return (regs->psr & PSR_SYSCALL); | ||
68 | } | ||
69 | |||
70 | static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | ||
71 | { | ||
72 | return (regs->psr &= ~PSR_SYSCALL); | ||
73 | } | ||
74 | |||
75 | #define user_mode(regs) (!((regs)->psr & PSR_PS)) | 75 | #define user_mode(regs) (!((regs)->psr & PSR_PS)) |
76 | #define instruction_pointer(regs) ((regs)->pc) | 76 | #define instruction_pointer(regs) ((regs)->pc) |
77 | #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) | 77 | #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) |
diff --git a/arch/sparc/include/asm/ptrace_64.h b/arch/sparc/include/asm/ptrace_64.h index ec6d45c84cd0..06e4914c13f4 100644 --- a/arch/sparc/include/asm/ptrace_64.h +++ b/arch/sparc/include/asm/ptrace_64.h | |||
@@ -37,21 +37,6 @@ struct pt_regs { | |||
37 | unsigned int magic; | 37 | unsigned int magic; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static inline int pt_regs_trap_type(struct pt_regs *regs) | ||
41 | { | ||
42 | return regs->magic & 0x1ff; | ||
43 | } | ||
44 | |||
45 | static inline bool pt_regs_is_syscall(struct pt_regs *regs) | ||
46 | { | ||
47 | return (regs->tstate & TSTATE_SYSCALL); | ||
48 | } | ||
49 | |||
50 | static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | ||
51 | { | ||
52 | return (regs->tstate &= ~TSTATE_SYSCALL); | ||
53 | } | ||
54 | |||
55 | struct pt_regs32 { | 40 | struct pt_regs32 { |
56 | unsigned int psr; | 41 | unsigned int psr; |
57 | unsigned int pc; | 42 | unsigned int pc; |
@@ -128,15 +113,30 @@ struct sparc_trapf { | |||
128 | 113 | ||
129 | #ifdef __KERNEL__ | 114 | #ifdef __KERNEL__ |
130 | 115 | ||
116 | static inline int pt_regs_trap_type(struct pt_regs *regs) | ||
117 | { | ||
118 | return regs->magic & 0x1ff; | ||
119 | } | ||
120 | |||
121 | static inline bool pt_regs_is_syscall(struct pt_regs *regs) | ||
122 | { | ||
123 | return (regs->tstate & TSTATE_SYSCALL); | ||
124 | } | ||
125 | |||
126 | static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | ||
127 | { | ||
128 | return (regs->tstate &= ~TSTATE_SYSCALL); | ||
129 | } | ||
130 | |||
131 | struct global_reg_snapshot { | 131 | struct global_reg_snapshot { |
132 | unsigned long tstate; | 132 | unsigned long tstate; |
133 | unsigned long tpc; | 133 | unsigned long tpc; |
134 | unsigned long tnpc; | 134 | unsigned long tnpc; |
135 | unsigned long o7; | 135 | unsigned long o7; |
136 | unsigned long i7; | 136 | unsigned long i7; |
137 | unsigned long rpc; | ||
137 | struct thread_info *thread; | 138 | struct thread_info *thread; |
138 | unsigned long pad1; | 139 | unsigned long pad1; |
139 | unsigned long pad2; | ||
140 | }; | 140 | }; |
141 | 141 | ||
142 | #define __ARCH_WANT_COMPAT_SYS_PTRACE | 142 | #define __ARCH_WANT_COMPAT_SYS_PTRACE |
@@ -154,7 +154,6 @@ extern unsigned long profile_pc(struct pt_regs *); | |||
154 | #define profile_pc(regs) instruction_pointer(regs) | 154 | #define profile_pc(regs) instruction_pointer(regs) |
155 | #endif | 155 | #endif |
156 | extern void show_regs(struct pt_regs *); | 156 | extern void show_regs(struct pt_regs *); |
157 | extern void __show_regs(struct pt_regs *); | ||
158 | #endif | 157 | #endif |
159 | 158 | ||
160 | #else /* __ASSEMBLY__ */ | 159 | #else /* __ASSEMBLY__ */ |
@@ -315,9 +314,9 @@ extern void __show_regs(struct pt_regs *); | |||
315 | #define GR_SNAP_TNPC 0x10 | 314 | #define GR_SNAP_TNPC 0x10 |
316 | #define GR_SNAP_O7 0x18 | 315 | #define GR_SNAP_O7 0x18 |
317 | #define GR_SNAP_I7 0x20 | 316 | #define GR_SNAP_I7 0x20 |
318 | #define GR_SNAP_THREAD 0x28 | 317 | #define GR_SNAP_RPC 0x28 |
319 | #define GR_SNAP_PAD1 0x30 | 318 | #define GR_SNAP_THREAD 0x30 |
320 | #define GR_SNAP_PAD2 0x38 | 319 | #define GR_SNAP_PAD1 0x38 |
321 | 320 | ||
322 | #endif /* __KERNEL__ */ | 321 | #endif /* __KERNEL__ */ |
323 | 322 | ||
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 4fd48ab7dda4..f8b50cbf4bf7 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -56,9 +56,6 @@ struct of_device *of_find_device_by_node(struct device_node *dp) | |||
56 | EXPORT_SYMBOL(of_find_device_by_node); | 56 | EXPORT_SYMBOL(of_find_device_by_node); |
57 | 57 | ||
58 | #ifdef CONFIG_PCI | 58 | #ifdef CONFIG_PCI |
59 | struct bus_type isa_bus_type; | ||
60 | EXPORT_SYMBOL(isa_bus_type); | ||
61 | |||
62 | struct bus_type ebus_bus_type; | 59 | struct bus_type ebus_bus_type; |
63 | EXPORT_SYMBOL(ebus_bus_type); | 60 | EXPORT_SYMBOL(ebus_bus_type); |
64 | #endif | 61 | #endif |
@@ -842,8 +839,6 @@ static int __init of_bus_driver_init(void) | |||
842 | err = of_bus_type_init(&of_platform_bus_type, "of"); | 839 | err = of_bus_type_init(&of_platform_bus_type, "of"); |
843 | #ifdef CONFIG_PCI | 840 | #ifdef CONFIG_PCI |
844 | if (!err) | 841 | if (!err) |
845 | err = of_bus_type_init(&isa_bus_type, "isa"); | ||
846 | if (!err) | ||
847 | err = of_bus_type_init(&ebus_bus_type, "ebus"); | 842 | err = of_bus_type_init(&ebus_bus_type, "ebus"); |
848 | #endif | 843 | #endif |
849 | #ifdef CONFIG_SBUS | 844 | #ifdef CONFIG_SBUS |
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 8a9cd3e165b9..7f5debdc5fed 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
@@ -52,8 +52,6 @@ | |||
52 | #include <asm/irq_regs.h> | 52 | #include <asm/irq_regs.h> |
53 | #include <asm/smp.h> | 53 | #include <asm/smp.h> |
54 | 54 | ||
55 | /* #define VERBOSE_SHOWREGS */ | ||
56 | |||
57 | static void sparc64_yield(int cpu) | 55 | static void sparc64_yield(int cpu) |
58 | { | 56 | { |
59 | if (tlb_type != hypervisor) | 57 | if (tlb_type != hypervisor) |
@@ -213,22 +211,8 @@ static void show_regwindow(struct pt_regs *regs) | |||
213 | printk("I7: <%pS>\n", (void *) rwk->ins[7]); | 211 | printk("I7: <%pS>\n", (void *) rwk->ins[7]); |
214 | } | 212 | } |
215 | 213 | ||
216 | #ifdef CONFIG_SMP | 214 | void show_regs(struct pt_regs *regs) |
217 | static DEFINE_SPINLOCK(regdump_lock); | ||
218 | #endif | ||
219 | |||
220 | void __show_regs(struct pt_regs * regs) | ||
221 | { | 215 | { |
222 | #ifdef CONFIG_SMP | ||
223 | unsigned long flags; | ||
224 | |||
225 | /* Protect against xcall ipis which might lead to livelock on the lock */ | ||
226 | __asm__ __volatile__("rdpr %%pstate, %0\n\t" | ||
227 | "wrpr %0, %1, %%pstate" | ||
228 | : "=r" (flags) | ||
229 | : "i" (PSTATE_IE)); | ||
230 | spin_lock(®dump_lock); | ||
231 | #endif | ||
232 | printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate, | 216 | printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate, |
233 | regs->tpc, regs->tnpc, regs->y, print_tainted()); | 217 | regs->tpc, regs->tnpc, regs->y, print_tainted()); |
234 | printk("TPC: <%pS>\n", (void *) regs->tpc); | 218 | printk("TPC: <%pS>\n", (void *) regs->tpc); |
@@ -246,64 +230,24 @@ void __show_regs(struct pt_regs * regs) | |||
246 | regs->u_regs[15]); | 230 | regs->u_regs[15]); |
247 | printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); | 231 | printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); |
248 | show_regwindow(regs); | 232 | show_regwindow(regs); |
249 | #ifdef CONFIG_SMP | ||
250 | spin_unlock(®dump_lock); | ||
251 | __asm__ __volatile__("wrpr %0, 0, %%pstate" | ||
252 | : : "r" (flags)); | ||
253 | #endif | ||
254 | } | 233 | } |
255 | 234 | ||
256 | #ifdef VERBOSE_SHOWREGS | 235 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; |
257 | static void idump_from_user (unsigned int *pc) | 236 | static DEFINE_SPINLOCK(global_reg_snapshot_lock); |
258 | { | ||
259 | int i; | ||
260 | int code; | ||
261 | |||
262 | if((((unsigned long) pc) & 3)) | ||
263 | return; | ||
264 | |||
265 | pc -= 3; | ||
266 | for(i = -3; i < 6; i++) { | ||
267 | get_user(code, pc); | ||
268 | printk("%c%08x%c",i?' ':'<',code,i?' ':'>'); | ||
269 | pc++; | ||
270 | } | ||
271 | printk("\n"); | ||
272 | } | ||
273 | #endif | ||
274 | 237 | ||
275 | void show_regs(struct pt_regs *regs) | 238 | static bool kstack_valid(struct thread_info *tp, struct reg_window *rw) |
276 | { | 239 | { |
277 | #ifdef VERBOSE_SHOWREGS | 240 | unsigned long thread_base, fp; |
278 | extern long etrap, etraptl1; | ||
279 | #endif | ||
280 | __show_regs(regs); | ||
281 | #if 0 | ||
282 | #ifdef CONFIG_SMP | ||
283 | { | ||
284 | extern void smp_report_regs(void); | ||
285 | 241 | ||
286 | smp_report_regs(); | 242 | thread_base = (unsigned long) tp; |
287 | } | 243 | fp = (unsigned long) rw; |
288 | #endif | ||
289 | #endif | ||
290 | 244 | ||
291 | #ifdef VERBOSE_SHOWREGS | 245 | if (fp < (thread_base + sizeof(struct thread_info)) || |
292 | if (regs->tpc >= &etrap && regs->tpc < &etraptl1 && | 246 | fp >= (thread_base + THREAD_SIZE)) |
293 | regs->u_regs[14] >= (long)current - PAGE_SIZE && | 247 | return false; |
294 | regs->u_regs[14] < (long)current + 6 * PAGE_SIZE) { | 248 | return true; |
295 | printk ("*********parent**********\n"); | ||
296 | __show_regs((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF)); | ||
297 | idump_from_user(((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF))->tpc); | ||
298 | printk ("*********endpar**********\n"); | ||
299 | } | ||
300 | #endif | ||
301 | } | 249 | } |
302 | 250 | ||
303 | #ifdef CONFIG_MAGIC_SYSRQ | ||
304 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; | ||
305 | static DEFINE_SPINLOCK(global_reg_snapshot_lock); | ||
306 | |||
307 | static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, | 251 | static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, |
308 | int this_cpu) | 252 | int this_cpu) |
309 | { | 253 | { |
@@ -315,14 +259,22 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, | |||
315 | global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7]; | 259 | global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7]; |
316 | 260 | ||
317 | if (regs->tstate & TSTATE_PRIV) { | 261 | if (regs->tstate & TSTATE_PRIV) { |
262 | struct thread_info *tp = current_thread_info(); | ||
318 | struct reg_window *rw; | 263 | struct reg_window *rw; |
319 | 264 | ||
320 | rw = (struct reg_window *) | 265 | rw = (struct reg_window *) |
321 | (regs->u_regs[UREG_FP] + STACK_BIAS); | 266 | (regs->u_regs[UREG_FP] + STACK_BIAS); |
322 | global_reg_snapshot[this_cpu].i7 = rw->ins[6]; | 267 | if (kstack_valid(tp, rw)) { |
323 | } else | 268 | global_reg_snapshot[this_cpu].i7 = rw->ins[7]; |
269 | rw = (struct reg_window *) | ||
270 | (rw->ins[6] + STACK_BIAS); | ||
271 | if (kstack_valid(tp, rw)) | ||
272 | global_reg_snapshot[this_cpu].rpc = rw->ins[7]; | ||
273 | } | ||
274 | } else { | ||
324 | global_reg_snapshot[this_cpu].i7 = 0; | 275 | global_reg_snapshot[this_cpu].i7 = 0; |
325 | 276 | global_reg_snapshot[this_cpu].rpc = 0; | |
277 | } | ||
326 | global_reg_snapshot[this_cpu].thread = tp; | 278 | global_reg_snapshot[this_cpu].thread = tp; |
327 | } | 279 | } |
328 | 280 | ||
@@ -341,7 +293,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp) | |||
341 | } | 293 | } |
342 | } | 294 | } |
343 | 295 | ||
344 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) | 296 | void __trigger_all_cpu_backtrace(void) |
345 | { | 297 | { |
346 | struct thread_info *tp = current_thread_info(); | 298 | struct thread_info *tp = current_thread_info(); |
347 | struct pt_regs *regs = get_irq_regs(); | 299 | struct pt_regs *regs = get_irq_regs(); |
@@ -375,13 +327,14 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty) | |||
375 | ((tp && tp->task) ? tp->task->pid : -1)); | 327 | ((tp && tp->task) ? tp->task->pid : -1)); |
376 | 328 | ||
377 | if (gp->tstate & TSTATE_PRIV) { | 329 | if (gp->tstate & TSTATE_PRIV) { |
378 | printk(" TPC[%pS] O7[%pS] I7[%pS]\n", | 330 | printk(" TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n", |
379 | (void *) gp->tpc, | 331 | (void *) gp->tpc, |
380 | (void *) gp->o7, | 332 | (void *) gp->o7, |
381 | (void *) gp->i7); | 333 | (void *) gp->i7, |
334 | (void *) gp->rpc); | ||
382 | } else { | 335 | } else { |
383 | printk(" TPC[%lx] O7[%lx] I7[%lx]\n", | 336 | printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n", |
384 | gp->tpc, gp->o7, gp->i7); | 337 | gp->tpc, gp->o7, gp->i7, gp->rpc); |
385 | } | 338 | } |
386 | } | 339 | } |
387 | 340 | ||
@@ -390,6 +343,13 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty) | |||
390 | spin_unlock_irqrestore(&global_reg_snapshot_lock, flags); | 343 | spin_unlock_irqrestore(&global_reg_snapshot_lock, flags); |
391 | } | 344 | } |
392 | 345 | ||
346 | #ifdef CONFIG_MAGIC_SYSRQ | ||
347 | |||
348 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) | ||
349 | { | ||
350 | __trigger_all_cpu_backtrace(); | ||
351 | } | ||
352 | |||
393 | static struct sysrq_key_op sparc_globalreg_op = { | 353 | static struct sysrq_key_op sparc_globalreg_op = { |
394 | .handler = sysrq_handle_globreg, | 354 | .handler = sysrq_handle_globreg, |
395 | .help_msg = "Globalregs", | 355 | .help_msg = "Globalregs", |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index d1b84456a9ee..ca5a6ae3a6e2 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/sparc64/kernel/signal.c | 2 | * arch/sparc64/kernel/signal.c |
3 | * | 3 | * |
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | 5 | * Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net) |
6 | * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) | 6 | * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) |
7 | * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) | 7 | * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) |
8 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | 8 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
@@ -91,7 +91,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) | |||
91 | err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4])); | 91 | err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4])); |
92 | err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5])); | 92 | err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5])); |
93 | err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6])); | 93 | err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6])); |
94 | err |= __get_user(regs->u_regs[UREG_G7], (&(*grp)[MC_G7])); | 94 | |
95 | /* Skip %g7 as that's the thread register in userspace. */ | ||
96 | |||
95 | err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0])); | 97 | err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0])); |
96 | err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1])); | 98 | err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1])); |
97 | err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2])); | 99 | err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2])); |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 7cf72b4bb108..340842e51ce1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -843,7 +843,6 @@ void smp_tsb_sync(struct mm_struct *mm) | |||
843 | extern unsigned long xcall_flush_tlb_mm; | 843 | extern unsigned long xcall_flush_tlb_mm; |
844 | extern unsigned long xcall_flush_tlb_pending; | 844 | extern unsigned long xcall_flush_tlb_pending; |
845 | extern unsigned long xcall_flush_tlb_kernel_range; | 845 | extern unsigned long xcall_flush_tlb_kernel_range; |
846 | extern unsigned long xcall_report_regs; | ||
847 | #ifdef CONFIG_MAGIC_SYSRQ | 846 | #ifdef CONFIG_MAGIC_SYSRQ |
848 | extern unsigned long xcall_fetch_glob_regs; | 847 | extern unsigned long xcall_fetch_glob_regs; |
849 | #endif | 848 | #endif |
@@ -1022,11 +1021,6 @@ void kgdb_roundup_cpus(unsigned long flags) | |||
1022 | } | 1021 | } |
1023 | #endif | 1022 | #endif |
1024 | 1023 | ||
1025 | void smp_report_regs(void) | ||
1026 | { | ||
1027 | smp_cross_call(&xcall_report_regs, 0, 0, 0); | ||
1028 | } | ||
1029 | |||
1030 | #ifdef CONFIG_MAGIC_SYSRQ | 1024 | #ifdef CONFIG_MAGIC_SYSRQ |
1031 | void smp_fetch_global_regs(void) | 1025 | void smp_fetch_global_regs(void) |
1032 | { | 1026 | { |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 504e678ee128..0804f71df6cb 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -68,7 +68,6 @@ extern void *__memscan_zero(void *, size_t); | |||
68 | extern void *__memscan_generic(void *, int, size_t); | 68 | extern void *__memscan_generic(void *, int, size_t); |
69 | extern int __memcmp(const void *, const void *, __kernel_size_t); | 69 | extern int __memcmp(const void *, const void *, __kernel_size_t); |
70 | extern __kernel_size_t strlen(const char *); | 70 | extern __kernel_size_t strlen(const char *); |
71 | extern void show_regs(struct pt_regs *); | ||
72 | extern void syscall_trace(struct pt_regs *, int); | 71 | extern void syscall_trace(struct pt_regs *, int); |
73 | extern void sys_sigsuspend(void); | 72 | extern void sys_sigsuspend(void); |
74 | extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); | 73 | extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index bd30ecba5630..404e8561e2d0 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -1777,7 +1777,7 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, | |||
1777 | pfx, | 1777 | pfx, |
1778 | ent->err_raddr, ent->err_size, ent->err_cpu); | 1778 | ent->err_raddr, ent->err_size, ent->err_cpu); |
1779 | 1779 | ||
1780 | __show_regs(regs); | 1780 | show_regs(regs); |
1781 | 1781 | ||
1782 | if ((cnt = atomic_read(ocnt)) != 0) { | 1782 | if ((cnt = atomic_read(ocnt)) != 0) { |
1783 | atomic_set(ocnt, 0); | 1783 | atomic_set(ocnt, 0); |
@@ -2177,7 +2177,6 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw) | |||
2177 | void die_if_kernel(char *str, struct pt_regs *regs) | 2177 | void die_if_kernel(char *str, struct pt_regs *regs) |
2178 | { | 2178 | { |
2179 | static int die_counter; | 2179 | static int die_counter; |
2180 | extern void smp_report_regs(void); | ||
2181 | int count = 0; | 2180 | int count = 0; |
2182 | 2181 | ||
2183 | /* Amuse the user. */ | 2182 | /* Amuse the user. */ |
@@ -2190,7 +2189,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2190 | printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); | 2189 | printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); |
2191 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); | 2190 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); |
2192 | __asm__ __volatile__("flushw"); | 2191 | __asm__ __volatile__("flushw"); |
2193 | __show_regs(regs); | 2192 | show_regs(regs); |
2194 | add_taint(TAINT_DIE); | 2193 | add_taint(TAINT_DIE); |
2195 | if (regs->tstate & TSTATE_PRIV) { | 2194 | if (regs->tstate & TSTATE_PRIV) { |
2196 | struct reg_window *rw = (struct reg_window *) | 2195 | struct reg_window *rw = (struct reg_window *) |
@@ -2215,11 +2214,6 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2215 | } | 2214 | } |
2216 | user_instruction_dump ((unsigned int __user *) regs->tpc); | 2215 | user_instruction_dump ((unsigned int __user *) regs->tpc); |
2217 | } | 2216 | } |
2218 | #if 0 | ||
2219 | #ifdef CONFIG_SMP | ||
2220 | smp_report_regs(); | ||
2221 | #endif | ||
2222 | #endif | ||
2223 | if (regs->tstate & TSTATE_PRIV) | 2217 | if (regs->tstate & TSTATE_PRIV) |
2224 | do_exit(SIGKILL); | 2218 | do_exit(SIGKILL); |
2225 | do_exit(SIGSEGV); | 2219 | do_exit(SIGSEGV); |
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 4c8ca131ffaf..ff1dc44d363e 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S | |||
@@ -480,41 +480,6 @@ xcall_sync_tick: | |||
480 | b rtrap_xcall | 480 | b rtrap_xcall |
481 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 | 481 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 |
482 | 482 | ||
483 | /* NOTE: This is SPECIAL!! We do etrap/rtrap however | ||
484 | * we choose to deal with the "BH's run with | ||
485 | * %pil==15" problem (described in asm/pil.h) | ||
486 | * by just invoking rtrap directly past where | ||
487 | * BH's are checked for. | ||
488 | * | ||
489 | * We do it like this because we do not want %pil==15 | ||
490 | * lockups to prevent regs being reported. | ||
491 | */ | ||
492 | .globl xcall_report_regs | ||
493 | xcall_report_regs: | ||
494 | |||
495 | 661: rdpr %pstate, %g2 | ||
496 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate | ||
497 | .section .sun4v_2insn_patch, "ax" | ||
498 | .word 661b | ||
499 | nop | ||
500 | nop | ||
501 | .previous | ||
502 | |||
503 | rdpr %pil, %g2 | ||
504 | wrpr %g0, 15, %pil | ||
505 | sethi %hi(109f), %g7 | ||
506 | b,pt %xcc, etrap_irq | ||
507 | 109: or %g7, %lo(109b), %g7 | ||
508 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
509 | call trace_hardirqs_off | ||
510 | nop | ||
511 | #endif | ||
512 | call __show_regs | ||
513 | add %sp, PTREGS_OFF, %o0 | ||
514 | /* Has to be a non-v9 branch due to the large distance. */ | ||
515 | b rtrap_xcall | ||
516 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 | ||
517 | |||
518 | #ifdef CONFIG_MAGIC_SYSRQ | 483 | #ifdef CONFIG_MAGIC_SYSRQ |
519 | .globl xcall_fetch_glob_regs | 484 | .globl xcall_fetch_glob_regs |
520 | xcall_fetch_glob_regs: | 485 | xcall_fetch_glob_regs: |
@@ -531,6 +496,13 @@ xcall_fetch_glob_regs: | |||
531 | stx %g7, [%g1 + GR_SNAP_TNPC] | 496 | stx %g7, [%g1 + GR_SNAP_TNPC] |
532 | stx %o7, [%g1 + GR_SNAP_O7] | 497 | stx %o7, [%g1 + GR_SNAP_O7] |
533 | stx %i7, [%g1 + GR_SNAP_I7] | 498 | stx %i7, [%g1 + GR_SNAP_I7] |
499 | /* Don't try this at home kids... */ | ||
500 | rdpr %cwp, %g2 | ||
501 | sub %g2, 1, %g7 | ||
502 | wrpr %g7, %cwp | ||
503 | mov %i7, %g7 | ||
504 | wrpr %g2, %cwp | ||
505 | stx %g7, [%g1 + GR_SNAP_RPC] | ||
534 | sethi %hi(trap_block), %g7 | 506 | sethi %hi(trap_block), %g7 |
535 | or %g7, %lo(trap_block), %g7 | 507 | or %g7, %lo(trap_block), %g7 |
536 | sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2 | 508 | sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2 |