From patchwork Tue Oct 4 12:42:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 77264 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp2211444qgf; Tue, 4 Oct 2016 06:12:17 -0700 (PDT) X-Received: by 10.55.164.195 with SMTP id n186mr3605395qke.197.1475586737950; Tue, 04 Oct 2016 06:12:17 -0700 (PDT) Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id k128si2743981qkb.111.2016.10.04.06.12.17 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 04 Oct 2016 06:12:17 -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; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:42407 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brPW5-0007vT-AG for patch@linaro.org; Tue, 04 Oct 2016 09:12:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brP3w-00007s-TP for qemu-devel@nongnu.org; Tue, 04 Oct 2016 08:43:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1brP3u-0006SA-3b for qemu-devel@nongnu.org; Tue, 04 Oct 2016 08:43:12 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:47192) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brP3t-0006RK-Sc for qemu-devel@nongnu.org; Tue, 04 Oct 2016 08:43:10 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1brP3t-0005tI-I6 for qemu-devel@nongnu.org; Tue, 04 Oct 2016 13:43:09 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 4 Oct 2016 13:42:55 +0100 Message-Id: <1475584975-25099-28-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475584975-25099-1-git-send-email-peter.maydell@linaro.org> References: <1475584975-25099-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 27/27] target-arm: Correctly handle 'sub pc, pc, 1' for ARMv6 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: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" In the ARM v6 architecture, 'sub pc, pc, 1' is not an interworking branch, so the computed new value is written to r15 as a normal value. The architecture says that in this case, bits [1:0] of the value written must be ignored if we are in ARM mode (or bit [0] ignored if in Thumb mode); this is a change from the ARMv4/v5 specification that behaviour is UNPREDICTABLE. Use the correct mask on the PC value when doing a non-interworking store to PC. A popular library used on RaspberryPi uses this instruction as part of a trick to determine whether it is running on ARMv6 or ARMv7, and we were mishandling the sequence. Fixes bug: https://bugs.launchpad.net/bugs/1625295 Reported-by: Signed-off-by: Peter Maydell Message-id: 1474380941-4730-1-git-send-email-peter.maydell@linaro.org --- target-arm/translate.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/target-arm/translate.c b/target-arm/translate.c index 693d4bc..8df24bf 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -180,7 +180,12 @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg) static void store_reg(DisasContext *s, int reg, TCGv_i32 var) { if (reg == 15) { - tcg_gen_andi_i32(var, var, ~1); + /* In Thumb mode, we must ignore bit 0. + * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0] + * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0]. + * We choose to ignore [1:0] in ARM mode for all architecture versions. + */ + tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3); s->is_jmp = DISAS_JUMP; } tcg_gen_mov_i32(cpu_R[reg], var);