diff -ur qemu-1.0/cpu-defs.h qemu-1.0-CSL373/cpu-defs.h --- qemu-1.0/cpu-defs.h 2011-12-02 01:37:34.000000000 +0530 +++ qemu-1.0-CSL373/cpu-defs.h 2012-01-03 18:42:28.000000000 +0530 @@ -66,6 +66,7 @@ #define EXCP_HLT 0x10001 /* hlt instruction reached */ #define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */ #define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */ +#define EXCP_TRIPLE 0x10004 /* cpu encountered triple fault */ #define TB_JMP_CACHE_BITS 12 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) diff -ur qemu-1.0/cpus.c qemu-1.0-CSL373/cpus.c --- qemu-1.0/cpus.c 2011-12-02 01:37:34.000000000 +0530 +++ qemu-1.0-CSL373/cpus.c 2012-01-03 18:48:28.000000000 +0530 @@ -1037,6 +1037,16 @@ if (cpu_can_run(env)) { r = tcg_cpu_exec(env); + if (r == EXCP_TRIPLE) { + cpu_dump_state(env, stderr, fprintf, 0); + fprintf(stderr, "Triple fault. Halting for inspection " + "via QEMU monitor.\n"); + if (gdbserver_running()) { + r = EXCP_DEBUG; + } else { + vm_stop(0); + } + } if (r == EXCP_DEBUG) { cpu_handle_guest_debug(env); break; diff -ur qemu-1.0/gdbstub.c qemu-1.0-CSL373/gdbstub.c --- qemu-1.0/gdbstub.c 2011-12-02 01:37:34.000000000 +0530 +++ qemu-1.0-CSL373/gdbstub.c 2012-01-03 18:42:28.000000000 +0530 @@ -2919,3 +2919,8 @@ return 0; } #endif + +int gdbserver_running(void) +{ + return gdbserver_state != NULL; +} diff -ur qemu-1.0/gdbstub.h qemu-1.0-CSL373/gdbstub.h --- qemu-1.0/gdbstub.h 2011-12-02 01:37:34.000000000 +0530 +++ qemu-1.0-CSL373/gdbstub.h 2012-01-03 18:42:28.000000000 +0530 @@ -24,6 +24,7 @@ void gdb_signalled(CPUState *, int); void gdbserver_fork(CPUState *); #endif +int gdbserver_running(void); /* Get or set a register. Returns the size of the register. */ typedef int (*gdb_reg_cb)(CPUState *env, uint8_t *buf, int reg); void gdb_register_coprocessor(CPUState *env, diff -ur qemu-1.0/target-i386/op_helper.c qemu-1.0-CSL373/target-i386/op_helper.c --- qemu-1.0/target-i386/op_helper.c 2011-12-02 01:37:34.000000000 +0530 +++ qemu-1.0-CSL373/target-i386/op_helper.c 2012-01-03 18:42:28.000000000 +0530 @@ -1443,8 +1443,18 @@ qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); +#if 0 qemu_system_reset_request(); return EXCP_HLT; +#else + // QEMU traditionally resets the machine on triple fault + // because programs written for 286 protected mode would exit + // protected mode by intentionally triple faulting the machine + // (after setting the boot vector to point to their code). + // This sucks for debugging programs that were written after + // 1985, so we instead halt the machine for inspection. + return EXCP_TRIPLE; +#endif } #endif