From patchwork Thu Mar 3 05:30:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 8488121 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0206CC0553 for ; Thu, 3 Mar 2016 05:34:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 364BB20251 for ; Thu, 3 Mar 2016 05:34:29 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5CB2C20145 for ; Thu, 3 Mar 2016 05:34:28 +0000 (UTC) Received: from localhost ([::1]:60657 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1abLu7-0003MW-O7 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 03 Mar 2016 00:34:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52271) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1abLrM-0007VK-04 for qemu-devel@nongnu.org; Thu, 03 Mar 2016 00:31:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1abLrK-00034p-Ul for qemu-devel@nongnu.org; Thu, 03 Mar 2016 00:31:35 -0500 Received: from mail-qg0-x242.google.com ([2607:f8b0:400d:c04::242]:34297) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1abLrK-00034U-Qd for qemu-devel@nongnu.org; Thu, 03 Mar 2016 00:31:34 -0500 Received: by mail-qg0-x242.google.com with SMTP id t4so757764qge.1 for ; Wed, 02 Mar 2016 21:31:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Hj2NParyY/pNRejxu1HQrq3df1HqfLGW7HRphzpZQh4=; b=ZyyGHZGTPlpfsNOMVESvrovp25QMC8zkB1jgtT/b+/z5IUPSWNio4j+ah9WMaDFCxH VAzaKAEsOlBGBL334hf+SokTSzrw4Jfl8CClY6h8sBJx4dqMm6rArU7tqlErBBrfTaSD EnnYNSEhrw0u7qN2y6etbm9i0e314H7NvgZWwAFqA+HtMYMTwEECpWbhHRGQvrUERZ8W yCd7fl+CKFlhQ1hYO0jssx5AG9b80q6SVLby05Scty9QFbKKFlLT3kJEEM1tWx/ryBok JQTMGT6sqL6KxNMu+hwEMUBh/aw9g826hUvpq4UapiND+0xZ4viUC12xXdBXD/EOl+6q AvyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Hj2NParyY/pNRejxu1HQrq3df1HqfLGW7HRphzpZQh4=; b=BvRWdgvfKFsO8SX/KTa59iMyFmNoyYqDnLmjvB9aw7WCZmnd4JRBSQPzgpIlUHtBzH NeT6N3PaG7yArbQX5JTq5LRdCYhW7zdj1aFaO+sPM1xTkIF7BoZMxrk/Y2gbw+4iTTr8 CR8a5hemAcCtFGus3gqlyXQEWiRLp7LRBbAJUk6W7aQxNSPFkJP8aQtu8HmNIXFGeFnu RSfjx1MsMM4tjUnzGOaC2dFsqEByuOSRDOkKBj5d0Y9I4wlFJrT90viU1Jkq5ImhQQrf DWHX59cFgAk2anwGdhwUBhMH/6yq1JHfwHaee9S27hZPDdtCcbk6bqouGXoTiobQvN82 4OHg== X-Gm-Message-State: AD7BkJLJzGIUnKPyXNCIqo9+Diw7yGjPeJGzG7pOuefRPeUcT94wQxhfCmkwdgLTtlKe2w== X-Received: by 10.140.156.138 with SMTP id c132mr843247qhc.96.1456983094460; Wed, 02 Mar 2016 21:31:34 -0800 (PST) Received: from bigtime.com (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by smtp.gmail.com with ESMTPSA id v65sm2301368qhv.6.2016.03.02.21.31.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Mar 2016 21:31:34 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 2 Mar 2016 21:30:51 -0800 Message-Id: <1456983051-14707-8-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1456983051-14707-1-git-send-email-rth@twiddle.net> References: <1456983051-14707-1-git-send-email-rth@twiddle.net> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c04::242 Cc: pbonzini@redhat.com, hpoussin@reactos.org Subject: [Qemu-devel] [PATCH 7/7] target-i386: Fix inhibit irq mask handling 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The patch in 7f0b714 was too simplistic, in that we wound up setting the flag and then resetting it immediately in gen_eob. Fixes the reported boot problem with Windows XP. Reported-by: Hervé Poussineau Signed-off-by: Richard Henderson --- target-i386/translate.c | 76 ++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 7455a18..513b53a 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2441,12 +2441,19 @@ static void gen_bnd_jmp(DisasContext *s) } } -/* generate a generic end of block. Trace exception is also generated - if needed */ -static void gen_eob(DisasContext *s) +/* Generate an end of block. Trace exception is also generated if needed. + If IIM, set HF_INHIBIT_IRQ_MASK if it isn't already set. */ +static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) { gen_update_cc_op(s); - gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); + + /* If several instructions disable interrupts, only the first does it. */ + if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) { + gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); + } else { + gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); + } + if (s->tb->flags & HF_RF_MASK) { gen_helper_reset_rf(cpu_env); } @@ -2460,6 +2467,12 @@ static void gen_eob(DisasContext *s) s->is_jmp = DISAS_TB_JUMP; } +/* End of block, resetting the inhibit irq flag. */ +static void gen_eob(DisasContext *s) +{ + gen_eob_inhibit_irq(s, false); +} + /* generate a jump to eip. No segment change must happen before as a direct call to the next block may occur */ static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num) @@ -5193,16 +5206,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, ot = gen_pop_T0(s); gen_movl_seg_T0(s, reg); gen_pop_update(s, ot); - if (reg == R_SS) { - /* if reg == SS, inhibit interrupts/trace. */ - /* If several instructions disable interrupts, only the - _first_ does it */ - gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); - s->tf = 0; - } + /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */ if (s->is_jmp) { gen_jmp_im(s->pc - s->cs_base); - gen_eob(s); + if (reg == R_SS) { + s->tf = 0; + gen_eob_inhibit_irq(s, true); + } else { + gen_eob(s); + } } break; case 0x1a1: /* pop fs */ @@ -5260,16 +5272,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_movl_seg_T0(s, reg); - if (reg == R_SS) { - /* if reg == SS, inhibit interrupts/trace */ - /* If several instructions disable interrupts, only the - _first_ does it */ - gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); - s->tf = 0; - } + /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */ if (s->is_jmp) { gen_jmp_im(s->pc - s->cs_base); - gen_eob(s); + if (reg == R_SS) { + s->tf = 0; + gen_eob_inhibit_irq(s, true); + } else { + gen_eob(s); + } } break; case 0x8c: /* mov Gv, seg */ @@ -6795,26 +6806,13 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } break; case 0xfb: /* sti */ - if (!s->vm86) { - if (s->cpl <= s->iopl) { - gen_sti: - gen_helper_sti(cpu_env); - /* interruptions are enabled only the first insn after sti */ - /* If several instructions disable interrupts, only the - _first_ does it */ - gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); - /* give a chance to handle pending irqs */ - gen_jmp_im(s->pc - s->cs_base); - gen_eob(s); - } else { - gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); - } + if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) { + gen_helper_sti(cpu_env); + /* interruptions are enabled only the first insn after sti */ + gen_jmp_im(s->pc - s->cs_base); + gen_eob_inhibit_irq(s, true); } else { - if (s->iopl == 3) { - goto gen_sti; - } else { - gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); - } + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } break; case 0x62: /* bound */