diff options
author | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-13 17:17:59 +0000 |
---|---|---|
committer | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-13 17:17:59 +0000 |
commit | 5435ea302127058a5f7f9b76f20d64ded949fd5a (patch) | |
tree | 7fadeb7693fffee58641f482eb973c1b8420ba18 | |
parent | 92d81c3c284e90da3169e79b5e8ab91e17403961 (diff) | |
download | xen-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-- | .rootkeys | 2 | ||||
-rw-r--r-- | xen/arch/x86/pdb-stub.c | 21 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 81 | ||||
-rw-r--r-- | xen/include/asm-x86/debugger.h | 137 | ||||
-rw-r--r-- | xen/include/asm-x86/pdb.h | 2 | ||||
-rw-r--r-- | xen/include/xen/debugger_hooks.h | 37 |
6 files changed, 183 insertions, 97 deletions
@@ -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__ */ |