From 1fcbe027b5d29ec9cd0eeb753c14fb366ae852ac Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Fri, 13 Aug 2010 08:40:57 -0400 Subject: arch/tile: support backtracing on TILE-Gx This functionality was stubbed out until recently. Now we support our normal backtracing API on TILE-Gx as well as on TILE64/TILEPro. This change includes a tweak to the instruction encoding caused by adding addxli for compat mode. Signed-off-by: Chris Metcalf --- arch/tile/kernel/stack.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/tile/kernel/stack.c') diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index b6268d3ae869..38a68b0b4581 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c @@ -108,7 +108,6 @@ static bool read_memory_func(void *result, VirtualAddress address, /* Return a pt_regs pointer for a valid fault handler frame */ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt) { -#ifndef __tilegx__ const char *fault = NULL; /* happy compiler */ char fault_buf[64]; VirtualAddress sp = kbt->it.sp; @@ -146,7 +145,6 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt) } if (!kbt->profile || (INT_MASK(p->faultnum) & QUEUED_INTERRUPTS) == 0) return p; -#endif return NULL; } @@ -351,12 +349,6 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) kbt->task->pid, kbt->task->tgid, kbt->task->comm, smp_processor_id(), get_cycles()); } -#ifdef __tilegx__ - if (kbt->is_current) { - __insn_mtspr(SPR_SIM_CONTROL, - SIM_DUMP_SPR_ARG(SIM_DUMP_BACKTRACE)); - } -#endif kbt->verbose = 1; i = 0; for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) { -- cgit v1.2.3 From 74fca9da097b74117ae2cef9e5f0d9b0e28ccbb7 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 15 Sep 2010 11:16:08 -0400 Subject: arch/tile: Change struct sigcontext to be more useful Rather than just using pt_regs, it now contains the actual saved state explicitly, similar to pt_regs. By doing it this way, we provide a cleaner API for userspace (or equivalently, we avoid the need for libc to provide its own definition of sigcontext). While we're at it, move PT_FLAGS_xxx to where they are not visible from userspace. And always pass siginfo and mcontext to signal handlers, even if they claim they don't need it, since sometimes they actually try to use it anyway in practice. Signed-off-by: Chris Metcalf --- arch/tile/kernel/stack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/tile/kernel/stack.c') diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index 38a68b0b4581..ea2e0ce28380 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c @@ -175,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) pr_err(" \n", frame->info.si_signo); } - return &frame->uc.uc_mcontext.regs; + return (struct pt_regs *)&frame->uc.uc_mcontext; } return NULL; } -- cgit v1.2.3 From dabe98c972091818762e02841ab1f982e573e7d0 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Thu, 14 Oct 2010 15:19:04 -0400 Subject: arch/tile: prevent corrupt top frame from causing backtracer runaway The backtracer will normally cut itself off after 100 frames anyway, but it's messy. With this change we notice that the frame being reported is the same as the last one, and cut off the dump with a message similar to what gdb displays in the same circumstance. Signed-off-by: Chris Metcalf --- arch/tile/kernel/stack.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'arch/tile/kernel/stack.c') diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index ea2e0ce28380..0d54106be3d6 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c @@ -30,6 +30,10 @@ #include #include +#define KBT_ONGOING 0 /* Backtrace still ongoing */ +#define KBT_DONE 1 /* Backtrace cleanly completed */ +#define KBT_RUNNING 2 /* Can't run backtrace on a running task */ +#define KBT_LOOP 3 /* Backtrace entered a loop */ /* Is address on the specified kernel stack? */ static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp) @@ -207,11 +211,11 @@ static int KBacktraceIterator_next_item_inclusive( for (;;) { do { if (!KBacktraceIterator_is_sigreturn(kbt)) - return 1; + return KBT_ONGOING; } while (backtrace_next(&kbt->it)); if (!KBacktraceIterator_restart(kbt)) - return 0; + return KBT_DONE; } } @@ -264,7 +268,7 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt, kbt->pgtable = NULL; kbt->verbose = 0; /* override in caller if desired */ kbt->profile = 0; /* override in caller if desired */ - kbt->end = 0; + kbt->end = KBT_ONGOING; kbt->new_context = 0; if (is_current) { HV_PhysAddr pgdir_pa = hv_inquire_context().page_table; @@ -290,7 +294,7 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt, if (regs == NULL) { if (is_current || t->state == TASK_RUNNING) { /* Can't do this; we need registers */ - kbt->end = 1; + kbt->end = KBT_RUNNING; return; } pc = get_switch_to_pc(); @@ -305,26 +309,29 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt, } backtrace_init(&kbt->it, read_memory_func, kbt, pc, lr, sp, r52); - kbt->end = !KBacktraceIterator_next_item_inclusive(kbt); + kbt->end = KBacktraceIterator_next_item_inclusive(kbt); } EXPORT_SYMBOL(KBacktraceIterator_init); int KBacktraceIterator_end(struct KBacktraceIterator *kbt) { - return kbt->end; + return kbt->end != KBT_ONGOING; } EXPORT_SYMBOL(KBacktraceIterator_end); void KBacktraceIterator_next(struct KBacktraceIterator *kbt) { + VirtualAddress old_pc = kbt->it.pc, old_sp = kbt->it.sp; kbt->new_context = 0; - if (!backtrace_next(&kbt->it) && - !KBacktraceIterator_restart(kbt)) { - kbt->end = 1; - return; - } - - kbt->end = !KBacktraceIterator_next_item_inclusive(kbt); + if (!backtrace_next(&kbt->it) && !KBacktraceIterator_restart(kbt)) { + kbt->end = KBT_DONE; + return; + } + kbt->end = KBacktraceIterator_next_item_inclusive(kbt); + if (old_pc == kbt->it.pc && old_sp == kbt->it.sp) { + /* Trapped in a loop; give up. */ + kbt->end = KBT_LOOP; + } } EXPORT_SYMBOL(KBacktraceIterator_next); @@ -387,6 +394,8 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) break; } } + if (kbt->end == KBT_LOOP) + pr_err("Stack dump stopped; next frame identical to this one\n"); if (headers) pr_err("Stack dump complete\n"); } -- cgit v1.2.3