From patchwork Sat Dec 10 09:59:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Gustafsson X-Patchwork-Id: 130517 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EB1CB1007D9 for ; Sat, 10 Dec 2011 20:59:30 +1100 (EST) Received: from localhost ([::1]:57388 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RZJiF-0000by-7b for incoming@patchwork.ozlabs.org; Sat, 10 Dec 2011 04:59:23 -0500 Received: from eggs.gnu.org ([140.186.70.92]:35814) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RZJi9-0000bi-IX for qemu-devel@nongnu.org; Sat, 10 Dec 2011 04:59:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RZJi8-0005EY-3c for qemu-devel@nongnu.org; Sat, 10 Dec 2011 04:59:17 -0500 Received: from gunk.araneus.fi ([166.84.6.82]:60242) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RZJi8-0005EQ-0y for qemu-devel@nongnu.org; Sat, 10 Dec 2011 04:59:16 -0500 Received: from guava.gson.org (guava.gson.org [10.0.11.2]) by gunk.araneus.fi (Postfix) with ESMTP id A83D01D07E7; Sat, 10 Dec 2011 09:59:11 +0000 (UTC) Received: by guava.gson.org (Postfix, from userid 101) id AE7BE75E5D; Sat, 10 Dec 2011 11:59:11 +0200 (EET) To: qemu-devel@nongnu.org X-Mailer: VM 8.0.14 under 21.4.1 (i386--netbsdelf) From: Andreas Gustafsson Message-Id: <20111210095911.AE7BE75E5D@guava.gson.org> Date: Sat, 10 Dec 2011 11:59:11 +0200 (EET) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 166.84.6.82 Cc: Alexander Graf Subject: [Qemu-devel] [PATCH] target-i386: fix cmpxchg instruction emulation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When the i386 cmpxchg instruction is executed with a memory operand and the comparison result is "unequal", do the memory write before changing the accumulator instead of the other way around, because otherwise the new accumulator value will incorrectly be used in the comparison when the instruction is restarted after a page fault. This bug was originally reported on 2010-04-25 as https://bugs.launchpad.net/qemu/+bug/569760 Signed-off-by: Andreas Gustafsson --- translate.c.orig 2011-12-09 18:21:28.000000000 +0200 +++ translate.c 2011-12-09 18:21:24.000000000 +0200 @@ -4870,20 +4870,23 @@ static target_ulong disas_insn(DisasCont tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0); gen_extu(ot, t2); tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1); + label2 = gen_new_label(); if (mod == 3) { - label2 = gen_new_label(); gen_op_mov_reg_v(ot, R_EAX, t0); tcg_gen_br(label2); gen_set_label(label1); gen_op_mov_reg_v(ot, rm, t1); - gen_set_label(label2); } else { - tcg_gen_mov_tl(t1, t0); + /* perform no-op store cycle like physical cpu; must be + before changing accumulator to ensure idempotency if + the store faults and the instruction is restarted */ + gen_op_st_v(ot + s->mem_index, t0, a0); gen_op_mov_reg_v(ot, R_EAX, t0); + tcg_gen_br(label2); gen_set_label(label1); - /* always store */ gen_op_st_v(ot + s->mem_index, t1, a0); } + gen_set_label(label2); tcg_gen_mov_tl(cpu_cc_src, t0); tcg_gen_mov_tl(cpu_cc_dst, t2); s->cc_op = CC_OP_SUBB + ot;