Blame 0010-target-i386-fix-cmpxchg-instruction-emulation.patch

Justin M. Forbes 45e84a
From abf80f880410ebbdd01a289c41c87153802fe900 Mon Sep 17 00:00:00 2001
Justin M. Forbes 45e84a
From: Andreas Gustafsson <gson@gson.org>
Justin M. Forbes 45e84a
Date: Mon, 12 Dec 2011 00:46:32 +0400
Justin M. Forbes 45e84a
Subject: [PATCH 10/25] target-i386: fix cmpxchg instruction emulation
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
When the i386 cmpxchg instruction is executed with a memory operand
Justin M. Forbes 45e84a
and the comparison result is "unequal", do the memory write before
Justin M. Forbes 45e84a
changing the accumulator instead of the other way around, because
Justin M. Forbes 45e84a
otherwise the new accumulator value will incorrectly be used in the
Justin M. Forbes 45e84a
comparison when the instruction is restarted after a page fault.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
This bug was originally reported on 2010-04-25 as
Justin M. Forbes 45e84a
https://bugs.launchpad.net/qemu/+bug/569760
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Signed-off-by: Andreas Gustafsson <gson@gson.org>
Justin M. Forbes 45e84a
---
Justin M. Forbes 45e84a
 target-i386/translate.c |   11 +++++++----
Justin M. Forbes 45e84a
 1 files changed, 7 insertions(+), 4 deletions(-)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
diff --git a/target-i386/translate.c b/target-i386/translate.c
Justin M. Forbes 45e84a
index 1ef8d16..8321bf3 100644
Justin M. Forbes 45e84a
--- a/target-i386/translate.c
Justin M. Forbes 45e84a
+++ b/target-i386/translate.c
Justin M. Forbes 45e84a
@@ -4870,20 +4870,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
Justin M. Forbes 45e84a
             tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
Justin M. Forbes 45e84a
             gen_extu(ot, t2);
Justin M. Forbes 45e84a
             tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
Justin M. Forbes 45e84a
+            label2 = gen_new_label();
Justin M. Forbes 45e84a
             if (mod == 3) {
Justin M. Forbes 45e84a
-                label2 = gen_new_label();
Justin M. Forbes 45e84a
                 gen_op_mov_reg_v(ot, R_EAX, t0);
Justin M. Forbes 45e84a
                 tcg_gen_br(label2);
Justin M. Forbes 45e84a
                 gen_set_label(label1);
Justin M. Forbes 45e84a
                 gen_op_mov_reg_v(ot, rm, t1);
Justin M. Forbes 45e84a
-                gen_set_label(label2);
Justin M. Forbes 45e84a
             } else {
Justin M. Forbes 45e84a
-                tcg_gen_mov_tl(t1, t0);
Justin M. Forbes 45e84a
+                /* perform no-op store cycle like physical cpu; must be
Justin M. Forbes 45e84a
+                   before changing accumulator to ensure idempotency if
Justin M. Forbes 45e84a
+                   the store faults and the instruction is restarted */
Justin M. Forbes 45e84a
+                gen_op_st_v(ot + s->mem_index, t0, a0);
Justin M. Forbes 45e84a
                 gen_op_mov_reg_v(ot, R_EAX, t0);
Justin M. Forbes 45e84a
+                tcg_gen_br(label2);
Justin M. Forbes 45e84a
                 gen_set_label(label1);
Justin M. Forbes 45e84a
-                /* always store */
Justin M. Forbes 45e84a
                 gen_op_st_v(ot + s->mem_index, t1, a0);
Justin M. Forbes 45e84a
             }
Justin M. Forbes 45e84a
+            gen_set_label(label2);
Justin M. Forbes 45e84a
             tcg_gen_mov_tl(cpu_cc_src, t0);
Justin M. Forbes 45e84a
             tcg_gen_mov_tl(cpu_cc_dst, t2);
Justin M. Forbes 45e84a
             s->cc_op = CC_OP_SUBB + ot;
Justin M. Forbes 45e84a
-- 
Justin M. Forbes 45e84a
1.7.7.5
Justin M. Forbes 45e84a