From patchwork Thu Jan 10 12:17:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 155148 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1837297jaa; Thu, 10 Jan 2019 04:27:21 -0800 (PST) X-Google-Smtp-Source: ALg8bN6BaGPJfpTivImjp6lXdtqKK+6ZTBinJJghunGw/BP+ewf244N7UlRnmegkY3aCJyd4KAd3 X-Received: by 2002:a1c:c70f:: with SMTP id x15mr9674055wmf.130.1547123241177; Thu, 10 Jan 2019 04:27:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547123241; cv=none; d=google.com; s=arc-20160816; b=FyeruogivoIl2ggb2hEWPkcu7GHTxzbr1ODUBK8n5wgNkHLWGx+dTwBmqP9uRz1vwI 4vVbEiJn3EQlej4Ml0LOD2+unfNpHbFRmNoJ/QlorlC+5sKICNLsSrHGnGfXEPEAJPeA 5P3aSG4MQ1PC1r8QG2xYj2rLULkVfmDwXzz4HjA10MpaXFYDPzdD0ENGxF/xFDfFJRdj +aN/UcnVT9F04ZSuQPewBEcNdRXKSVRONDG3+aXSxb56sMag8IgQusfYqgys802BUOZX 6pRFIGT+161DK8F/BebjvOMQRdTM2hhE4/cGZIFk4IotfPLtjtzue9Sw2YU2JRNRVF1L ka6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=/YB2L3OtfumYbatzc4HBobxII2tPYayqfJux+fHDtIY=; b=pCyci/nQFwrLV1FyqyJJbF3qVKSY4u4dytoFV7O2/Gr/ZQQTV1l94/zEwDIbS1CdXp oNzBRDbgmQP2MJSOpG1wUDKnjagWQNnbwn0zI4cm3LoYokUF87F/jC9EhF28oHoWIL0S J2+/K4KOP35atbnf3gbrTm/POGsbR//GjPFZc7y2A7CI8Jwduifcx/zzQk29+TBls19y iCeulDwI89pLzTqiXNvkZveALtkvfyGc78+3GXftdtxHvgQiNt6NxiBancqXAAooEvhH ljrgk4IRQdko78zfhC/kIgPXlpO5PRcJxwibFJ6j0DXWJfq2rjEvV3dzVuimtma6XoSb IEag== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HWYtGytL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id g16si41022158wrq.455.2019.01.10.04.27.20 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Jan 2019 04:27:21 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HWYtGytL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:58270 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghZQe-0002uv-3C for patch@linaro.org; Thu, 10 Jan 2019 07:27:20 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56021) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghZHb-0004XM-8j for qemu-devel@nongnu.org; Thu, 10 Jan 2019 07:18:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghZHZ-0007dV-W8 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 07:17:59 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:32977) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ghZHZ-0007cu-N9 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 07:17:57 -0500 Received: by mail-pl1-x642.google.com with SMTP id z23so5134824plo.0 for ; Thu, 10 Jan 2019 04:17:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/YB2L3OtfumYbatzc4HBobxII2tPYayqfJux+fHDtIY=; b=HWYtGytLLkOnRHqXxJKbzoHch3/Rh+LQJ2jxK3s/SJtjS1lHkho+Bb64IiVZZ0FmCg IyClrDXJ2lkyuE/Zi6FgLpo+uyHmGlKc35F6oOrXWSb3zSZtXadc/kuW6Pb+Rt6iaITc TiWPPkD5XUuakzAuH6o/lSQhQaYcf9/CCH9wM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/YB2L3OtfumYbatzc4HBobxII2tPYayqfJux+fHDtIY=; b=gtJ5pNBGIydrxTXWXYhWWisoH3KX13BZYZVsOrHASpnu197xjI7J998XDEhX6GwGsc Zr3kK4GXb3YRXqu0u2I4jqdn/yLEZInuumHuagHtZG6zuOMQYY7Stb7JO8ALf89VOXve 9WBgN7oI3hwndXnuKtU57Fjs6+OxyHd1KnSpBFI2W23Z1mPsBES495BH4YpzblI7yuJQ ylyjyX85Hp+TTGTtGrlme4bSuT//5QlBwvRZr3p6DkcSod+jGetUBz2ywU/J+5qfU7wr 0sDEAzcPzgENRFz6l8hOwKd3haUX5OXdBpFfUU5OnOEty+YMiWf2/HZW2pzsXMAxEJLL LxNw== X-Gm-Message-State: AJcUukd0C6UdjQwvcbW1bA+dF4P78DBWl6diIc7pFmmsY42zsjmtmFIV 5ExeBC7ZQCZOqQhTAgBPbqyGzbluGwGO3w== X-Received: by 2002:a17:902:5ac7:: with SMTP id g7mr10274374plm.212.1547122676196; Thu, 10 Jan 2019 04:17:56 -0800 (PST) Received: from cloudburst.twiddle.net (c220-239-117-135.belrs4.nsw.optusnet.com.au. [220.239.117.135]) by smtp.gmail.com with ESMTPSA id h74sm140934699pfd.35.2019.01.10.04.17.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 10 Jan 2019 04:17:55 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 23:17:30 +1100 Message-Id: <20190110121736.23448-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190110121736.23448-1-richard.henderson@linaro.org> References: <20190110121736.23448-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH 05/11] target/arm: Default handling of BTYPE during translation 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: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The branch target exception for guarded pages has high priority, and only 8 instructions are valid for that case. Perform this check before doing any other decode. Clear BTYPE after all insns that neither set BTYPE nor exit via exception (DISAS_NORETURN). Not yet handled are insns that exit via DISAS_NORETURN for some other reason, like direct branches. Signed-off-by: Richard Henderson --- target/arm/internals.h | 6 ++ target/arm/translate.h | 9 ++- target/arm/translate-a64.c | 139 +++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 2 deletions(-) -- 2.17.2 Reviewed-by: Peter Maydell diff --git a/target/arm/internals.h b/target/arm/internals.h index a6fd4582b2..d01a3f9f44 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -268,6 +268,7 @@ enum arm_exception_class { EC_FPIDTRAP = 0x08, EC_PACTRAP = 0x09, EC_CP14RRTTRAP = 0x0c, + EC_BTITRAP = 0x0d, EC_ILLEGALSTATE = 0x0e, EC_AA32_SVC = 0x11, EC_AA32_HVC = 0x12, @@ -439,6 +440,11 @@ static inline uint32_t syn_pactrap(void) return EC_PACTRAP << ARM_EL_EC_SHIFT; } +static inline uint32_t syn_btitrap(int btype) +{ + return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype; +} + static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc) { return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) diff --git a/target/arm/translate.h b/target/arm/translate.h index 3d5e8bacac..f73939d7b4 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -71,8 +71,13 @@ typedef struct DisasContext { bool pauth_active; /* True with v8.5-BTI and SCTLR_ELx.BT* set. */ bool bt; - /* A copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI. */ - uint8_t btype; + /* + * >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI. + * < 0, set by the current instruction. + */ + int8_t btype; + /* True if this page is guarded. */ + bool guarded_page; /* Bottom two bits of XScale c15_cpar coprocessor access control reg */ int c15_cpar; /* TCG op of the current insn_start. */ diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index ca2ae40701..68eb27089a 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -128,6 +128,16 @@ static inline int get_a64_user_mem_index(DisasContext *s) return arm_to_core_mmu_idx(useridx); } +static void reset_btype(DisasContext *s) +{ + if (s->btype != 0) { + TCGv_i32 zero = tcg_const_i32(0); + tcg_gen_st_i32(zero, cpu_env, offsetof(CPUARMState, btype)); + tcg_temp_free_i32(zero); + s->btype = 0; + } +} + void aarch64_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags) { @@ -13716,6 +13726,90 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) } } +/** + * is_guarded_page: + * @env: The cpu environment + * @s: The DisasContext + * + * Return true if the page is guarded. + */ +static bool is_guarded_page(CPUARMState *env, DisasContext *s) +{ +#ifdef CONFIG_USER_ONLY + return false; /* FIXME */ +#else + uint64_t addr = s->base.pc_first; + int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx); + unsigned int index = tlb_index(env, mmu_idx, addr); + CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); + + /* + * We test this immediately after reading an insn, which means + * that any normal page must be in the TLB. The only exception + * would be for executing from flash or device memory, which + * does not retain the TLB entry. + * + * FIXME: Assume false for those, for now. We could use + * arm_cpu_get_phys_page_attrs_debug to re-read the page + * table entry even for that case. + */ + return (tlb_hit(entry->addr_code, addr) && + env->iotlb[mmu_idx][index].attrs.guarded); +#endif +} + +/** + * btype_destination_ok: + * @insn: The instruction at the branch destination + * @bt: SCTLR_ELx.BT + * @btype: PSTATE.BTYPE, and is non-zero + * + * On a guarded page, there are a limited number of insns + * that may be present at the branch target: + * - branch target identifiers, + * - paciasp, pacibsp, + * - BRK insn + * - HLT insn + * Anything else causes a Branch Target Exception. + * + * Return true if the branch is compatible, false to raise BTITRAP. + */ +static bool btype_destination_ok(uint32_t insn, bool bt, int btype) +{ + if ((insn & 0xfffff01fu) == 0xd503201fu) { + /* HINT space */ + switch (extract32(insn, 5, 7)) { + case 031: /* PACIASP */ + case 033: /* PACIBSP */ + /* + * If SCTLR_ELx.BT, then PACI*SP are not compatible + * with btype == 3. Otherwise all btype are ok. + */ + return !bt || btype != 3; + case 040: /* BTI */ + /* Not compatible with any btype. */ + return false; + case 042: /* BTI c */ + /* Not compatible with btype == 3 */ + return btype != 3; + case 044: /* BTI j */ + /* Not compatible with btype == 2 */ + return btype != 2; + case 046: /* BTI jc */ + /* Compatible with any btype. */ + return true; + } + } else { + switch (insn & 0xffe0001fu) { + case 0xd4200000u: /* BRK */ + case 0xd4400000u: /* HLT */ + /* Give priority to the breakpoint exception. */ + return true; + } + } + return false; +} + /* C3.1 A64 instruction index by encoding */ static void disas_a64_insn(CPUARMState *env, DisasContext *s) { @@ -13727,6 +13821,43 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s) s->fp_access_checked = false; + if (dc_isar_feature(aa64_bti, s)) { + if (s->base.num_insns == 1) { + /* + * At the first insn of the TB, compute s->guarded_page. + * We delayed computing this until successfully reading + * the first insn of the TB, above. This (mostly) ensures + * that the softmmu tlb entry has been populated, and the + * page table GP bit is available. + * + * Note that we need to compute this even if btype == 0, + * because this value is used for BR instructions later + * where ENV is not available. + */ + s->guarded_page = is_guarded_page(env, s); + + /* First insn can have btype set to non-zero. */ + tcg_debug_assert(s->btype >= 0); + + /* + * Note that the Branch Target Exception has fairly high + * priority -- below debugging exceptions but above most + * everything else. This allows us to handle this now + * instead of waiting until the insn is otherwise decoded. + */ + if (s->btype != 0 + && s->guarded_page + && !btype_destination_ok(insn, s->bt, s->btype)) { + gen_exception_insn(s, 4, EXCP_UDEF, syn_btitrap(s->btype), + default_exception_el(s)); + return; + } + } else { + /* Not the first insn: btype must be 0. */ + tcg_debug_assert(s->btype == 0); + } + } + switch (extract32(insn, 25, 4)) { case 0x0: case 0x1: case 0x3: /* UNALLOCATED */ unallocated_encoding(s); @@ -13763,6 +13894,14 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s) /* if we allocated any temporaries, free them here */ free_tmp_a64(s); + + /* + * After execution of most insns, btype is reset to 0. + * Note that we set btype == -1 when the insn sets btype. + */ + if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) { + reset_btype(s); + } } static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,