]> xenbits.xensource.com Git - xen.git/commitdiff
bitkeeper revision 1.1159.170.19 (419641c7PFSwb0OCvYznpBOaQJY6Fw)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Sat, 13 Nov 2004 17:17:59 +0000 (17:17 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Sat, 13 Nov 2004 17:17:59 +0000 (17:17 +0000)
Cleaned up debugger interface to traps.c.

.rootkeys
xen/arch/x86/pdb-stub.c
xen/arch/x86/traps.c
xen/include/asm-x86/debugger.h [new file with mode: 0644]
xen/include/asm-x86/pdb.h
xen/include/xen/debugger_hooks.h [deleted file]

index 45ec7aa3a7437fafbfe038ac17b2bbeb09d23027..3556df5ba046281098ba8d4bc7b5158573264b2b 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 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
 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
index a6133b78ae371685e4e5c2f4526611bb4019828f..946755d9093de3f5167fb7d3c83d263d19874d83 100644 (file)
@@ -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[];
index 2026432ec006dfd6bd3ac79008ee9aa4ab2bab5e..815740773bfe0a57fe90a4614885df2b2379ab58 100644 (file)
@@ -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 (file)
index 0000000..b19e099
--- /dev/null
@@ -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__ */
index 39386f82ea89c2d7e4709122d0d0c0b089f404e6..79b0c4183b8d5921eeff20e988784d06da11329f 100644 (file)
@@ -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 (file)
index 4663b2b..0000000
+++ /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__ */