From patchwork Thu Apr 17 10:33:24 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 28580 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f71.google.com (mail-oa0-f71.google.com [209.85.219.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id A4E77206A6 for ; Thu, 17 Apr 2014 12:41:30 +0000 (UTC) Received: by mail-oa0-f71.google.com with SMTP id j17sf1887728oag.6 for ; Thu, 17 Apr 2014 05:41:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=9Uqzgw3AMVvlR6aHOXYvildaj9ueg0u+rdnlEQV0GRM=; b=RVaKFHOzDsRSHs9EydJ1zMb6cOM9uFmIS1aeAjkXeCxY/+WvWqjPuZBA0aBvXhAtnC O2rEZhGo/Dd+WNf92I+1cJpRX3TMH8vqHi80t5zIubSC5cjNa6BbP+EhNSW3SvLKcHta zg1yw6WTME5q7s9Mg/CU+8hbl5EzkvaN0EyyiJnrDV+63xfU7yKLeQ+0ZLvYjDikpzbn jY2iTsJlY6+L9CdmhAQiN0dASg2H1U595Hl/MFjSuLPlQCrZ5T3g0WdBIPnilxJupZSO YsTsqWalTFuDLbmRIlEUFK1WEeraWJlmjVjf5y6zb24bE8LOA4pZVWfc/gqh9mvONSkZ kg9Q== X-Gm-Message-State: ALoCoQll3O4V8csUY/pvu1kOFbWyAuRUNAJt6xLaJ9B2BI86yxxGjGzYuKpq3yZKXqLtKJP3490z X-Received: by 10.182.3.68 with SMTP id a4mr7164219oba.16.1397738490069; Thu, 17 Apr 2014 05:41:30 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.80.145 with SMTP id c17ls1006414qgd.60.gmail; Thu, 17 Apr 2014 05:41:29 -0700 (PDT) X-Received: by 10.221.22.71 with SMTP id qv7mr157533vcb.34.1397738489934; Thu, 17 Apr 2014 05:41:29 -0700 (PDT) Received: from mail-vc0-f176.google.com (mail-vc0-f176.google.com [209.85.220.176]) by mx.google.com with ESMTPS id ck5si3399100vdd.163.2014.04.17.05.41.29 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 17 Apr 2014 05:41:29 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.176 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.176; Received: by mail-vc0-f176.google.com with SMTP id lc6so411871vcb.21 for ; Thu, 17 Apr 2014 05:41:29 -0700 (PDT) X-Received: by 10.220.191.134 with SMTP id dm6mr7623697vcb.16.1397738489835; Thu, 17 Apr 2014 05:41:29 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp32150vcb; Thu, 17 Apr 2014 05:41:29 -0700 (PDT) X-Received: by 10.224.69.66 with SMTP id y2mr12340347qai.25.1397738489019; Thu, 17 Apr 2014 05:41:29 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id n7si10457927qas.217.2014.04.17.05.41.28 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 17 Apr 2014 05:41:29 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:59558 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wajt8-0006lV-1t for patch@linaro.org; Thu, 17 Apr 2014 06:49:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51149) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WajeK-00080x-4c for qemu-devel@nongnu.org; Thu, 17 Apr 2014 06:34:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WajeI-0002Yd-T7 for qemu-devel@nongnu.org; Thu, 17 Apr 2014 06:34:32 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:47842) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WajeI-0002OB-LZ for qemu-devel@nongnu.org; Thu, 17 Apr 2014 06:34:30 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Wajdv-0001zN-Fn for qemu-devel@nongnu.org; Thu, 17 Apr 2014 11:34:07 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 17 Apr 2014 11:33:24 +0100 Message-Id: <1397730846-7576-10-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1397730846-7576-1-git-send-email-peter.maydell@linaro.org> References: <1397730846-7576-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 09/51] target-arm: Fix VFP enables for AArch32 EL0 under AArch64 EL1 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+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.176 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The current A32/T32 decoder bases its "is VFP/Neon enabled?" check on the FPSCR.EN bit. This is correct if EL1 is AArch32, but for an AArch64 EL1 the logic is different: it must act as if FPSCR.EN is always set. Instead, trapping must happen according to CPACR bits for cp10/cp11; these cover all of FP/Neon, including the FPSCR/FPSID/MVFR register accesses which FPSCR.EN does not affect. Add support for CPACR checks (which are also required for ARMv7, but were unimplemented because Linux happens not to use them) and make sure they generate exceptions with the correct syndrome. We actually return incorrect syndrome information for cases where FP is disabled but the specific instruction bit pattern is unallocated: strictly these should be the Uncategorized exception, not a "SIMD disabled" exception. This should be mostly harmless, and the structure of the A32/T32 VFP/Neon decoder makes it painful to put the 'FP disabled?' checks in the right places. Signed-off-by: Peter Maydell Reviewed-by: Peter Crosthwaite --- target-arm/cpu.h | 10 +++++++++- target-arm/translate.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 72c4c7a..ff56519 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1104,6 +1104,8 @@ static inline int cpu_mmu_index (CPUARMState *env) #define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT) #define ARM_TBFLAG_BSWAP_CODE_SHIFT 16 #define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT) +#define ARM_TBFLAG_CPACR_FPEN_SHIFT 17 +#define ARM_TBFLAG_CPACR_FPEN_MASK (1 << ARM_TBFLAG_CPACR_FPEN_SHIFT) /* Bit usage when in AArch64 state */ #define ARM_TBFLAG_AA64_EL_SHIFT 0 @@ -1128,6 +1130,8 @@ static inline int cpu_mmu_index (CPUARMState *env) (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT) #define ARM_TBFLAG_BSWAP_CODE(F) \ (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT) +#define ARM_TBFLAG_CPACR_FPEN(F) \ + (((F) & ARM_TBFLAG_CPACR_FPEN_MASK) >> ARM_TBFLAG_CPACR_FPEN_SHIFT) #define ARM_TBFLAG_AA64_EL(F) \ (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT) #define ARM_TBFLAG_AA64_FPEN(F) \ @@ -1161,9 +1165,13 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, if (privmode) { *flags |= ARM_TBFLAG_PRIV_MASK; } - if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) { + if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30) + || arm_el_is_aa64(env, 1)) { *flags |= ARM_TBFLAG_VFPEN_MASK; } + if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) { + *flags |= ARM_TBFLAG_CPACR_FPEN_MASK; + } } *cs_base = 0; diff --git a/target-arm/translate.c b/target-arm/translate.c index 84700ca..03e2c00 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2952,6 +2952,16 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) if (!arm_feature(env, ARM_FEATURE_VFP)) return 1; + /* FIXME: this access check should not take precedence over UNDEF + * for invalid encodings; we will generate incorrect syndrome information + * for attempts to execute invalid vfp/neon encodings with FP disabled. + */ + if (!s->cpacr_fpen) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb)); + return 0; + } + if (!s->vfp_enabled) { /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ if ((insn & 0x0fe00fff) != 0x0ee00a10) @@ -4232,6 +4242,16 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn) TCGv_i32 tmp2; TCGv_i64 tmp64; + /* FIXME: this access check should not take precedence over UNDEF + * for invalid encodings; we will generate incorrect syndrome information + * for attempts to execute invalid vfp/neon encodings with FP disabled. + */ + if (!s->cpacr_fpen) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb)); + return 0; + } + if (!s->vfp_enabled) return 1; VFP_DREG_D(rd, insn); @@ -4954,6 +4974,16 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5; TCGv_i64 tmp64; + /* FIXME: this access check should not take precedence over UNDEF + * for invalid encodings; we will generate incorrect syndrome information + * for attempts to execute invalid vfp/neon encodings with FP disabled. + */ + if (!s->cpacr_fpen) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb)); + return 0; + } + if (!s->vfp_enabled) return 1; q = (insn & (1 << 6)) != 0; @@ -10736,6 +10766,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, #if !defined(CONFIG_USER_ONLY) dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0); #endif + dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags); dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags); dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);