From patchwork Mon Oct 19 12:09:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 55221 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by patches.linaro.org (Postfix) with ESMTPS id 9097C22EA2 for ; Mon, 19 Oct 2015 12:09:06 +0000 (UTC) Received: by wicfg8 with SMTP id fg8sf499429wic.0 for ; Mon, 19 Oct 2015 05:09:05 -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:cc:subject :date:message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=b1tHgYxnj95ZZrNecl5YSwQsQi7WI0WOs/1JcTW3Wdk=; b=YGl1V4O3NtCjXa+ZW4MoRInrwTK2lMxmysDihlJ20EsIpUXnfyMAWsdBSwg2mjAbRV /XYVZDfdPm2zrXSuvkfzcKygUbqlXozfMCzpmyPqvY9Blo6xSgcGT6OLODQ3PrkDa7Ky CvWXjXl1mx9fvxmFyw5q+wwrkNkm8BWx3R22Yizj2Y1pVZmhOF8UcyZr8BAtp1xpi8f0 MQ0ZbE/8tqWn+x0SZJcx7v6EcefUoLYqmF1yyNbu2i/BixKzmPjUGdWuDR2Ssdopcg4W cx84NOw1tI/wk3PWkHyex8hWwh4q71vyq2RHVRIQ7m/3DGou/V1QTl4IaWTUDw8JGn6h qNQQ== X-Gm-Message-State: ALoCoQl/VJ+Oiq3VxWgDgxC8PdnO2BQutRwkdts/CurvQK+WO4dcDP7PkNnpaU5cC7+AbcnZSq5V X-Received: by 10.180.184.164 with SMTP id ev4mr4143591wic.3.1445256545896; Mon, 19 Oct 2015 05:09:05 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.148.143 with SMTP id w137ls520143lfd.105.gmail; Mon, 19 Oct 2015 05:09:05 -0700 (PDT) X-Received: by 10.112.172.165 with SMTP id bd5mr14429553lbc.51.1445256545747; Mon, 19 Oct 2015 05:09:05 -0700 (PDT) Received: from mail-lf0-f48.google.com (mail-lf0-f48.google.com. [209.85.215.48]) by mx.google.com with ESMTPS id zz10si22612189lbb.56.2015.10.19.05.09.05 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Oct 2015 05:09:05 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.48 as permitted sender) client-ip=209.85.215.48; Received: by lffy185 with SMTP id y185so110066698lff.2 for ; Mon, 19 Oct 2015 05:09:05 -0700 (PDT) X-Received: by 10.25.154.203 with SMTP id c194mr2760391lfe.32.1445256545619; Mon, 19 Oct 2015 05:09:05 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1431050lbq; Mon, 19 Oct 2015 05:09:04 -0700 (PDT) X-Received: by 10.180.208.68 with SMTP id mc4mr21211808wic.60.1445256544825; Mon, 19 Oct 2015 05:09:04 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id uz5si40659835wjc.199.2015.10.19.05.09.04 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 19 Oct 2015 05:09:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Zo9FO-0004tX-U9; Mon, 19 Oct 2015 13:09:02 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Pavel Dovgalyuk , Laurent Desnogues Subject: [PATCH v2] target-arm/translate.c: Handle non-executable page-straddling Thumb insns Date: Mon, 19 Oct 2015 13:09:02 +0100 Message-Id: <1445256542-18790-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.48 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When the memory we're trying to translate code from is not executable we have to turn this into a guest fault. In order to report the correct PC for this fault, and to make sure it is not reported until after any other possible faults for instructions earlier in execution, we must terminate TBs at the end of a page, in case the next instruction is in a non-executable page. This is simple for T16, A32 and A64 instructions, which are always aligned to their size. However T32 instructions may be 32-bits but only 16-aligned, so they can straddle a page boundary. Correct the condition that checks whether the next instruction will touch the following page, to ensure that if we're 2 bytes before the boundary and this insn is T32 then we end the TB. Reported-by: Pavel Dovgalyuk Reviewed-by: Laurent Desnogues Signed-off-by: Peter Maydell --- Changes v1->v2: * rebase * check '(insn >> 11) >= 0x1d' rather than switching on insn >> 11 target-arm/translate.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 9f1d740..6be2c72 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -11179,6 +11179,35 @@ undef: default_exception_el(s)); } +static bool insn_crosses_page(CPUARMState *env, DisasContext *s) +{ + /* Return true if the insn at dc->pc might cross a page boundary. + * (False positives are OK, false negatives are not.) + */ + uint16_t insn; + + if ((s->pc & 3) == 0) { + /* At a 4-aligned address we can't be crossing a page */ + return false; + } + + /* This must be a Thumb insn */ + insn = arm_lduw_code(env, s->pc, s->bswap_code); + + if ((insn >> 11) >= 0x1d) { + /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the + * First half of a 32-bit Thumb insn. Thumb-1 cores might + * end up actually treating this as two 16-bit insns (see the + * code at the start of disas_thumb2_insn()) but we don't bother + * to check for that as it is unlikely, and false positives here + * are harmless. + */ + return true; + } + /* Definitely a 16-bit insn, can't be crossing a page. */ + return false; +} + /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. */ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) @@ -11190,6 +11219,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) target_ulong next_page_start; int num_insns; int max_insns; + bool end_of_page; /* generate intermediate code */ @@ -11411,11 +11441,24 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) * Otherwise the subsequent code could get translated several times. * Also stop translation when a page boundary is reached. This * ensures prefetch aborts occur at the right place. */ + + /* We want to stop the TB if the next insn starts in a new page, + * or if it spans between this page and the next. This means that + * if we're looking at the last halfword in the page we need to + * see if it's a 16-bit Thumb insn (which will fit in this TB) + * or a 32-bit Thumb insn (which won't). + * This is to avoid generating a silly TB with a single 16-bit insn + * in it at the end of this page (which would execute correctly + * but isn't very efficient). + */ + end_of_page = (dc->pc >= next_page_start) || + ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc)); + } while (!dc->is_jmp && !tcg_op_buf_full() && !cs->singlestep_enabled && !singlestep && !dc->ss_active && - dc->pc < next_page_start && + !end_of_page && num_insns < max_insns); if (tb->cflags & CF_LAST_IO) {