From patchwork Fri May 28 19:07:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Monjalon X-Patchwork-Id: 53956 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D2C61B7D1E for ; Sat, 29 May 2010 05:09:22 +1000 (EST) Received: from localhost ([127.0.0.1]:48919 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OI4vm-0002Hj-Cc for incoming@patchwork.ozlabs.org; Fri, 28 May 2010 15:09:18 -0400 Received: from [140.186.70.92] (port=38736 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OI4uC-0000c9-3Z for qemu-devel@nongnu.org; Fri, 28 May 2010 15:07:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OI4uA-00057F-M9 for qemu-devel@nongnu.org; Fri, 28 May 2010 15:07:39 -0400 Received: from smtp21.orange.fr ([80.12.242.48]:16091) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OI4uA-000579-FH for qemu-devel@nongnu.org; Fri, 28 May 2010 15:07:38 -0400 Received: from me-wanadoo.net (localhost [127.0.0.1]) by mwinf2114.orange.fr (SMTP Server) with ESMTP id 6C9661C00485; Fri, 28 May 2010 21:07:37 +0200 (CEST) Received: from me-wanadoo.net (localhost [127.0.0.1]) by mwinf2114.orange.fr (SMTP Server) with ESMTP id 5D7891C00493; Fri, 28 May 2010 21:07:37 +0200 (CEST) Received: from tmonjalo-laptop (LPuteaux-156-15-47-90.w82-127.abo.wanadoo.fr [82.127.74.90]) by mwinf2114.orange.fr (SMTP Server) with ESMTP id A7FE81C00485; Fri, 28 May 2010 21:07:34 +0200 (CEST) X-ME-UUID: 20100528190734688.A7FE81C00485@mwinf2114.orange.fr From: Thomas Monjalon To: qemu-devel@nongnu.org Date: Fri, 28 May 2010 21:07:32 +0200 Message-Id: <1275073652-20834-1-git-send-email-thomas_ml@monjalon.net> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Alexander Graf Subject: [Qemu-devel] [PATCH] target-ppc: fix RFI by clearing some bits of MSR X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Thomas Monjalon Since commit 2ada0ed, "Return From Interrupt" is broken for PPC processors because some interrupt specifics bits of SRR1 are copied to MSR. SRR1 is a save of MSR during interrupt. During RFI, MSR must be restored from SRR1. But some bits of SRR1 are interrupt-specific and are not used for MSR saving. This is the specification (ISA 2.06) at chapter 6.4.3 (Interrupt Processing): "2. Bits 33:36 and 42:47 of SRR1 or HSRR1 are loaded with information specific to the interrupt type. 3. Bits 0:32, 37:41, and 48:63 of SRR1 or HSRR1 are loaded with a copy of the corresponding bits of the MSR." Below is a representation of MSR bits which are not saved: 0:15 16:31 32 33:36 37:41 42:47 48:63 ——— | ——— | — X X X X — — — — — X X X X X X | ———— 0000 0000 | 7 | 8 | 3 | F | 0000 History: In the initial Qemu implementation (e1833e1), the mask 0x783F0000 was used for saving MSR in SRR1. But all the bits 32:47 were cleared during RFI restoring. This was wrong. The commit 2ada0ed explains that this breaks Altivec. Indeed, bit 38 (for Altivec support) must be saved and restored. The change of 2ada0ed was to restore all the bits of SRR1 to MSR. But it's also wrong. Explanation: As an example, let's see what's happening after a TLB miss. According to the e300 manual (E300CORERM table 5-6), the TLB miss interrupts set the bits 44-47 for KEY, I/D, WAY and S/L. These bits are specifics to the interrupt and must not be copied into MSR at the end of the interrupt. With the current implementation, a TLB miss overwrite bits POW, TGPR and ILE. Fix: It shouldn't be needed to filter-out bits on MSR saving when interrupt occurs. Specific bits overwrite MSR ones in SRR1. But at the end of interrupt (RFI), specifics bits must be cleared before restoring MSR from SRR1. The mask 0x783F0000 apply here. Discussion: The bits of the mask 0x783F0000 are cleared after an interrupt. I cannot find a specification which talks about this but I assume it is the truth since Linux can run this way. Maybe it's not perfect but it's better (works for e300). Signed-off-by: Thomas Monjalon Cc: Alexander Graf Acked-by: Alexander Graf --- target-ppc/helper.c | 1 - target-ppc/op_helper.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/target-ppc/helper.c b/target-ppc/helper.c index dabf1fd..5035d92 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2080,7 +2080,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) srr1 = SPR_SRR1; asrr0 = -1; asrr1 = -1; - msr &= ~((target_ulong)0x783F0000); switch (excp) { case POWERPC_EXCP_NONE: /* Should never happen */ diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 8f2ee98..3c3aa60 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -1646,20 +1646,20 @@ static inline void do_rfi(target_ulong nip, target_ulong msr, void helper_rfi (void) { do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1], - ~((target_ulong)0x0), 1); + ~((target_ulong)0x783F0000), 1); } #if defined(TARGET_PPC64) void helper_rfid (void) { do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1], - ~((target_ulong)0x0), 0); + ~((target_ulong)0x783F0000), 0); } void helper_hrfid (void) { do_rfi(env->spr[SPR_HSRR0], env->spr[SPR_HSRR1], - ~((target_ulong)0x0), 0); + ~((target_ulong)0x783F0000), 0); } #endif #endif