# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID 8d75d4e0af1e3ef30fc86874c10288df6ad5a76e
# Parent db37448ffe971e94d1586eea3990fc5e0c49be5d
[XEN] Improve double-fault tracing -- print backtrace
on stack overflow.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/traps.c | 30 ++++++++++++++++++++++++++++++
xen/arch/x86/x86_32/traps.c | 1 +
xen/arch/x86/x86_64/traps.c | 11 ++++++++---
xen/include/asm-x86/processor.h | 1 +
4 files changed, 40 insertions(+), 3 deletions(-)
diff -r db37448ffe97 -r 8d75d4e0af1e xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Mon Jun 19 11:10:10 2006 +0100
+++ b/xen/arch/x86/traps.c Mon Jun 19 11:21:40 2006 +0100
@@ -276,6 +276,36 @@ void show_stack(struct cpu_user_regs *re
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 -r db37448ffe97 -r 8d75d4e0af1e xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Mon Jun 19 11:10:10 2006 +0100
+++ b/xen/arch/x86/x86_32/traps.c Mon Jun 19 11:21:40 2006 +0100
@@ -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 -r db37448ffe97 -r 8d75d4e0af1e xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Mon Jun 19 11:10:10 2006 +0100
+++ b/xen/arch/x86/x86_64/traps.c Mon Jun 19 11:21:40 2006 +0100
@@ -21,7 +21,7 @@
#include <public/callback.h>
-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
"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 c
/* 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 -r db37448ffe97 -r 8d75d4e0af1e xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Mon Jun 19 11:10:10 2006 +0100
+++ b/xen/include/asm-x86/processor.h Mon Jun 19 11:21:40 2006 +0100
@@ -529,6 +529,7 @@ extern always_inline void prefetchw(cons
#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);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|