{
unsigned int trapnr = regs->entry_vector;
- DEBUGGER_trap_fatal(trapnr, regs);
+ if ( debugger_trap_fatal(trapnr, regs) )
+ return;
+
show_execution_state(regs);
panic("FATAL RESERVED TRAP %#x: %s", trapnr, trapstr(trapnr));
}
if ( regs->error_code & X86_XEC_EXT )
goto hardware_trap;
- DEBUGGER_trap_entry(trapnr, regs);
+ if ( debugger_trap_entry(trapnr, regs) )
+ return;
if ( guest_mode(regs) )
{
}
hardware_trap:
- DEBUGGER_trap_fatal(trapnr, regs);
+ if ( debugger_trap_fatal(trapnr, regs) )
+ return;
show_execution_state(regs);
panic("FATAL TRAP: vector = %d (%s)\n"
int id = -1, lineno;
const struct virtual_region *region;
- DEBUGGER_trap_entry(TRAP_invalid_op, regs);
+ if ( debugger_trap_entry(TRAP_invalid_op, regs) )
+ return;
if ( likely(guest_mode(regs)) )
{
case BUGFRAME_bug:
printk("Xen BUG at %s%s:%d\n", prefix, filename, lineno);
- DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+
+ if ( debugger_trap_fatal(TRAP_invalid_op, regs) )
+ return;
+
show_execution_state(regs);
panic("Xen BUG at %s%s:%d", prefix, filename, lineno);
printk("Assertion '%s' failed at %s%s:%d\n",
predicate, prefix, filename, lineno);
- DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+
+ if ( debugger_trap_fatal(TRAP_invalid_op, regs) )
+ return;
+
show_execution_state(regs);
panic("Assertion '%s' failed at %s%s:%d",
predicate, prefix, filename, lineno);
regs->eip = fixup;
return;
}
- DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+
+ if ( debugger_trap_fatal(TRAP_invalid_op, regs) )
+ return;
+
show_execution_state(regs);
panic("FATAL TRAP: vector = %d (invalid opcode)", TRAP_invalid_op);
}
void do_int3(struct cpu_user_regs *regs)
{
- DEBUGGER_trap_entry(TRAP_int3, regs);
+ if ( debugger_trap_entry(TRAP_int3, regs) )
+ return;
if ( !guest_mode(regs) )
{
/* fixup_page_fault() might change regs->error_code, so cache it here. */
error_code = regs->error_code;
- DEBUGGER_trap_entry(TRAP_page_fault, regs);
+ if ( debugger_trap_entry(TRAP_page_fault, regs) )
+ return;
perfc_incr(page_faults);
return;
}
- DEBUGGER_trap_fatal(TRAP_page_fault, regs);
+ if ( debugger_trap_fatal(TRAP_page_fault, regs) )
+ return;
show_execution_state(regs);
show_page_walk(addr);
struct vcpu *v = current;
unsigned long fixup;
- DEBUGGER_trap_entry(TRAP_gp_fault, regs);
+ if ( debugger_trap_entry(TRAP_gp_fault, regs) )
+ return;
if ( regs->error_code & X86_XEC_EXT )
goto hardware_gp;
}
hardware_gp:
- DEBUGGER_trap_fatal(TRAP_gp_fault, regs);
+ if ( debugger_trap_fatal(TRAP_gp_fault, regs) )
+ return;
show_execution_state(regs);
panic("GENERAL PROTECTION FAULT\n[error_code=%04x]", regs->error_code);
{
struct vcpu *v = current;
- DEBUGGER_trap_entry(TRAP_debug, regs);
+ if ( debugger_trap_entry(TRAP_debug, regs) )
+ return;
if ( !guest_mode(regs) )
{
#include <asm/regs.h>
#include <asm/processor.h>
-/* The main trap handlers use these helper macros which include early bail. */
-#define DEBUGGER_trap_entry(_v, _r) \
- if ( debugger_trap_entry(_v, _r) ) return;
-#define DEBUGGER_trap_fatal(_v, _r) \
- if ( debugger_trap_fatal(_v, _r) ) return;
-
#ifdef CONFIG_CRASH_DEBUG
#include <xen/gdbstub.h>
-static inline int debugger_trap_fatal(
+static inline bool debugger_trap_fatal(
unsigned int vector, struct cpu_user_regs *regs)
{
int rc = __trap_to_gdb(regs, vector);
#else
-static inline int debugger_trap_fatal(
+static inline bool debugger_trap_fatal(
unsigned int vector, struct cpu_user_regs *regs)
{
- return 0;
+ return false;
}
#define debugger_trap_immediate() ((void)0)
#endif
-static inline int debugger_trap_entry(
+static inline bool debugger_trap_entry(
unsigned int vector, struct cpu_user_regs *regs)
{
+ /*
+ * This function is called before any checks are made. Amongst other
+ * things, be aware that during early boot, current is not a safe pointer
+ * to follow.
+ */
struct vcpu *v = current;
- if ( guest_kernel_mode(v, regs) && v->domain->debugger_attached &&
- ((vector == TRAP_int3) || (vector == TRAP_debug)) )
+ if ( vector != TRAP_int3 && vector != TRAP_debug )
+ return false;
+
+ if ( guest_mode(regs) && guest_kernel_mode(v, regs) &&
+ v->domain->debugger_attached )
{
if ( vector != TRAP_debug ) /* domain pause is good enough */
current->arch.gdbsx_vcpu_event = vector;
domain_pause_for_debugger();
- return 1;
+ return true;
}
- return 0;
+ return false;
}
unsigned int dbg_rw_mem(void * __user addr, void * __user buf,