From patchwork Sat Jul 9 03:41:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 9221967 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4781D60572 for ; Sat, 9 Jul 2016 03:42:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3758528799 for ; Sat, 9 Jul 2016 03:42:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 28070287BC; Sat, 9 Jul 2016 03:42:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 90A4728799 for ; Sat, 9 Jul 2016 03:42:33 +0000 (UTC) Received: from localhost ([::1]:48812 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bLjA0-0001Gm-OW for patchwork-qemu-devel@patchwork.kernel.org; Fri, 08 Jul 2016 23:42:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41557) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bLj9Z-0001Ei-Gl for qemu-devel@nongnu.org; Fri, 08 Jul 2016 23:42:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bLj9X-0001rZ-GG for qemu-devel@nongnu.org; Fri, 08 Jul 2016 23:42:04 -0400 Received: from gate.crashing.org ([63.228.1.57]:57878) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bLj9R-0001qM-M0; Fri, 08 Jul 2016 23:41:57 -0400 Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id u693fY27005243; Fri, 8 Jul 2016 22:41:35 -0500 Message-ID: <1468035691.20552.29.camel@kernel.crashing.org> From: Benjamin Herrenschmidt To: Mark Cave-Ayland , David Gibson , peter.maydell@linaro.org Date: Sat, 09 Jul 2016 13:41:31 +1000 In-Reply-To: <1468033695.20552.24.camel@kernel.crashing.org> References: <1467355319-28406-1-git-send-email-david@gibson.dropbear.id.au> <1467355319-28406-6-git-send-email-david@gibson.dropbear.id.au> <1468032411.20552.21.camel@kernel.crashing.org> <1468032757.20552.22.camel@au1.ibm.com> <1468033216.20552.23.camel@kernel.crashing.org> <1468033695.20552.24.camel@kernel.crashing.org> X-Mailer: Evolution 3.20.3 (3.20.3-1.fc24.1) Mime-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 63.228.1.57 Subject: [Qemu-devel] [PATCH v2] ppc: Fix support for odd MSR combinations X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?ISO-8859-1?Q?C=E9dric?= Le Goater Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP MacOS uses an architecturally illegal MSR combination that seems nonetheless supported by 32-bit processors, which is to have MSR[PR]=1 and one or more of MSR[DR/IR/EE]=0. This adds support for it. To work properly we need to also properly include support for PR=1,{I,D}R=0 to the MMU index used by the qemu TLB. Signed-off-by: Benjamin Herrenschmidt Tested-by: Mark Cave-Ayland --- v2. Use the correct flags target-ppc/helper_regs.h | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h index 8fdfa5c..466ad67 100644 --- a/target-ppc/helper_regs.h +++ b/target-ppc/helper_regs.h @@ -41,17 +41,19 @@ static inline void hreg_swap_gpr_tgpr(CPUPPCState *env) static inline void hreg_compute_mem_idx(CPUPPCState *env) { - /* This is our encoding for server processors + /* This is our encoding for server processors. The architecture + * specifies that there is no such thing as userspace with + * translation off, however it appears that MacOS does it and + * some 32-bit CPUs support it. Weird... * * 0 = Guest User space virtual mode * 1 = Guest Kernel space virtual mode - * 2 = Guest Kernel space real mode - * 3 = HV User space virtual mode - * 4 = HV Kernel space virtual mode - * 5 = HV Kernel space real mode - * - * The combination PR=1 IR&DR=0 is invalid, we will treat - * it as IR=DR=1 + * 2 = Guest User space real mode + * 3 = Guest Kernel space real mode + * 4 = HV User space virtual mode + * 5 = HV Kernel space virtual mode + * 6 = HV User space real mode + * 7 = HV Kernel space real mode * * For BookE, we need 8 MMU modes as follow: * @@ -71,20 +73,11 @@ static inline void hreg_compute_mem_idx(CPUPPCState *env) env->immu_idx += msr_gs ? 4 : 0; env->dmmu_idx += msr_gs ? 4 : 0; } else { - /* First calucalte a base value independent of HV */ - if (msr_pr != 0) { - /* User space, ignore IR and DR */ - env->immu_idx = env->dmmu_idx = 0; - } else { - /* Kernel, setup a base I/D value */ - env->immu_idx = msr_ir ? 1 : 2; - env->dmmu_idx = msr_dr ? 1 : 2; - } - /* Then offset it for HV */ - if (msr_hv) { - env->immu_idx += 3; - env->dmmu_idx += 3; - } + env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; + env->immu_idx += msr_ir ? 0 : 2; + env->dmmu_idx += msr_dr ? 0 : 2; + env->immu_idx += msr_hv ? 4 : 0; + env->dmmu_idx += msr_hv ? 4 : 0; } } @@ -136,8 +129,13 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, /* Change the exception prefix on PowerPC 601 */ env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000; } - /* If PR=1 then EE, IR and DR must be 1 */ - if ((value >> MSR_PR) & 1) { + /* If PR=1 then EE, IR and DR must be 1 + * + * Note: We only enforce this on 64-bit processors. It appears that + * 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS + * exploits it. + */ + if ((env->insns_flags & PPC_64B) && ((value >> MSR_PR) & 1)) { value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR); } #endif