ia64/xen-unstable
changeset 2971:4d94e2b30873
bitkeeper revision 1.1159.170.19 (419641c7PFSwb0OCvYznpBOaQJY6Fw)
Cleaned up debugger interface to traps.c.
Cleaned up debugger interface to traps.c.
author | kaf24@freefall.cl.cam.ac.uk |
---|---|
date | Sat Nov 13 17:17:59 2004 +0000 (2004-11-13) |
parents | 34da3b621a8a |
children | 3c505be01ff1 |
files | .rootkeys xen/arch/x86/pdb-stub.c xen/arch/x86/traps.c xen/include/asm-x86/debugger.h xen/include/asm-x86/pdb.h xen/include/xen/debugger_hooks.h |
line diff
1.1 --- a/.rootkeys Sat Nov 13 16:10:28 2004 +0000 1.2 +++ b/.rootkeys Sat Nov 13 17:17:59 2004 +0000 1.3 @@ -704,6 +704,7 @@ 3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/inclu 1.4 404f1b920OQVnrbnXnySS-WxrH9Wzw xen/include/asm-x86/config.h 1.5 3ddb79c2LLt11EQHjrd6sB7FUqvFfA xen/include/asm-x86/cpufeature.h 1.6 40cf1596ajIU1KJfF22XD-tSLfH6XA xen/include/asm-x86/current.h 1.7 +4194efbdvxUXjCLobbopgLOojisO4Q xen/include/asm-x86/debugger.h 1.8 3ddb79c2jFkPAZTDmU35L6IUssYMgQ xen/include/asm-x86/debugreg.h 1.9 3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h 1.10 3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h 1.11 @@ -768,7 +769,6 @@ 3f840f12CkbYSlwMrY2S11Mpyxg7Nw xen/inclu 1.12 3ddb79c259jh8hE7vre_8NuE7nwNSA xen/include/xen/config.h 1.13 3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h 1.14 3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h 1.15 -4194efbdvxUXjCLobbopgLOojisO4Q xen/include/xen/debugger_hooks.h 1.16 3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h 1.17 3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h 1.18 3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
2.1 --- a/xen/arch/x86/pdb-stub.c Sat Nov 13 16:10:28 2004 +0000 2.2 +++ b/xen/arch/x86/pdb-stub.c Sat Nov 13 17:17:59 2004 +0000 2.3 @@ -1214,6 +1214,27 @@ void pdb_key_pressed(unsigned char key) 2.4 pdb_handle_exception(KEYPRESS_EXCEPTION, regs); 2.5 } 2.6 2.7 +void pdb_handle_debug_trap(struct xen_regs *regs, long error_code) 2.8 +{ 2.9 + unsigned int condition; 2.10 + struct domain *tsk = current; 2.11 + struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); 2.12 + 2.13 + __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); 2.14 + if ( (condition & (1 << 14)) != (1 << 14) ) 2.15 + printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition); 2.16 + __asm__("movl %0,%%db6" : : "r" (0)); 2.17 + 2.18 + if ( pdb_handle_exception(1, regs) != 0 ) 2.19 + { 2.20 + tsk->thread.debugreg[6] = condition; 2.21 + 2.22 + gtb->flags = GTBF_TRAP_NOCODE; 2.23 + gtb->cs = tsk->thread.traps[1].cs; 2.24 + gtb->eip = tsk->thread.traps[1].address; 2.25 + } 2.26 +} 2.27 + 2.28 void initialize_pdb() 2.29 { 2.30 extern char opt_pdb[];
3.1 --- a/xen/arch/x86/traps.c Sat Nov 13 16:10:28 2004 +0000 3.2 +++ b/xen/arch/x86/traps.c Sat Nov 13 17:17:59 2004 +0000 3.3 @@ -50,8 +50,7 @@ 3.4 #include <asm/flushtlb.h> 3.5 #include <asm/uaccess.h> 3.6 #include <asm/i387.h> 3.7 -#include <asm/pdb.h> 3.8 -#include <xen/debugger_hooks.h> 3.9 +#include <asm/debugger.h> 3.10 3.11 extern char opt_nmi[]; 3.12 3.13 @@ -223,7 +222,9 @@ static inline void do_trap(int trapnr, c 3.14 trap_info_t *ti; 3.15 unsigned long fixup; 3.16 3.17 - if (!(regs->cs & 3)) 3.18 + DEBUGGER_trap_entry(trapnr, regs, error_code); 3.19 + 3.20 + if ( !(regs->cs & 3) ) 3.21 goto xen_fault; 3.22 3.23 ti = current->thread.traps + trapnr; 3.24 @@ -244,8 +245,7 @@ static inline void do_trap(int trapnr, c 3.25 return; 3.26 } 3.27 3.28 - if (debugger_trap(trapnr, regs)) 3.29 - return; 3.30 + DEBUGGER_trap_fatal(trapnr, regs, error_code); 3.31 3.32 show_registers(regs); 3.33 panic("CPU%d FATAL TRAP: vector = %d (%s)\n" 3.34 @@ -284,18 +284,15 @@ asmlinkage void do_int3(struct xen_regs 3.35 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); 3.36 trap_info_t *ti; 3.37 3.38 - if (debugger_trap(3, regs)) 3.39 - return; 3.40 + DEBUGGER_trap_entry(TRAP_int3, regs, error_code); 3.41 3.42 - if ( (regs->cs & 3) != 3 ) 3.43 + if ( unlikely((regs->cs & 3) == 0) ) 3.44 { 3.45 - if ( unlikely((regs->cs & 3) == 0) ) 3.46 - { 3.47 - show_registers(regs); 3.48 - panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n" 3.49 - "[error_code=%08x]\n", 3.50 - smp_processor_id(), error_code); 3.51 - } 3.52 + DEBUGGER_trap_fatal(TRAP_int3, regs, error_code); 3.53 + show_registers(regs); 3.54 + panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n" 3.55 + "[error_code=%08x]\n", 3.56 + smp_processor_id(), error_code); 3.57 } 3.58 3.59 ti = current->thread.traps + 3; 3.60 @@ -331,7 +328,7 @@ asmlinkage void do_double_fault(void) 3.61 printk("System needs manual reset.\n"); 3.62 printk("************************************\n"); 3.63 3.64 - debugger_trap(8, NULL); 3.65 + DEBUGGER_trap_fatal(TRAP_double_fault, NULL, 0); 3.66 3.67 /* Lock up the console to prevent spurious output from other CPUs. */ 3.68 console_force_lock(); 3.69 @@ -351,6 +348,8 @@ asmlinkage void do_page_fault(struct xen 3.70 3.71 __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : ); 3.72 3.73 + DEBUGGER_trap_entry(TRAP_page_fault, regs, error_code); 3.74 + 3.75 perfc_incrc(page_faults); 3.76 3.77 if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) ) 3.78 @@ -410,8 +409,7 @@ asmlinkage void do_page_fault(struct xen 3.79 return; 3.80 } 3.81 3.82 - if (debugger_trap(14, regs)) 3.83 - return; 3.84 + DEBUGGER_trap_fatal(TRAP_page_fault, regs, error_code); 3.85 3.86 if ( addr >= PAGE_OFFSET ) 3.87 { 3.88 @@ -444,6 +442,8 @@ asmlinkage void do_general_protection(st 3.89 trap_info_t *ti; 3.90 unsigned long fixup; 3.91 3.92 + DEBUGGER_trap_entry(TRAP_gp_fault, regs, error_code); 3.93 + 3.94 /* Badness if error in ring 0, or result of an interrupt. */ 3.95 if ( !(regs->cs & 3) || (error_code & 1) ) 3.96 goto gp_in_kernel; 3.97 @@ -474,15 +474,6 @@ asmlinkage void do_general_protection(st 3.98 ti = current->thread.traps + (error_code>>3); 3.99 if ( TI_GET_DPL(ti) >= (regs->cs & 3) ) 3.100 { 3.101 -#ifdef XEN_DEBUGGER 3.102 - if ( pdb_initialized && (pdb_ctx.system_call != 0) ) 3.103 - { 3.104 - unsigned long cr3 = read_cr3(); 3.105 - if ( cr3 == pdb_ctx.ptbr ) 3.106 - pdb_linux_syscall_enter_bkpt(regs, error_code, ti); 3.107 - } 3.108 -#endif 3.109 - 3.110 gtb->flags = GTBF_TRAP_NOCODE; 3.111 regs->eip += 2; 3.112 goto finish_propagation; 3.113 @@ -495,7 +486,7 @@ asmlinkage void do_general_protection(st 3.114 gpf_emulate_4gb(regs) ) 3.115 return; 3.116 #endif 3.117 - 3.118 + 3.119 /* Pass on GPF as is. */ 3.120 ti = current->thread.traps + 13; 3.121 gtb->flags = GTBF_TRAP; 3.122 @@ -516,8 +507,7 @@ asmlinkage void do_general_protection(st 3.123 return; 3.124 } 3.125 3.126 - if (debugger_trap(13, regs)) 3.127 - return; 3.128 + DEBUGGER_trap_fatal(TRAP_gp_fault, regs, error_code); 3.129 3.130 die("general protection fault", regs, error_code); 3.131 } 3.132 @@ -564,8 +554,7 @@ asmlinkage void io_check_error(struct xe 3.133 3.134 static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs) 3.135 { 3.136 - if (debugger_trap(2, regs)) 3.137 - return; 3.138 + DEBUGGER_trap_entry(TRAP_nmi, regs, 0); 3.139 3.140 printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); 3.141 printk("Dazed and confused, but trying to continue\n"); 3.142 @@ -620,39 +609,13 @@ asmlinkage void math_state_restore(struc 3.143 } 3.144 } 3.145 3.146 -#ifdef XEN_DEBUGGER 3.147 -asmlinkage void do_pdb_debug(struct xen_regs *regs, long error_code) 3.148 -{ 3.149 - unsigned int condition; 3.150 - struct domain *tsk = current; 3.151 - struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); 3.152 - 3.153 - __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); 3.154 - if ( (condition & (1 << 14)) != (1 << 14) ) 3.155 - printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition); 3.156 - __asm__("movl %0,%%db6" : : "r" (0)); 3.157 - 3.158 - if ( pdb_handle_exception(1, regs) != 0 ) 3.159 - { 3.160 - tsk->thread.debugreg[6] = condition; 3.161 - 3.162 - gtb->flags = GTBF_TRAP_NOCODE; 3.163 - gtb->cs = tsk->thread.traps[1].cs; 3.164 - gtb->eip = tsk->thread.traps[1].address; 3.165 - } 3.166 -} 3.167 -#endif 3.168 - 3.169 asmlinkage void do_debug(struct xen_regs *regs, long error_code) 3.170 { 3.171 unsigned int condition; 3.172 struct domain *tsk = current; 3.173 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); 3.174 3.175 -#ifdef XEN_DEBUGGER 3.176 - if ( pdb_initialized ) 3.177 - return do_pdb_debug(regs, error_code); 3.178 -#endif 3.179 + DEBUGGER_trap_entry(TRAP_debug, regs, error_code); 3.180 3.181 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); 3.182
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/xen/include/asm-x86/debugger.h Sat Nov 13 17:17:59 2004 +0000 4.3 @@ -0,0 +1,137 @@ 4.4 +/****************************************************************************** 4.5 + * asm/debugger.h 4.6 + * 4.7 + * Generic hooks into arch-dependent Xen. 4.8 + * 4.9 + * Each debugger should define two functions here: 4.10 + * 4.11 + * 1. debugger_trap_entry(): 4.12 + * Called at start of any synchronous fault or trap, before any other work 4.13 + * is done. The idea is that if your debugger deliberately caused the trap 4.14 + * (e.g. to implement breakpoints or data watchpoints) then you can take 4.15 + * appropriate action and return a non-zero value to cause early exit from 4.16 + * the trap function. 4.17 + * 4.18 + * 2. debugger_trap_fatal(): 4.19 + * Called when Xen is about to give up and crash. Typically you will use this 4.20 + * hook to drop into a debug session. It can also be used to hook off 4.21 + * deliberately caused traps (which you then handle and return non-zero) 4.22 + * but really these should be hooked off 'debugger_trap_entry'. 4.23 + */ 4.24 + 4.25 +#ifndef __X86_DEBUGGER_H__ 4.26 +#define __X86_DEBUGGER_H__ 4.27 + 4.28 +/* Avoid magic vector numbers by using these semi-sensical names. */ 4.29 +#define TRAP_divide_error 0 4.30 +#define TRAP_debug 1 4.31 +#define TRAP_nmi 2 4.32 +#define TRAP_int3 3 4.33 +#define TRAP_overflow 4 4.34 +#define TRAP_bounds 5 4.35 +#define TRAP_invalid_op 6 4.36 +#define TRAP_no_device 7 4.37 +#define TRAP_double_fault 8 4.38 +#define TRAP_copro_seg 9 4.39 +#define TRAP_invalid_tss 10 4.40 +#define TRAP_no_segment 11 4.41 +#define TRAP_stack_error 12 4.42 +#define TRAP_gp_fault 13 4.43 +#define TRAP_page_fault 14 4.44 +#define TRAP_spurious_int 15 4.45 +#define TRAP_copro_error 16 4.46 +#define TRAP_alignment_check 17 4.47 +#define TRAP_machine_check 18 4.48 +#define TRAP_simd_error 19 4.49 + 4.50 +/* The main trap handlers use these helper macros which include early bail. */ 4.51 +#define DEBUGGER_trap_entry(_v, _r, _e) \ 4.52 + if ( debugger_trap_entry(_v, _r, _e) ) return; 4.53 +#define DEBUGGER_trap_fatal(_v, _r, _e) \ 4.54 + if ( debugger_trap_fatal(_v, _r, _e) ) return; 4.55 + 4.56 +#ifdef XEN_DEBUGGER 4.57 + 4.58 +#include <asm/pdb.h> 4.59 + 4.60 +static inline int debugger_trap_entry( 4.61 + unsigned int vector, struct xen_regs *regs, unsigned int error_code) 4.62 +{ 4.63 + int ret = 0; 4.64 + 4.65 + switch ( vector ) 4.66 + { 4.67 + case TRAP_debug: 4.68 + if ( pdb_initialized ) 4.69 + { 4.70 + pdb_handle_debug_trap(regs, (long)error_code); 4.71 + ret = 1; /* early exit */ 4.72 + } 4.73 + break; 4.74 + 4.75 + case TRAP_int3: 4.76 + if ( pdb_initialized && (pdb_handle_exception(vector, regs) == 0) ) 4.77 + ret = 1; /* early exit */ 4.78 + break; 4.79 + 4.80 + case TRAP_gp_fault: 4.81 + if ( ((regs->cs & 3) != 0) && ((error_code & 3) == 2) && 4.82 + pdb_initialized && (pdb_ctx.system_call != 0) ) 4.83 + { 4.84 + unsigned long cr3 = read_cr3(); 4.85 + if ( cr3 == pdb_ctx.ptbr ) 4.86 + pdb_linux_syscall_enter_bkpt( 4.87 + regs, error_code, current->thread.traps + (error_code>>3)); 4.88 + } 4.89 + break; 4.90 + } 4.91 + 4.92 + return ret; 4.93 +} 4.94 + 4.95 +static inline int debugger_trap_fatal( 4.96 + unsigned int vector, struct xen_regs *regs, unsigned int error_code) 4.97 +{ 4.98 + int ret = 0; 4.99 + 4.100 + switch ( vector ) 4.101 + { 4.102 + case TRAP_page_fault: 4.103 + if ( pdb_page_fault_possible ) 4.104 + { 4.105 + pdb_page_fault = 1; 4.106 + /* make eax & edx valid to complete the instruction */ 4.107 + regs->eax = (long)&pdb_page_fault_scratch; 4.108 + regs->edx = (long)&pdb_page_fault_scratch; 4.109 + ret = 1; /* exit - do not crash! */ 4.110 + } 4.111 + break; 4.112 + } 4.113 + 4.114 + return ret; 4.115 +} 4.116 + 4.117 +#elif 0 4.118 + 4.119 +extern int kdb_trap(int, int, struct xen_regs *); 4.120 + 4.121 +static inline int debugger_trap_entry( 4.122 + unsigned int vector, struct xen_regs *regs, unsigned int error_code) 4.123 +{ 4.124 + return 0; 4.125 +} 4.126 + 4.127 +static inline int debugger_trap_fatal( 4.128 + unsigned int vector, struct xen_regs *regs, unsigned int error_code) 4.129 +{ 4.130 + return kdb_trap(vector, 0, regs); 4.131 +} 4.132 + 4.133 +#else 4.134 + 4.135 +#define debugger_trap_entry(_v, _r, _e) (0) 4.136 +#define debugger_trap_fatal(_v, _r, _e) (0) 4.137 + 4.138 +#endif 4.139 + 4.140 +#endif /* __X86_DEBUGGER_H__ */
5.1 --- a/xen/include/asm-x86/pdb.h Sat Nov 13 16:10:28 2004 +0000 5.2 +++ b/xen/include/asm-x86/pdb.h Sat Nov 13 17:17:59 2004 +0000 5.3 @@ -84,4 +84,6 @@ void pdb_linux_syscall_enter_bkpt (struc 5.4 void pdb_linux_syscall_exit_bkpt (struct xen_regs *regs, 5.5 struct pdb_context *pdb_ctx); 5.6 5.7 +void pdb_handle_debug_trap(struct xen_regs *regs, long error_code); 5.8 + 5.9 #endif /* __PDB_H__ */
6.1 --- a/xen/include/xen/debugger_hooks.h Sat Nov 13 16:10:28 2004 +0000 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,37 +0,0 @@ 6.4 - 6.5 -#ifndef __DEBUGGER_HOOKS_H__ 6.6 -#define __DEBUGGER_HOOKS_H__ 6.7 - 6.8 -static inline int debugger_trap(int type, struct xen_regs *regs) 6.9 -{ 6.10 - int ret = 0; 6.11 - 6.12 -#ifdef XEN_DEBUGGER 6.13 - switch (type) { 6.14 - case 3: 6.15 - if ( pdb_initialized && pdb_handle_exception(type, regs) == 0 ) 6.16 - return 1; 6.17 - break; 6.18 - case 14: 6.19 - if ( pdb_page_fault_possible ) 6.20 - { 6.21 - pdb_page_fault = 1; 6.22 - /* make eax & edx valid to complete the instruction */ 6.23 - regs->eax = (long)&pdb_page_fault_scratch; 6.24 - regs->edx = (long)&pdb_page_fault_scratch; 6.25 - return 1; 6.26 - } 6.27 - break; 6.28 - } 6.29 -#endif 6.30 - 6.31 -#if 0 6.32 - extern int kdb_trap(int, int, struct xen_regs *); 6.33 - if ((ret = kdb_trap(type, 0, regs))) 6.34 - return ret; 6.35 -#endif 6.36 - 6.37 - return ret; 6.38 -} 6.39 - 6.40 -#endif /* __DEBUGGER_HOOKS_H__ */