diff options
-rw-r--r-- | .rootkeys | 4 | ||||
-rw-r--r-- | xen/Rules.mk | 8 | ||||
-rw-r--r-- | xen/arch/x86/Makefile | 4 | ||||
-rw-r--r-- | xen/arch/x86/cdb.c (renamed from xen/arch/x86/xdb.c) | 86 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/cdb_trap.S (renamed from xen/arch/x86/x86_32/xdb_trap.S) | 13 | ||||
-rw-r--r-- | xen/common/domain.c | 3 | ||||
-rw-r--r-- | xen/common/keyhandler.c | 12 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 3 | ||||
-rw-r--r-- | xen/include/asm-x86/debugger.h | 11 |
9 files changed, 84 insertions, 60 deletions
@@ -881,6 +881,7 @@ 3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen/arch/x86/boot/mkelf32.c 3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S 40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S +4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/cdb.c 3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c 40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c 3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c @@ -921,6 +922,7 @@ 41f97ef5139vN42cOYHfX_Ac8WOOjA xen/arch/x86/vmx_platform.c 41c0c4128URE0dxcO15JME_MuKBPfg xen/arch/x86/vmx_vmcs.c 419cbedeQDg8IrO3izo3o5rQNlo0kQ xen/arch/x86/x86_32/asm-offsets.c +4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/cdb_trap.S 4202391dkvdTZ8GhWXe3Gqf9EOgWXg xen/arch/x86/x86_32/domain_build.c 3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c 3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S @@ -928,7 +930,6 @@ 40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c 42000d3ckiFc1qxa4AWqsd0t3lxuyw xen/arch/x86/x86_32/traps.c 3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c -4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/xdb_trap.S 3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds 41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c 4202391dA91ZovYX9d_5zJi9yGvLoQ xen/arch/x86/x86_64/domain_build.c @@ -937,7 +938,6 @@ 42000d3cMb8o1WuFBXC07c8i3lPZBw xen/arch/x86/x86_64/traps.c 40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c 40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds -4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/xdb.c 3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile 3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c 3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c diff --git a/xen/Rules.mk b/xen/Rules.mk index 300efbf581..f8def0ec88 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -5,6 +5,7 @@ debugger ?= n perfc ?= n trace ?= n optimize ?= y +crash_debug ?= n # Currently supported architectures: x86_32, x86_64 COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) @@ -54,8 +55,11 @@ else CFLAGS += -DVERBOSE endif -ifeq ($(gdb_stub),y) -CFLAGS += -g +ifeq ($(crash_debug),y) +CFLAGS += -g -DCRASH_DEBUG +ifeq ($(debugger),y) +error Crash debugger conflicts with PDB +endif endif ifeq ($(perfc),y) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index c2a48624e0..d0750ac400 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -11,6 +11,10 @@ ifneq ($(TARGET_SUBARCH),x86_32) OBJS := $(patsubst vmx%.o,,$(OBJS)) endif +ifneq ($(crash_debug),y) +OBJS := $(subst cdb%.o,,$(OBJS)) +endif + default: $(TARGET) $(TARGET): $(TARGET)-syms boot/mkelf32 diff --git a/xen/arch/x86/xdb.c b/xen/arch/x86/cdb.c index b7bf77057a..db0e9b0371 100644 --- a/xen/arch/x86/xdb.c +++ b/xen/arch/x86/cdb.c @@ -1,16 +1,23 @@ -/* Simple hacked-up version of pdb for us in post-mortem debugging of +/* Simple hacked-up version of pdb for use in post-mortem debugging of Xen and domain 0. This should be a little cleaner, hopefully. Note that we can't share a serial line with PDB. */ +/* We try to avoid assuming much about what the rest of the system is + doing. In particular, dynamic memory allocation is out of the + question. */ #include <xen/lib.h> #include <asm/uaccess.h> #include <xen/serial.h> #include <asm/irq.h> #include <xen/spinlock.h> +#include <asm/debugger.h> /* Printk isn't particularly safe just after we've trapped to the debugger. so avoid it. */ #define dbg_printk(...) +static unsigned char opt_cdb[30] = "none"; +string_param("cdb", opt_cdb); + struct xendbg_context { int serhnd; u8 reply_csum; @@ -24,15 +31,6 @@ xendbg_put_char(u8 data, struct xendbg_context *ctx) serial_putc(ctx->serhnd, data); } -static u8 -xendbg_get_char(struct xendbg_context *ctx) -{ - u8 ch; - extern unsigned char __serial_getc(int handle); - ch = __serial_getc(ctx->serhnd); - return ch; -} - static int hex_char_val(unsigned char c) { @@ -58,11 +56,11 @@ attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx) u8 ch; /* Skip over everything up to the first '$' */ - while ((ch = xendbg_get_char(ctx)) != '$') + while ((ch = irq_serial_getc(ctx->serhnd)) != '$') ; csum = 0; for (count = 0; count < 4096; count++) { - ch = xendbg_get_char(ctx); + ch = irq_serial_getc(ctx->serhnd); if (ch == '#') break; recv_buf[count] = ch; @@ -73,8 +71,8 @@ attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx) return -1; } recv_buf[count] = 0; - received_csum = hex_char_val(xendbg_get_char(ctx)) * 16 + - hex_char_val(xendbg_get_char(ctx)); + received_csum = hex_char_val(irq_serial_getc(ctx->serhnd)) * 16 + + hex_char_val(irq_serial_getc(ctx->serhnd)); if (received_csum == csum) { return 0; } else { @@ -130,7 +128,7 @@ xendbg_finish_reply(struct xendbg_context *ctx) xendbg_put_char('#', ctx); xendbg_send(buf, 2, ctx); - ch = xendbg_get_char(ctx); + ch = irq_serial_getc(ctx->serhnd); if (ch == '+') return 0; else @@ -154,16 +152,13 @@ handle_memory_read_command(unsigned long addr, unsigned long length, int x; unsigned char val; int r; - unsigned old_s_limit; char buf[2]; dbg_printk("Memory read starting at %lx, length %lx.\n", addr, length); - old_s_limit = current->addr_limit.seg; - current->addr_limit.seg = ~0; xendbg_start_reply(ctx); for (x = 0; x < length; x++) { - r = copy_from_user(&val, (void *)(addr + x), 1); + r = __copy_from_user(&val, (void *)(addr + x), 1); if (r != 0) { dbg_printk("Error reading from %lx.\n", addr + x); break; @@ -174,7 +169,6 @@ handle_memory_read_command(unsigned long addr, unsigned long length, if (x == 0) xendbg_send("E05", 3, ctx); dbg_printk("Read done.\n"); - current->addr_limit.seg = old_s_limit; return xendbg_finish_reply(ctx); } @@ -187,7 +181,7 @@ xendbg_send_reply(const char *buf, struct xendbg_context *ctx) } static int -handle_register_read_command(struct pt_regs *regs, struct xendbg_context *ctx) +handle_register_read_command(struct xen_regs *regs, struct xendbg_context *ctx) { char buf[121]; @@ -203,16 +197,16 @@ handle_register_read_command(struct pt_regs *regs, struct xendbg_context *ctx) bswab32(regs->edi), bswab32(regs->eip), bswab32(regs->eflags), - bswab32(regs->xcs), - bswab32(regs->xss), - bswab32(regs->xes), - bswab32(regs->xfs), - bswab32(regs->xgs)); + bswab32(regs->cs), + bswab32(regs->ss), + bswab32(regs->es), + bswab32(regs->fs), + bswab32(regs->gs)); return xendbg_send_reply(buf, ctx); } static int -process_command(char *received_packet, struct pt_regs *regs, +process_command(char *received_packet, struct xen_regs *regs, struct xendbg_context *ctx) { char *ptr; @@ -288,11 +282,11 @@ xdb_ctx = { }; void -__trap_to_xendbg(struct pt_regs *regs) +__trap_to_cdb(struct xen_regs *regs) { int resume = 0; int r; - static int xendbg_running; + static atomic_t xendbg_running = ATOMIC_INIT(1); static char recv_buf[4096]; unsigned flags; @@ -300,24 +294,34 @@ __trap_to_xendbg(struct pt_regs *regs) dbg_printk("Debugger not ready yet.\n"); return; } + + /* Try to make things a little more stable by disabling + interrupts while we're here. */ + local_irq_save(flags); + /* We rely on our caller to ensure we're only on one processor * at a time... We should probably panic here, but given that * we're a debugger we should probably be a little tolerant of * things going wrong. */ - if (xendbg_running) { - dbg_printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n"); + /* We don't want to use a spin lock here, because we're doing + two distinct things: + + 1 -- we don't want to run on more than one processor at a time, + and + 2 -- we want to do something sensible if we re-enter ourselves. + + Spin locks are good for 1, but useless for 2. */ + if (!atomic_dec_and_test(&xendbg_running)) { + printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n"); + atomic_inc(&xendbg_running); + local_irq_restore(flags); return; } - xendbg_running = 1; /* Shouldn't really do this, but otherwise we stop for no obvious reason, which is Bad */ printk("Waiting for GDB to attach to XenDBG\n"); - /* Try to make things a little more stable by disabling - interrupts while we're here. */ - local_irq_save(flags); - /* If gdb is already attached, tell it we've stopped again. */ if (xdb_ctx.currently_attached) { do { @@ -333,20 +337,18 @@ __trap_to_xendbg(struct pt_regs *regs) } else resume = process_command(recv_buf, regs, &xdb_ctx); } - xendbg_running = 0; + atomic_inc(&xendbg_running); local_irq_restore(flags); } void initialize_xendbg(void) { - extern char opt_xendbg[]; - - if (!strcmp(opt_xendbg, "none")) + if (!strcmp(opt_cdb, "none")) return; - xdb_ctx.serhnd = parse_serial_handle(opt_xendbg); + xdb_ctx.serhnd = parse_serial_handle(opt_cdb); if (xdb_ctx.serhnd == -1) - panic("Can't parse %s as XDB serial info.\n", opt_xendbg); + panic("Can't parse %s as CDB serial info.\n", opt_cdb); /* Acknowledge any spurious GDB packets. */ xendbg_put_char('+', &xdb_ctx); diff --git a/xen/arch/x86/x86_32/xdb_trap.S b/xen/arch/x86/x86_32/cdb_trap.S index 262c6dbf73..dfae4c5e42 100644 --- a/xen/arch/x86/x86_32/xdb_trap.S +++ b/xen/arch/x86/x86_32/cdb_trap.S @@ -1,5 +1,5 @@ -.global trap_to_xendbg -.extern __trap_to_xendbg +.global cdb_trap +.extern __trap_to_cdb #define SAVE_ALL_NOSEGREGS \ pushw $0; \ @@ -18,11 +18,11 @@ pushl %ecx; \ pushl %ebx; - // Save the register state and call __trap_to_xendbg -trap_to_xendbg: + // Save the register state and call __trap_to_cdb +cdb_trap: pushw $0 pushw %ss - pushl %esp //We'll fix this up later, in __trap_to_xendbg, by adding 8 + pushl %esp //We'll fix this up later, in __trap_to_cdb, by adding 8 pushf pushw $0 pushw %cs @@ -30,6 +30,7 @@ trap_to_xendbg: 1: pushl $0 // Orig_eax SAVE_ALL_NOSEGREGS pushl %esp - call __trap_to_xendbg + call __trap_to_cdb add $72, %esp + xorl %eax, %eax ret diff --git a/xen/common/domain.c b/xen/common/domain.c index 394e9804be..081c68820f 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -18,6 +18,7 @@ #include <asm/shadow.h> #include <public/dom0_ops.h> #include <asm/domain_page.h> +#include <asm/debugger.h> /* Both these structures are protected by the domlist_lock. */ rwlock_t domlist_lock = RW_LOCK_UNLOCKED; @@ -172,7 +173,7 @@ void domain_shutdown(u8 reason) extern void machine_restart(char *); extern void machine_halt(void); - trap_to_xendbg(); + debugger_trap_immediate(); if ( reason == 0 ) { diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 5b5cd662ef..571b76e59b 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -10,6 +10,7 @@ #include <xen/serial.h> #include <xen/sched.h> #include <xen/softirq.h> +#include <asm/debugger.h> #define KEY_MAX 256 #define STR_MAX 64 @@ -146,13 +147,12 @@ extern void perfc_printall(unsigned char key); extern void perfc_reset(unsigned char key); #endif -void do_debug_key(unsigned char key, void *dev_id, struct pt_regs *regs) +void do_debug_key(unsigned char key, struct xen_regs *regs) { - extern void trap_to_xendbg(void); - trap_to_xendbg(); + debugger_trap_fatal(0xf001, regs); asm volatile ("nop"); /* Prevent the compiler doing tail call - optimisation, as that confuses xendbg a - bit. */ + optimisation, as that confuses xendbg a + bit. */ } void initialize_keytable(void) @@ -185,5 +185,5 @@ void initialize_keytable(void) register_keyhandler( 'P', perfc_reset, "reset performance counters"); #endif - add_key_handler('%', do_debug_key, "Trap to xendbg"); + register_irq_keyhandler('%', do_debug_key, "Trap to xendbg"); } diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index a94714bcb8..c0a9dd248e 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -20,6 +20,7 @@ #include <xen/keyhandler.h> #include <asm/uaccess.h> #include <asm/mm.h> +#include <asm/debugger.h> /* opt_console: comma-separated list of console outputs. */ static unsigned char opt_console[30] = OPT_CONSOLE_STR; @@ -497,7 +498,7 @@ void panic(const char *fmt, ...) (void)vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - trap_to_xendbg(); + debugger_trap_immediate(); /* Spit out multiline message in one go. */ spin_lock_irqsave(&console_lock, flags); diff --git a/xen/include/asm-x86/debugger.h b/xen/include/asm-x86/debugger.h index d44b2d5e62..74e8a82ef5 100644 --- a/xen/include/asm-x86/debugger.h +++ b/xen/include/asm-x86/debugger.h @@ -93,6 +93,16 @@ static inline int debugger_trap_fatal( return ret; } +#define debugger_trap_immediate() () + +#elif defined(CRASH_DEBUG) + +extern void cdb_trap(void); +extern void __trap_to_cdb(struct xen_regs *); +#define debugger_trap_entry(_v, _r) (0) +#define debugger_trap_fatal(_v, _r) (__trap_to_cdb(_r), 0) +#define debugger_trap_immediate() (cdb_trap()) + #elif 0 extern int kdb_trap(int, int, struct xen_regs *); @@ -113,6 +123,7 @@ static inline int debugger_trap_fatal( #define debugger_trap_entry(_v, _r) (0) #define debugger_trap_fatal(_v, _r) (0) +#define debugger_trap_immediate() () #endif |