ia64/xen-unstable

changeset 2971:4d94e2b30873

bitkeeper revision 1.1159.170.19 (419641c7PFSwb0OCvYznpBOaQJY6Fw)

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__ */