From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38692) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WuVtE-0007YB-4u for qemu-devel@nongnu.org; Tue, 10 Jun 2014 19:55:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WuVt8-0004DX-D3 for qemu-devel@nongnu.org; Tue, 10 Jun 2014 19:55:40 -0400 Received: from edge20.ethz.ch ([82.130.99.26]:2313) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WuVt7-0004D6-Np for qemu-devel@nongnu.org; Tue, 10 Jun 2014 19:55:34 -0400 From: Fabian Aggeler Date: Wed, 11 Jun 2014 01:54:56 +0200 Message-ID: <1402444514-19658-15-git-send-email-aggelerf@ethz.ch> In-Reply-To: <1402444514-19658-1-git-send-email-aggelerf@ethz.ch> References: <1402444514-19658-1-git-send-email-aggelerf@ethz.ch> MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, peter.crosthwaite@xilinx.com, greg.bellows@linaro.org, serge.fdrv@gmail.com, edgar.iglesias@gmail.com, christoffer.dall@linaro.org bits when modifying CPSR. Signed-off-by: Fabian Aggeler --- target-arm/helper.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 2fbecfa..f6ff4aa 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3091,9 +3091,6 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) env->GE = (val >> 16) & 0xf; } - env->daif &= ~(CPSR_AIF & mask); - env->daif |= val & CPSR_AIF & mask; - if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { if (bad_mode_switch(env, val & CPSR_M)) { /* Attempt to switch to an invalid mode: this is UNPREDICTABLE. @@ -3105,6 +3102,45 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) switch_mode(env, val & CPSR_M); } } + + /* In an implementation that does not include Virtualization Extensions + * the SCR.FW and SCR.AW bit control whether non-secure software is allowed + * to change the CPSR_F and CPSR_A bits respectively. + */ + if ((mask & CPSR_A) + && (val & CPSR_A) != (env->uncached_cpsr & CPSR_A) + && arm_feature(env, ARM_FEATURE_EL3) + && !(env->cp15.scr_el3 & SCR_AW) && !arm_is_secure(env)) { + qemu_log_mask(LOG_GUEST_ERROR, "Ignoring attempt to switch CPSR_A " + "flag from non-secure world with SCR.AW bit set\n"); + mask &= ~CPSR_A; + } + + if ((mask & CPSR_F)) { + /* Pre ARMv8: Check whether non-maskable FIQ (NMFI) support is enabled. + * If this bit is set software is not allowed to mask FIQs, + * but is allowed to set CPSR_F to 0. + */ + if (!arm_feature(env, ARM_FEATURE_V8) && + (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) && + (val & CPSR_F)) { + qemu_log_mask(LOG_GUEST_ERROR, "Ignoring attempt to enable CPSR_F " + "flag (non-maskable FIQ [NMFI] support enabled)\n"); + mask &= ~CPSR_F; + } + + if ((val & CPSR_F) != (env->uncached_cpsr & CPSR_F) + && arm_feature(env, ARM_FEATURE_EL3) + && !(env->cp15.scr_el3 & SCR_FW) && !arm_is_secure(env)) { + qemu_log_mask(LOG_GUEST_ERROR, "Ignoring attempt to switch CPSR_F " + "flag from non-secure world with SCR.FW bit set\n"); + mask &= ~CPSR_F; + } + } + + env->daif &= ~(CPSR_AIF & mask); + env->daif |= val & CPSR_AIF & mask; + mask &= ~CACHED_CPSR_BITS; env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); } -- 1.8.3.2