From patchwork Tue Feb 5 17:04:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 10797831 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 227BA746 for ; Tue, 5 Feb 2019 17:31:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12A002A8EA for ; Tue, 5 Feb 2019 17:31:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1127B2C743; Tue, 5 Feb 2019 17:31:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4AD412C72A for ; Tue, 5 Feb 2019 17:31:47 +0000 (UTC) Received: from localhost ([127.0.0.1]:35582 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr4ZW-0006tX-Ed for patchwork-qemu-devel@patchwork.kernel.org; Tue, 05 Feb 2019 12:31:46 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35925) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr4AS-0001uW-Q9 for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:05:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gr4AQ-0000Y3-Qp for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:05:52 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:45382) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gr4AM-0000Kk-AR for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:05:48 -0500 Received: by mail-wr1-x443.google.com with SMTP id q15so4407403wro.12 for ; Tue, 05 Feb 2019 09:05:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=PVirn6BLcAXppSndYzC07n8dGqp6nt4fa98BODjPqNw=; b=zPpfI9ZfBjEXx6N/xscOmHCYgoM6dMFtslLWKQpcI45fWQY+ebVvsZgONZ1ndE3FTj /p4bLmavPFLCF+2Fafc43TOneYykuAHf3t4YjUIhjWmziYne4SMcmU9zr6MGnlOTxDiy 4RqRMZ08jvdzEGv1XDOhBsHgd1WTq9VtugcrAxC68M4AexRmo5Q6ihcKaaEWrg829Iww vkKsSPssCztNyBIVTgo6SG864YlM5JG9JkLpTocfVb37FPk6Cd9xObTaIZJXyCpAhoL9 L7O5TrJigW65LFjltbVExqUSDRCLAM+n14pXx9scx2Y/PINSTWP5iE9iFZwgPPOd8pI/ vtOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PVirn6BLcAXppSndYzC07n8dGqp6nt4fa98BODjPqNw=; b=BZruO219F/R9YDOmL6iOOjjcdl4n0S8xd2Lo1Q5bXm8AP+Mz1KN1B4+9vUQLjyiTyr BBRImmL0CKQpwZ5A1uQ/xz2OUIFv+IkSUi0/y6pn/Fl8a7Zz7LRa9CuhzNqFuN0kzfJx SLqKlQkc6X++7LXD9NC6hyC4ED6tpZ6bQTDnI9pL7XSKZ09ov/9PC+jqVVS30xxUcsX8 rYmcEZFO+5cOWW0zbNrru1DADDa7az0UBKi4G7DPl8uAtdfNdmpwYyNcLL/K4/SEg2eD xJSzbCuPHGT8xunaZBlhIaZ1EQapdqi6ur/kEs3lFBDB2KoFiHDthKVj8MS181UqsGfU s8HQ== X-Gm-Message-State: AHQUAuYtV1SPi9tjSOVQSebBK4PUW5rZyLUinj+ISkxAyumNk2whRltV Pmxrn/+hD+kKXOrEM2faDdjLT7go9MAsdA== X-Google-Smtp-Source: AHgI3IbyYYLp2IeRasZ68QUzDpIpYuXPdWR5J6tmYpIbMRihy1crGNdZIODlH37j7BZVAajkQY3zFQ== X-Received: by 2002:adf:ba94:: with SMTP id p20mr4462946wrg.62.1549386321596; Tue, 05 Feb 2019 09:05:21 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id w13sm5583164wmf.5.2019.02.05.09.05.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Feb 2019 09:05:20 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 5 Feb 2019 17:04:54 +0000 Message-Id: <20190205170510.21984-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205170510.21984-1-peter.maydell@linaro.org> References: <20190205170510.21984-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PULL 06/22] 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: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Richard Henderson 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. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20190128223118.5255-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 6 ++ target/arm/translate.h | 9 ++- target/arm/translate-a64.c | 139 +++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index a6fd4582b2b..d01a3f9f44b 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 3d5e8bacacb..f73939d7b4f 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 a92fd433783..7034fb3d129 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) { @@ -13756,6 +13766,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.target_tlb_bit0); +#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 0b011001: /* PACIASP */ + case 0b011011: /* PACIBSP */ + /* + * If SCTLR_ELx.BT, then PACI*SP are not compatible + * with btype == 3. Otherwise all btype are ok. + */ + return !bt || btype != 3; + case 0b100000: /* BTI */ + /* Not compatible with any btype. */ + return false; + case 0b100010: /* BTI c */ + /* Not compatible with btype == 3 */ + return btype != 3; + case 0b100100: /* BTI j */ + /* Not compatible with btype == 2 */ + return btype != 2; + case 0b100110: /* 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) { @@ -13767,6 +13861,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); @@ -13803,6 +13934,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,