[SPARC64]: Add irqtrace/stacktrace/lockdep support.
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
af1713e0f1
commit
10e267234c
@@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
|
||||
power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
|
||||
visemul.o prom.o of_device.o
|
||||
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
|
||||
pci_psycho.o pci_sabre.o pci_schizo.o \
|
||||
pci_sun4v.o pci_sun4v_asm.o
|
||||
|
@@ -597,7 +597,12 @@ __spitfire_cee_trap_continue:
|
||||
1: ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
2: mov %l4, %o1
|
||||
2:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call spitfire_access_error
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
@@ -824,6 +829,10 @@ do_cheetah_plus_data_parity:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov 0x0, %o0
|
||||
call cheetah_plus_parity_error
|
||||
add %sp, PTREGS_OFF, %o1
|
||||
@@ -855,6 +864,10 @@ do_cheetah_plus_insn_parity:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov 0x1, %o0
|
||||
call cheetah_plus_parity_error
|
||||
add %sp, PTREGS_OFF, %o1
|
||||
@@ -1183,6 +1196,10 @@ c_fast_ecc:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call cheetah_fecc_handler
|
||||
@@ -1211,6 +1228,10 @@ c_cee:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call cheetah_cee_handler
|
||||
@@ -1239,6 +1260,10 @@ c_deferred:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call cheetah_deferred_handler
|
||||
|
@@ -489,6 +489,14 @@ tlb_fixup_done:
|
||||
call __bzero
|
||||
sub %o1, %o0, %o1
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
/* We have this call this super early, as even prom_init can grab
|
||||
* spinlocks and thus call into the lockdep code.
|
||||
*/
|
||||
call lockdep_init
|
||||
nop
|
||||
#endif
|
||||
|
||||
mov %l6, %o1 ! OpenPROM stack
|
||||
call prom_init
|
||||
mov %l7, %o0 ! OpenPROM cif handler
|
||||
|
@@ -165,14 +165,26 @@ rtrap:
|
||||
__handle_softirq_continue:
|
||||
rtrap_xcall:
|
||||
sethi %hi(0xf << 20), %l4
|
||||
andcc %l1, TSTATE_PRIV, %l3
|
||||
and %l1, %l4, %l4
|
||||
andn %l1, %l4, %l1
|
||||
srl %l4, 20, %l4
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
brnz,pn %l4, rtrap_no_irq_enable
|
||||
nop
|
||||
call trace_hardirqs_on
|
||||
nop
|
||||
wrpr %l4, %pil
|
||||
rtrap_no_irq_enable:
|
||||
#endif
|
||||
andcc %l1, TSTATE_PRIV, %l3
|
||||
bne,pn %icc, to_kernel
|
||||
andn %l1, %l4, %l1
|
||||
nop
|
||||
|
||||
/* We must hold IRQs off and atomically test schedule+signal
|
||||
* state, then hold them off all the way back to userspace.
|
||||
* If we are returning to kernel, none of this matters.
|
||||
* If we are returning to kernel, none of this matters. Note
|
||||
* that we are disabling interrupts via PSTATE_IE, not using
|
||||
* %pil.
|
||||
*
|
||||
* If we do not do this, there is a window where we would do
|
||||
* 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
|
||||
|
||||
ld [%sp + PTREGS_OFF + PT_V9_Y], %o3
|
||||
wr %o3, %g0, %y
|
||||
srl %l4, 20, %l4
|
||||
wrpr %l4, 0x0, %pil
|
||||
wrpr %g0, 0x1, %tl
|
||||
wrpr %l1, %g0, %tstate
|
||||
@@ -374,8 +385,8 @@ to_kernel:
|
||||
ldx [%g6 + TI_FLAGS], %l5
|
||||
andcc %l5, _TIF_NEED_RESCHED, %g0
|
||||
be,pt %xcc, kern_fpucheck
|
||||
srl %l4, 20, %l5
|
||||
cmp %l5, 0
|
||||
nop
|
||||
cmp %l4, 0
|
||||
bne,pn %xcc, kern_fpucheck
|
||||
sethi %hi(PREEMPT_ACTIVE), %l6
|
||||
stw %l6, [%g6 + TI_PRE_COUNT]
|
||||
|
41
arch/sparc64/kernel/stacktrace.c
Normal file
41
arch/sparc64/kernel/stacktrace.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
|
||||
{
|
||||
unsigned long ksp, fp, thread_base;
|
||||
struct thread_info *tp;
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
tp = task_thread_info(task);
|
||||
if (task == current) {
|
||||
flushw_all();
|
||||
__asm__ __volatile__(
|
||||
"mov %%fp, %0"
|
||||
: "=r" (ksp)
|
||||
);
|
||||
} else
|
||||
ksp = tp->ksp;
|
||||
|
||||
fp = ksp + STACK_BIAS;
|
||||
thread_base = (unsigned long) tp;
|
||||
do {
|
||||
struct reg_window *rw;
|
||||
|
||||
/* Bogus frame pointer? */
|
||||
if (fp < (thread_base + sizeof(struct thread_info)) ||
|
||||
fp >= (thread_base + THREAD_SIZE))
|
||||
break;
|
||||
|
||||
rw = (struct reg_window *) fp;
|
||||
if (trace->skip > 0)
|
||||
trace->skip--;
|
||||
else
|
||||
trace->entries[trace->nr_entries++] = rw->ins[7];
|
||||
|
||||
fp = rw->ins[6] + STACK_BIAS;
|
||||
} while (trace->nr_entries < trace->max_entries);
|
||||
}
|
@@ -190,7 +190,10 @@ sun4v_res_mondo:
|
||||
mov %g1, %g4
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
/* Log the event. */
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
call sun4v_resum_error
|
||||
@@ -216,7 +219,10 @@ sun4v_res_mondo_queue_full:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
call sun4v_resum_overflow
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
|
||||
@@ -295,7 +301,10 @@ sun4v_nonres_mondo:
|
||||
mov %g1, %g4
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
/* Log the event. */
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
call sun4v_nonresum_error
|
||||
@@ -321,7 +330,10 @@ sun4v_nonres_mondo_queue_full:
|
||||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
call sun4v_nonresum_overflow
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
|
||||
|
Reference in New Issue
Block a user