From: kfraser@dhcp93.uk.xensource.com Date: Mon, 19 Jun 2006 10:21:40 +0000 (+0100) Subject: [XEN] Improve double-fault tracing -- print backtrace X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15921^2~34 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=8a6db74322526f476023f19afaa2d0ec8f67de55;p=xen.git [XEN] Improve double-fault tracing -- print backtrace on stack overflow. Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index cd143360f9..c3eb12f847 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -276,6 +276,36 @@ void show_stack(struct cpu_user_regs *regs) show_trace(regs); } +void show_stack_overflow(unsigned long esp) +{ +#ifdef MEMORY_GUARD + unsigned long esp_top = get_stack_bottom() & PAGE_MASK; + unsigned long *stack, addr; + + /* Trigger overflow trace if %esp is within 100 bytes of the guard page. */ + if ( ((esp - esp_top) > 100) && ((esp_top - esp) > 100) ) + return; + + if ( esp < esp_top ) + esp = esp_top; + + printk("Xen stack overflow:\n "); + + stack = (unsigned long *)esp; + while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 ) + { + addr = *stack++; + if ( is_kernel_text(addr) ) + { + printk("%p: [<%p>]", stack, _p(addr)); + print_symbol(" %s\n ", addr); + } + } + + printk("\n"); +#endif +} + /* * This is called for faults at very unexpected times (e.g., when interrupts * are disabled). In such situations we can't do much that is safe. We try to diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index c064415aad..d6afff2ab4 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -139,6 +139,7 @@ asmlinkage void do_double_fault(void) tss->esi, tss->edi, tss->ebp, tss->esp); printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n", tss->ds, tss->es, tss->fs, tss->gs, tss->ss); + show_stack_overflow(tss->esp); printk("************************************\n"); printk("CPU%d DOUBLE FAULT -- system shutdown\n", cpu); printk("System needs manual reset.\n"); diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index b5716c23a7..3e416542f1 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -21,7 +21,7 @@ #include -void show_registers(struct cpu_user_regs *regs) +static void __show_registers(struct cpu_user_regs *regs) { struct cpu_user_regs fault_regs = *regs; unsigned long fault_crs[8]; @@ -68,7 +68,11 @@ void show_registers(struct cpu_user_regs *regs) "ss: %04x cs: %04x\n", fault_regs.ds, fault_regs.es, fault_regs.fs, fault_regs.gs, fault_regs.ss, fault_regs.cs); +} +void show_registers(struct cpu_user_regs *regs) +{ + __show_registers(regs); show_stack(regs); } @@ -124,7 +128,8 @@ asmlinkage void do_double_fault(struct cpu_user_regs *regs) /* Find information saved during fault and dump it to the console. */ printk("************************************\n"); - show_registers(regs); + __show_registers(regs); + show_stack_overflow(regs->rsp); printk("************************************\n"); printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id()); printk("System needs manual reset.\n"); diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index f32a763b27..79c683d6ff 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -529,6 +529,7 @@ extern always_inline void prefetchw(const void *x) #endif void show_stack(struct cpu_user_regs *regs); +void show_stack_overflow(unsigned long esp); void show_registers(struct cpu_user_regs *regs); void show_page_walk(unsigned long addr); asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);