aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rootkeys4
-rw-r--r--xen/Rules.mk8
-rw-r--r--xen/arch/x86/Makefile4
-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.c3
-rw-r--r--xen/common/keyhandler.c12
-rw-r--r--xen/drivers/char/console.c3
-rw-r--r--xen/include/asm-x86/debugger.h11
9 files changed, 84 insertions, 60 deletions
diff --git a/.rootkeys b/.rootkeys
index ab7a2c49ce..8c6ec110cb 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -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