In qemu-0.9.0, an exception in cmpxchg8b (e.g. page fault due to a missing TLB entry) causes the wrong eip value to be pushed onto the exception stack -- it seems to be the eip of the last exception or the start of the translation block, whichever happened last. This makes it impossible to resume execution after such an exception.
The simple patch below fixes it, by explicitly saving the current eip before invoking the cmpxchg8b helper; the same approach appears to be taken in many other instructions before generating code that could raise an exception. Apologies for the non-tab-clean patch, but it's simple enough to apply by hand. I can't quite understand what's generating the equivalent piece of code (to save pc_start into eip) for the cmpxchgl instruction (defined right above cmpxchg8b in translate.c). I'd be thankful if someone could explain to me where it's getting saved. Nickolai. --- qemu-0.9.0/target-i386/translate.c 2007-02-05 15:01:54.000000000 -0800 +++ /home/nickolai/build/qemu-0.9.0/target-i386/translate.c 2007-04-24 19:33:47.000000000 -0700 @@ -3800,6 +3800,7 @@ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_lea_modrm(s, modrm, ®_addr, &offset_addr); + gen_jmp_im(pc_start - s->cs_base); gen_op_cmpxchg8b(); s->cc_op = CC_OP_EFLAGS; break;