aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/Makefile1
-rw-r--r--arch/sparc64/kernel/entry.S27
-rw-r--r--arch/sparc64/kernel/head.S8
-rw-r--r--arch/sparc64/kernel/rtrap.S23
-rw-r--r--arch/sparc64/kernel/stacktrace.c41
-rw-r--r--arch/sparc64/kernel/sun4v_ivec.S20
6 files changed, 109 insertions, 11 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index e1eabebaed39..eff0c01d3579 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ 14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
15 visemul.o prom.o of_device.o 15 visemul.o prom.o of_device.o
16 16
17obj-$(CONFIG_STACKTRACE) += stacktrace.o
17obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ 18obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
18 pci_psycho.o pci_sabre.o pci_schizo.o \ 19 pci_psycho.o pci_sabre.o pci_schizo.o \
19 pci_sun4v.o pci_sun4v_asm.o 20 pci_sun4v.o pci_sun4v_asm.o
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 6f28bec0a9bf..c15a3edcb826 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -597,7 +597,12 @@ __spitfire_cee_trap_continue:
5971: ba,pt %xcc, etrap_irq 5971: ba,pt %xcc, etrap_irq
598 rd %pc, %g7 598 rd %pc, %g7
599 599
6002: mov %l4, %o1 6002:
601#ifdef CONFIG_TRACE_IRQFLAGS
602 call trace_hardirqs_off
603 nop
604#endif
605 mov %l4, %o1
601 mov %l5, %o2 606 mov %l5, %o2
602 call spitfire_access_error 607 call spitfire_access_error
603 add %sp, PTREGS_OFF, %o0 608 add %sp, PTREGS_OFF, %o0
@@ -824,6 +829,10 @@ do_cheetah_plus_data_parity:
824 wrpr %g0, 15, %pil 829 wrpr %g0, 15, %pil
825 ba,pt %xcc, etrap_irq 830 ba,pt %xcc, etrap_irq
826 rd %pc, %g7 831 rd %pc, %g7
832#ifdef CONFIG_TRACE_IRQFLAGS
833 call trace_hardirqs_off
834 nop
835#endif
827 mov 0x0, %o0 836 mov 0x0, %o0
828 call cheetah_plus_parity_error 837 call cheetah_plus_parity_error
829 add %sp, PTREGS_OFF, %o1 838 add %sp, PTREGS_OFF, %o1
@@ -855,6 +864,10 @@ do_cheetah_plus_insn_parity:
855 wrpr %g0, 15, %pil 864 wrpr %g0, 15, %pil
856 ba,pt %xcc, etrap_irq 865 ba,pt %xcc, etrap_irq
857 rd %pc, %g7 866 rd %pc, %g7
867#ifdef CONFIG_TRACE_IRQFLAGS
868 call trace_hardirqs_off
869 nop
870#endif
858 mov 0x1, %o0 871 mov 0x1, %o0
859 call cheetah_plus_parity_error 872 call cheetah_plus_parity_error
860 add %sp, PTREGS_OFF, %o1 873 add %sp, PTREGS_OFF, %o1
@@ -1183,6 +1196,10 @@ c_fast_ecc:
1183 wrpr %g0, 15, %pil 1196 wrpr %g0, 15, %pil
1184 ba,pt %xcc, etrap_irq 1197 ba,pt %xcc, etrap_irq
1185 rd %pc, %g7 1198 rd %pc, %g7
1199#ifdef CONFIG_TRACE_IRQFLAGS
1200 call trace_hardirqs_off
1201 nop
1202#endif
1186 mov %l4, %o1 1203 mov %l4, %o1
1187 mov %l5, %o2 1204 mov %l5, %o2
1188 call cheetah_fecc_handler 1205 call cheetah_fecc_handler
@@ -1211,6 +1228,10 @@ c_cee:
1211 wrpr %g0, 15, %pil 1228 wrpr %g0, 15, %pil
1212 ba,pt %xcc, etrap_irq 1229 ba,pt %xcc, etrap_irq
1213 rd %pc, %g7 1230 rd %pc, %g7
1231#ifdef CONFIG_TRACE_IRQFLAGS
1232 call trace_hardirqs_off
1233 nop
1234#endif
1214 mov %l4, %o1 1235 mov %l4, %o1
1215 mov %l5, %o2 1236 mov %l5, %o2
1216 call cheetah_cee_handler 1237 call cheetah_cee_handler
@@ -1239,6 +1260,10 @@ c_deferred:
1239 wrpr %g0, 15, %pil 1260 wrpr %g0, 15, %pil
1240 ba,pt %xcc, etrap_irq 1261 ba,pt %xcc, etrap_irq
1241 rd %pc, %g7 1262 rd %pc, %g7
1263#ifdef CONFIG_TRACE_IRQFLAGS
1264 call trace_hardirqs_off
1265 nop
1266#endif
1242 mov %l4, %o1 1267 mov %l4, %o1
1243 mov %l5, %o2 1268 mov %l5, %o2
1244 call cheetah_deferred_handler 1269 call cheetah_deferred_handler
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index c8e9dc9d68a9..03ffaf895a22 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -489,6 +489,14 @@ tlb_fixup_done:
489 call __bzero 489 call __bzero
490 sub %o1, %o0, %o1 490 sub %o1, %o0, %o1
491 491
492#ifdef CONFIG_LOCKDEP
493 /* We have this call this super early, as even prom_init can grab
494 * spinlocks and thus call into the lockdep code.
495 */
496 call lockdep_init
497 nop
498#endif
499
492 mov %l6, %o1 ! OpenPROM stack 500 mov %l6, %o1 ! OpenPROM stack
493 call prom_init 501 call prom_init
494 mov %l7, %o0 ! OpenPROM cif handler 502 mov %l7, %o0 ! OpenPROM cif handler
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 3522cd66f3bb..079d18a11d24 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -165,14 +165,26 @@ rtrap:
165__handle_softirq_continue: 165__handle_softirq_continue:
166rtrap_xcall: 166rtrap_xcall:
167 sethi %hi(0xf << 20), %l4 167 sethi %hi(0xf << 20), %l4
168 andcc %l1, TSTATE_PRIV, %l3
169 and %l1, %l4, %l4 168 and %l1, %l4, %l4
169 andn %l1, %l4, %l1
170 srl %l4, 20, %l4
171#ifdef CONFIG_TRACE_IRQFLAGS
172 brnz,pn %l4, rtrap_no_irq_enable
173 nop
174 call trace_hardirqs_on
175 nop
176 wrpr %l4, %pil
177rtrap_no_irq_enable:
178#endif
179 andcc %l1, TSTATE_PRIV, %l3
170 bne,pn %icc, to_kernel 180 bne,pn %icc, to_kernel
171 andn %l1, %l4, %l1 181 nop
172 182
173 /* We must hold IRQs off and atomically test schedule+signal 183 /* We must hold IRQs off and atomically test schedule+signal
174 * state, then hold them off all the way back to userspace. 184 * state, then hold them off all the way back to userspace.
175 * If we are returning to kernel, none of this matters. 185 * If we are returning to kernel, none of this matters. Note
186 * that we are disabling interrupts via PSTATE_IE, not using
187 * %pil.
176 * 188 *
177 * If we do not do this, there is a window where we would do 189 * If we do not do this, there is a window where we would do
178 * the tests, later the signal/resched event arrives but we do 190 * the tests, later the signal/resched event arrives but we do
@@ -256,7 +268,6 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
256 268
257 ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 269 ld [%sp + PTREGS_OFF + PT_V9_Y], %o3
258 wr %o3, %g0, %y 270 wr %o3, %g0, %y
259 srl %l4, 20, %l4
260 wrpr %l4, 0x0, %pil 271 wrpr %l4, 0x0, %pil
261 wrpr %g0, 0x1, %tl 272 wrpr %g0, 0x1, %tl
262 wrpr %l1, %g0, %tstate 273 wrpr %l1, %g0, %tstate
@@ -374,8 +385,8 @@ to_kernel:
374 ldx [%g6 + TI_FLAGS], %l5 385 ldx [%g6 + TI_FLAGS], %l5
375 andcc %l5, _TIF_NEED_RESCHED, %g0 386 andcc %l5, _TIF_NEED_RESCHED, %g0
376 be,pt %xcc, kern_fpucheck 387 be,pt %xcc, kern_fpucheck
377 srl %l4, 20, %l5 388 nop
378 cmp %l5, 0 389 cmp %l4, 0
379 bne,pn %xcc, kern_fpucheck 390 bne,pn %xcc, kern_fpucheck
380 sethi %hi(PREEMPT_ACTIVE), %l6 391 sethi %hi(PREEMPT_ACTIVE), %l6
381 stw %l6, [%g6 + TI_PRE_COUNT] 392 stw %l6, [%g6 + TI_PRE_COUNT]
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c
new file mode 100644
index 000000000000..c4d15f2762b9
--- /dev/null
+++ b/arch/sparc64/kernel/stacktrace.c
@@ -0,0 +1,41 @@
1#include <linux/sched.h>
2#include <linux/stacktrace.h>
3#include <linux/thread_info.h>
4#include <asm/ptrace.h>
5
6void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
7{
8 unsigned long ksp, fp, thread_base;
9 struct thread_info *tp;
10
11 if (!task)
12 task = current;
13 tp = task_thread_info(task);
14 if (task == current) {
15 flushw_all();
16 __asm__ __volatile__(
17 "mov %%fp, %0"
18 : "=r" (ksp)
19 );
20 } else
21 ksp = tp->ksp;
22
23 fp = ksp + STACK_BIAS;
24 thread_base = (unsigned long) tp;
25 do {
26 struct reg_window *rw;
27
28 /* Bogus frame pointer? */
29 if (fp < (thread_base + sizeof(struct thread_info)) ||
30 fp >= (thread_base + THREAD_SIZE))
31 break;
32
33 rw = (struct reg_window *) fp;
34 if (trace->skip > 0)
35 trace->skip--;
36 else
37 trace->entries[trace->nr_entries++] = rw->ins[7];
38
39 fp = rw->ins[6] + STACK_BIAS;
40 } while (trace->nr_entries < trace->max_entries);
41}
diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S
index 49703c3c5769..405855dd886b 100644
--- a/arch/sparc64/kernel/sun4v_ivec.S
+++ b/arch/sparc64/kernel/sun4v_ivec.S
@@ -190,7 +190,10 @@ sun4v_res_mondo:
190 mov %g1, %g4 190 mov %g1, %g4
191 ba,pt %xcc, etrap_irq 191 ba,pt %xcc, etrap_irq
192 rd %pc, %g7 192 rd %pc, %g7
193 193#ifdef CONFIG_TRACE_IRQFLAGS
194 call trace_hardirqs_off
195 nop
196#endif
194 /* Log the event. */ 197 /* Log the event. */
195 add %sp, PTREGS_OFF, %o0 198 add %sp, PTREGS_OFF, %o0
196 call sun4v_resum_error 199 call sun4v_resum_error
@@ -216,7 +219,10 @@ sun4v_res_mondo_queue_full:
216 wrpr %g0, 15, %pil 219 wrpr %g0, 15, %pil
217 ba,pt %xcc, etrap_irq 220 ba,pt %xcc, etrap_irq
218 rd %pc, %g7 221 rd %pc, %g7
219 222#ifdef CONFIG_TRACE_IRQFLAGS
223 call trace_hardirqs_off
224 nop
225#endif
220 call sun4v_resum_overflow 226 call sun4v_resum_overflow
221 add %sp, PTREGS_OFF, %o0 227 add %sp, PTREGS_OFF, %o0
222 228
@@ -295,7 +301,10 @@ sun4v_nonres_mondo:
295 mov %g1, %g4 301 mov %g1, %g4
296 ba,pt %xcc, etrap_irq 302 ba,pt %xcc, etrap_irq
297 rd %pc, %g7 303 rd %pc, %g7
298 304#ifdef CONFIG_TRACE_IRQFLAGS
305 call trace_hardirqs_off
306 nop
307#endif
299 /* Log the event. */ 308 /* Log the event. */
300 add %sp, PTREGS_OFF, %o0 309 add %sp, PTREGS_OFF, %o0
301 call sun4v_nonresum_error 310 call sun4v_nonresum_error
@@ -321,7 +330,10 @@ sun4v_nonres_mondo_queue_full:
321 wrpr %g0, 15, %pil 330 wrpr %g0, 15, %pil
322 ba,pt %xcc, etrap_irq 331 ba,pt %xcc, etrap_irq
323 rd %pc, %g7 332 rd %pc, %g7
324 333#ifdef CONFIG_TRACE_IRQFLAGS
334 call trace_hardirqs_off
335 nop
336#endif
325 call sun4v_nonresum_overflow 337 call sun4v_nonresum_overflow
326 add %sp, PTREGS_OFF, %o0 338 add %sp, PTREGS_OFF, %o0
327 339