aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/of_device.c5
-rw-r--r--arch/sparc64/kernel/process.c110
-rw-r--r--arch/sparc64/kernel/signal.c6
-rw-r--r--arch/sparc64/kernel/smp.c6
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c1
-rw-r--r--arch/sparc64/kernel/traps.c10
-rw-r--r--arch/sparc64/mm/ultra.S42
7 files changed, 48 insertions, 132 deletions
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)
56EXPORT_SYMBOL(of_find_device_by_node); 56EXPORT_SYMBOL(of_find_device_by_node);
57 57
58#ifdef CONFIG_PCI 58#ifdef CONFIG_PCI
59struct bus_type isa_bus_type;
60EXPORT_SYMBOL(isa_bus_type);
61
62struct bus_type ebus_bus_type; 59struct bus_type ebus_bus_type;
63EXPORT_SYMBOL(ebus_bus_type); 60EXPORT_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
57static void sparc64_yield(int cpu) 55static 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 214void show_regs(struct pt_regs *regs)
217static DEFINE_SPINLOCK(regdump_lock);
218#endif
219
220void __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(&regdump_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(&regdump_lock);
251 __asm__ __volatile__("wrpr %0, 0, %%pstate"
252 : : "r" (flags));
253#endif
254} 233}
255 234
256#ifdef VERBOSE_SHOWREGS 235struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
257static void idump_from_user (unsigned int *pc) 236static 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
275void show_regs(struct pt_regs *regs) 238static 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
304struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
305static DEFINE_SPINLOCK(global_reg_snapshot_lock);
306
307static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, 251static 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
344static void sysrq_handle_globreg(int key, struct tty_struct *tty) 296void __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
348static void sysrq_handle_globreg(int key, struct tty_struct *tty)
349{
350 __trigger_all_cpu_backtrace();
351}
352
393static struct sysrq_key_op sparc_globalreg_op = { 353static 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)
843extern unsigned long xcall_flush_tlb_mm; 843extern unsigned long xcall_flush_tlb_mm;
844extern unsigned long xcall_flush_tlb_pending; 844extern unsigned long xcall_flush_tlb_pending;
845extern unsigned long xcall_flush_tlb_kernel_range; 845extern unsigned long xcall_flush_tlb_kernel_range;
846extern unsigned long xcall_report_regs;
847#ifdef CONFIG_MAGIC_SYSRQ 846#ifdef CONFIG_MAGIC_SYSRQ
848extern unsigned long xcall_fetch_glob_regs; 847extern 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
1025void 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
1031void smp_fetch_global_regs(void) 1025void 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);
68extern void *__memscan_generic(void *, int, size_t); 68extern void *__memscan_generic(void *, int, size_t);
69extern int __memcmp(const void *, const void *, __kernel_size_t); 69extern int __memcmp(const void *, const void *, __kernel_size_t);
70extern __kernel_size_t strlen(const char *); 70extern __kernel_size_t strlen(const char *);
71extern void show_regs(struct pt_regs *);
72extern void syscall_trace(struct pt_regs *, int); 71extern void syscall_trace(struct pt_regs *, int);
73extern void sys_sigsuspend(void); 72extern void sys_sigsuspend(void);
74extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); 73extern 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)
2177void die_if_kernel(char *str, struct pt_regs *regs) 2177void 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
493xcall_report_regs:
494
495661: 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
507109: 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
520xcall_fetch_glob_regs: 485xcall_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