aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>2004-11-13 17:17:59 +0000
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>2004-11-13 17:17:59 +0000
commit5435ea302127058a5f7f9b76f20d64ded949fd5a (patch)
tree7fadeb7693fffee58641f482eb973c1b8420ba18
parent92d81c3c284e90da3169e79b5e8ab91e17403961 (diff)
downloadxen-5435ea302127058a5f7f9b76f20d64ded949fd5a.tar.gz
xen-5435ea302127058a5f7f9b76f20d64ded949fd5a.tar.bz2
xen-5435ea302127058a5f7f9b76f20d64ded949fd5a.zip
bitkeeper revision 1.1159.170.19 (419641c7PFSwb0OCvYznpBOaQJY6Fw)
Cleaned up debugger interface to traps.c.
-rw-r--r--.rootkeys2
-rw-r--r--xen/arch/x86/pdb-stub.c21
-rw-r--r--xen/arch/x86/traps.c81
-rw-r--r--xen/include/asm-x86/debugger.h137
-rw-r--r--xen/include/asm-x86/pdb.h2
-rw-r--r--xen/include/xen/debugger_hooks.h37
6 files changed, 183 insertions, 97 deletions
diff --git a/.rootkeys b/.rootkeys
index 45ec7aa3a7..3556df5ba0 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -704,6 +704,7 @@
404f1b920OQVnrbnXnySS-WxrH9Wzw xen/include/asm-x86/config.h
3ddb79c2LLt11EQHjrd6sB7FUqvFfA xen/include/asm-x86/cpufeature.h
40cf1596ajIU1KJfF22XD-tSLfH6XA xen/include/asm-x86/current.h
+4194efbdvxUXjCLobbopgLOojisO4Q xen/include/asm-x86/debugger.h
3ddb79c2jFkPAZTDmU35L6IUssYMgQ xen/include/asm-x86/debugreg.h
3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h
3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h
@@ -768,7 +769,6 @@
3ddb79c259jh8hE7vre_8NuE7nwNSA xen/include/xen/config.h
3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h
3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h
-4194efbdvxUXjCLobbopgLOojisO4Q xen/include/xen/debugger_hooks.h
3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h
3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h
3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
diff --git a/xen/arch/x86/pdb-stub.c b/xen/arch/x86/pdb-stub.c
index a6133b78ae..946755d909 100644
--- a/xen/arch/x86/pdb-stub.c
+++ b/xen/arch/x86/pdb-stub.c
@@ -1214,6 +1214,27 @@ void pdb_key_pressed(unsigned char key)
pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
}
+void pdb_handle_debug_trap(struct xen_regs *regs, long error_code)
+{
+ unsigned int condition;
+ struct domain *tsk = current;
+ struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
+
+ __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
+ if ( (condition & (1 << 14)) != (1 << 14) )
+ printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
+ __asm__("movl %0,%%db6" : : "r" (0));
+
+ if ( pdb_handle_exception(1, regs) != 0 )
+ {
+ tsk->thread.debugreg[6] = condition;
+
+ gtb->flags = GTBF_TRAP_NOCODE;
+ gtb->cs = tsk->thread.traps[1].cs;
+ gtb->eip = tsk->thread.traps[1].address;
+ }
+}
+
void initialize_pdb()
{
extern char opt_pdb[];
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 2026432ec0..815740773b 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -50,8 +50,7 @@
#include <asm/flushtlb.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
-#include <asm/pdb.h>
-#include <xen/debugger_hooks.h>
+#include <asm/debugger.h>
extern char opt_nmi[];
@@ -223,7 +222,9 @@ static inline void do_trap(int trapnr, char *str,
trap_info_t *ti;
unsigned long fixup;
- if (!(regs->cs & 3))
+ DEBUGGER_trap_entry(trapnr, regs, error_code);
+
+ if ( !(regs->cs & 3) )
goto xen_fault;
ti = current->thread.traps + trapnr;
@@ -244,8 +245,7 @@ static inline void do_trap(int trapnr, char *str,
return;
}
- if (debugger_trap(trapnr, regs))
- return;
+ DEBUGGER_trap_fatal(trapnr, regs, error_code);
show_registers(regs);
panic("CPU%d FATAL TRAP: vector = %d (%s)\n"
@@ -284,18 +284,15 @@ asmlinkage void do_int3(struct xen_regs *regs, long error_code)
struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
trap_info_t *ti;
- if (debugger_trap(3, regs))
- return;
+ DEBUGGER_trap_entry(TRAP_int3, regs, error_code);
- if ( (regs->cs & 3) != 3 )
+ if ( unlikely((regs->cs & 3) == 0) )
{
- if ( unlikely((regs->cs & 3) == 0) )
- {
- show_registers(regs);
- panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n"
- "[error_code=%08x]\n",
- smp_processor_id(), error_code);
- }
+ DEBUGGER_trap_fatal(TRAP_int3, regs, error_code);
+ show_registers(regs);
+ panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n"
+ "[error_code=%08x]\n",
+ smp_processor_id(), error_code);
}
ti = current->thread.traps + 3;
@@ -331,7 +328,7 @@ asmlinkage void do_double_fault(void)
printk("System needs manual reset.\n");
printk("************************************\n");
- debugger_trap(8, NULL);
+ DEBUGGER_trap_fatal(TRAP_double_fault, NULL, 0);
/* Lock up the console to prevent spurious output from other CPUs. */
console_force_lock();
@@ -351,6 +348,8 @@ asmlinkage void do_page_fault(struct xen_regs *regs, long error_code)
__asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
+ DEBUGGER_trap_entry(TRAP_page_fault, regs, error_code);
+
perfc_incrc(page_faults);
if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
@@ -410,8 +409,7 @@ asmlinkage void do_page_fault(struct xen_regs *regs, long error_code)
return;
}
- if (debugger_trap(14, regs))
- return;
+ DEBUGGER_trap_fatal(TRAP_page_fault, regs, error_code);
if ( addr >= PAGE_OFFSET )
{
@@ -444,6 +442,8 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
trap_info_t *ti;
unsigned long fixup;
+ DEBUGGER_trap_entry(TRAP_gp_fault, regs, error_code);
+
/* Badness if error in ring 0, or result of an interrupt. */
if ( !(regs->cs & 3) || (error_code & 1) )
goto gp_in_kernel;
@@ -474,15 +474,6 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
ti = current->thread.traps + (error_code>>3);
if ( TI_GET_DPL(ti) >= (regs->cs & 3) )
{
-#ifdef XEN_DEBUGGER
- if ( pdb_initialized && (pdb_ctx.system_call != 0) )
- {
- unsigned long cr3 = read_cr3();
- if ( cr3 == pdb_ctx.ptbr )
- pdb_linux_syscall_enter_bkpt(regs, error_code, ti);
- }
-#endif
-
gtb->flags = GTBF_TRAP_NOCODE;
regs->eip += 2;
goto finish_propagation;
@@ -495,7 +486,7 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
gpf_emulate_4gb(regs) )
return;
#endif
-
+
/* Pass on GPF as is. */
ti = current->thread.traps + 13;
gtb->flags = GTBF_TRAP;
@@ -516,8 +507,7 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
return;
}
- if (debugger_trap(13, regs))
- return;
+ DEBUGGER_trap_fatal(TRAP_gp_fault, regs, error_code);
die("general protection fault", regs, error_code);
}
@@ -564,8 +554,7 @@ asmlinkage void io_check_error(struct xen_regs *regs)
static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs)
{
- if (debugger_trap(2, regs))
- return;
+ DEBUGGER_trap_entry(TRAP_nmi, regs, 0);
printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
printk("Dazed and confused, but trying to continue\n");
@@ -620,39 +609,13 @@ asmlinkage void math_state_restore(struct xen_regs *regs, long error_code)
}
}
-#ifdef XEN_DEBUGGER
-asmlinkage void do_pdb_debug(struct xen_regs *regs, long error_code)
-{
- unsigned int condition;
- struct domain *tsk = current;
- struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
-
- __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
- if ( (condition & (1 << 14)) != (1 << 14) )
- printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
- __asm__("movl %0,%%db6" : : "r" (0));
-
- if ( pdb_handle_exception(1, regs) != 0 )
- {
- tsk->thread.debugreg[6] = condition;
-
- gtb->flags = GTBF_TRAP_NOCODE;
- gtb->cs = tsk->thread.traps[1].cs;
- gtb->eip = tsk->thread.traps[1].address;
- }
-}
-#endif
-
asmlinkage void do_debug(struct xen_regs *regs, long error_code)
{
unsigned int condition;
struct domain *tsk = current;
struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
-#ifdef XEN_DEBUGGER
- if ( pdb_initialized )
- return do_pdb_debug(regs, error_code);
-#endif
+ DEBUGGER_trap_entry(TRAP_debug, regs, error_code);
__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
diff --git a/xen/include/asm-x86/debugger.h b/xen/include/asm-x86/debugger.h
new file mode 100644
index 0000000000..b19e099a9f
--- /dev/null
+++ b/xen/include/asm-x86/debugger.h
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * asm/debugger.h
+ *
+ * Generic hooks into arch-dependent Xen.
+ *
+ * Each debugger should define two functions here:
+ *
+ * 1. debugger_trap_entry():
+ * Called at start of any synchronous fault or trap, before any other work
+ * is done. The idea is that if your debugger deliberately caused the trap
+ * (e.g. to implement breakpoints or data watchpoints) then you can take
+ * appropriate action and return a non-zero value to cause early exit from
+ * the trap function.
+ *
+ * 2. debugger_trap_fatal():
+ * Called when Xen is about to give up and crash. Typically you will use this
+ * hook to drop into a debug session. It can also be used to hook off
+ * deliberately caused traps (which you then handle and return non-zero)
+ * but really these should be hooked off 'debugger_trap_entry'.
+ */
+
+#ifndef __X86_DEBUGGER_H__
+#define __X86_DEBUGGER_H__
+
+/* Avoid magic vector numbers by using these semi-sensical names. */
+#define TRAP_divide_error 0
+#define TRAP_debug 1
+#define TRAP_nmi 2
+#define TRAP_int3 3
+#define TRAP_overflow 4
+#define TRAP_bounds 5
+#define TRAP_invalid_op 6
+#define TRAP_no_device 7
+#define TRAP_double_fault 8
+#define TRAP_copro_seg 9
+#define TRAP_invalid_tss 10
+#define TRAP_no_segment 11
+#define TRAP_stack_error 12
+#define TRAP_gp_fault 13
+#define TRAP_page_fault 14
+#define TRAP_spurious_int 15
+#define TRAP_copro_error 16
+#define TRAP_alignment_check 17
+#define TRAP_machine_check 18
+#define TRAP_simd_error 19
+
+/* The main trap handlers use these helper macros which include early bail. */
+#define DEBUGGER_trap_entry(_v, _r, _e) \
+ if ( debugger_trap_entry(_v, _r, _e) ) return;
+#define DEBUGGER_trap_fatal(_v, _r, _e) \
+ if ( debugger_trap_fatal(_v, _r, _e) ) return;
+
+#ifdef XEN_DEBUGGER
+
+#include <asm/pdb.h>
+
+static inline int debugger_trap_entry(
+ unsigned int vector, struct xen_regs *regs, unsigned int error_code)
+{
+ int ret = 0;
+
+ switch ( vector )
+ {
+ case TRAP_debug:
+ if ( pdb_initialized )
+ {
+ pdb_handle_debug_trap(regs, (long)error_code);
+ ret = 1; /* early exit */
+ }
+ break;
+
+ case TRAP_int3:
+ if ( pdb_initialized && (pdb_handle_exception(vector, regs) == 0) )
+ ret = 1; /* early exit */
+ break;
+
+ case TRAP_gp_fault:
+ if ( ((regs->cs & 3) != 0) && ((error_code & 3) == 2) &&
+ pdb_initialized && (pdb_ctx.system_call != 0) )
+ {
+ unsigned long cr3 = read_cr3();
+ if ( cr3 == pdb_ctx.ptbr )
+ pdb_linux_syscall_enter_bkpt(
+ regs, error_code, current->thread.traps + (error_code>>3));
+ }
+ break;
+ }
+
+ return ret;
+}
+
+static inline int debugger_trap_fatal(
+ unsigned int vector, struct xen_regs *regs, unsigned int error_code)
+{
+ int ret = 0;
+
+ switch ( vector )
+ {
+ case TRAP_page_fault:
+ if ( pdb_page_fault_possible )
+ {
+ pdb_page_fault = 1;
+ /* make eax & edx valid to complete the instruction */
+ regs->eax = (long)&pdb_page_fault_scratch;
+ regs->edx = (long)&pdb_page_fault_scratch;
+ ret = 1; /* exit - do not crash! */
+ }
+ break;
+ }
+
+ return ret;
+}
+
+#elif 0
+
+extern int kdb_trap(int, int, struct xen_regs *);
+
+static inline int debugger_trap_entry(
+ unsigned int vector, struct xen_regs *regs, unsigned int error_code)
+{
+ return 0;
+}
+
+static inline int debugger_trap_fatal(
+ unsigned int vector, struct xen_regs *regs, unsigned int error_code)
+{
+ return kdb_trap(vector, 0, regs);
+}
+
+#else
+
+#define debugger_trap_entry(_v, _r, _e) (0)
+#define debugger_trap_fatal(_v, _r, _e) (0)
+
+#endif
+
+#endif /* __X86_DEBUGGER_H__ */
diff --git a/xen/include/asm-x86/pdb.h b/xen/include/asm-x86/pdb.h
index 39386f82ea..79b0c4183b 100644
--- a/xen/include/asm-x86/pdb.h
+++ b/xen/include/asm-x86/pdb.h
@@ -84,4 +84,6 @@ void pdb_linux_syscall_enter_bkpt (struct xen_regs *regs, long error_code,
void pdb_linux_syscall_exit_bkpt (struct xen_regs *regs,
struct pdb_context *pdb_ctx);
+void pdb_handle_debug_trap(struct xen_regs *regs, long error_code);
+
#endif /* __PDB_H__ */
diff --git a/xen/include/xen/debugger_hooks.h b/xen/include/xen/debugger_hooks.h
deleted file mode 100644
index 4663b2b3bd..0000000000
--- a/xen/include/xen/debugger_hooks.h
+++ /dev/null
@@ -1,37 +0,0 @@
-
-#ifndef __DEBUGGER_HOOKS_H__
-#define __DEBUGGER_HOOKS_H__
-
-static inline int debugger_trap(int type, struct xen_regs *regs)
-{
- int ret = 0;
-
-#ifdef XEN_DEBUGGER
- switch (type) {
- case 3:
- if ( pdb_initialized && pdb_handle_exception(type, regs) == 0 )
- return 1;
- break;
- case 14:
- if ( pdb_page_fault_possible )
- {
- pdb_page_fault = 1;
- /* make eax & edx valid to complete the instruction */
- regs->eax = (long)&pdb_page_fault_scratch;
- regs->edx = (long)&pdb_page_fault_scratch;
- return 1;
- }
- break;
- }
-#endif
-
-#if 0
- extern int kdb_trap(int, int, struct xen_regs *);
- if ((ret = kdb_trap(type, 0, regs)))
- return ret;
-#endif
-
- return ret;
-}
-
-#endif /* __DEBUGGER_HOOKS_H__ */