From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40743) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UsEHf-00063z-O3 for qemu-devel@nongnu.org; Thu, 27 Jun 2013 11:39:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UsEHZ-0006E5-Lv for qemu-devel@nongnu.org; Thu, 27 Jun 2013 11:38:55 -0400 Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa ([2001:8b0:1d0::1]:58293 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UsEHZ-0006DX-FG for qemu-devel@nongnu.org; Thu, 27 Jun 2013 11:38:49 -0400 From: Peter Maydell Date: Thu, 27 Jun 2013 16:38:47 +0100 Message-Id: <1372347527-4428-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PATCH] target-arm: avoid undefined behaviour when writing TTBCR List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: patches@linaro.org LPAE CPUs have more potentially valid bits in the TTBCR, and so the simple masking out of invalid bits is no longer sufficient to obtain the base address width field of the register, which is what we use to precalculate c2_mask and c2_base_mask. Explicitly extract the relevant register field rather than simply shifting by the register value. This bug would have had no ill effects in practice, since if the EAE bit (TTBCR bit 31) is set then we don't use the precalculated masks, and if EAE is zero then bits 30..3 are all UNK/SBZP, so well-behaved guests won't set them. However the shift is undefined behaviour, so we should avoid it. Signed-off-by: Peter Maydell --- Another one spotted by clang... target-arm/helper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 5f639fd..4bca570 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -891,6 +891,8 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = { static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { + int maskshift = extract32(value, 0, 3); + if (arm_feature(env, ARM_FEATURE_LPAE)) { value &= ~((7 << 19) | (3 << 14) | (0xf << 3)); } else { @@ -902,8 +904,8 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri, * and the c2_mask and c2_base_mask values are meaningless. */ env->cp15.c2_control = value; - env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> value); - env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> value); + env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift); + env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift); return 0; } -- 1.7.9.5