[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v8 08/45] target/arm: Add MTE bits to tb_flags
From: |
Richard Henderson |
Subject: |
[PATCH v8 08/45] target/arm: Add MTE bits to tb_flags |
Date: |
Tue, 23 Jun 2020 12:36:21 -0700 |
Cache the composite ATA setting.
Cache when MTE is fully enabled, i.e. access to tags are enabled
and tag checks affect the PE. Do this for both the normal context
and the UNPRIV context.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v3: Remove stub helper_mte_check; moved to a later patch.
v6: Add mte0_active and ata bits; drop reviewed-by.
---
target/arm/cpu.h | 12 ++++++++----
target/arm/internals.h | 18 +++++++++++++++++
target/arm/translate.h | 5 +++++
target/arm/helper.c | 40 ++++++++++++++++++++++++++++++++++++++
target/arm/translate-a64.c | 4 ++++
5 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 49cf37d43b..a5d3b6c9ee 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3187,10 +3187,10 @@ typedef ARMCPU ArchCPU;
* | | | TBFLAG_A32 | |
* | | +-----+----------+ TBFLAG_AM32 |
* | TBFLAG_ANY | |TBFLAG_M32| |
- * | | +-+----------+--------------|
- * | | | TBFLAG_A64 |
- * +--------------+---------+---------------------------+
- * 31 20 15 0
+ * | +-----------+----------+--------------|
+ * | | TBFLAG_A64 |
+ * +--------------+-------------------------------------+
+ * 31 20 0
*
* Unless otherwise noted, these bits are cached in env->hflags.
*/
@@ -3257,6 +3257,10 @@ FIELD(TBFLAG_A64, BT, 9, 1)
FIELD(TBFLAG_A64, BTYPE, 10, 2) /* Not cached. */
FIELD(TBFLAG_A64, TBID, 12, 2)
FIELD(TBFLAG_A64, UNPRIV, 14, 1)
+FIELD(TBFLAG_A64, ATA, 15, 1)
+FIELD(TBFLAG_A64, TCMA, 16, 2)
+FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
+FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
/**
* cpu_mmu_index:
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 56b4672685..53e249687b 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1198,6 +1198,24 @@ static inline int exception_target_el(CPUARMState *env)
return target_el;
}
+/* Determine if allocation tags are available. */
+static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
+ uint64_t sctlr)
+{
+ if (el < 3
+ && arm_feature(env, ARM_FEATURE_EL3)
+ && !(env->cp15.scr_el3 & SCR_ATA)) {
+ return false;
+ }
+ if (el < 2
+ && arm_feature(env, ARM_FEATURE_EL2)
+ && !(arm_hcr_el2_eff(env) & HCR_ATA)) {
+ return false;
+ }
+ sctlr &= (el == 0 ? SCTLR_ATA0 : SCTLR_ATA);
+ return sctlr != 0;
+}
+
#ifndef CONFIG_USER_ONLY
/* Security attributes for an address, as returned by v8m_security_lookup. */
diff --git a/target/arm/translate.h b/target/arm/translate.h
index c6f9376000..dbbf6145cb 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -30,6 +30,7 @@ typedef struct DisasContext {
ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
uint8_t tbii; /* TBI1|TBI0 for insns */
uint8_t tbid; /* TBI1|TBI0 for data */
+ uint8_t tcma; /* TCMA1|TCMA0 for MTE */
bool ns; /* Use non-secure CPREG bank on access */
int fp_excp_el; /* FP exception EL or 0 if enabled */
int sve_excp_el; /* SVE exception EL or 0 if enabled */
@@ -77,6 +78,10 @@ typedef struct DisasContext {
bool unpriv;
/* True if v8.3-PAuth is active. */
bool pauth_active;
+ /* True if v8.5-MTE access to tags is enabled. */
+ bool ata;
+ /* True if v8.5-MTE tag checks affect the PE; index with is_unpriv. */
+ bool mte_active[2];
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
bool bt;
/* True if any CP15 access is trapped by HSTR_EL2 */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b4842ea23e..2c6ec244af 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10655,6 +10655,16 @@ static int aa64_va_parameter_tbid(uint64_t tcr,
ARMMMUIdx mmu_idx)
}
}
+static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
+{
+ if (regime_has_2_ranges(mmu_idx)) {
+ return extract64(tcr, 57, 2);
+ } else {
+ /* Replicate the single TCMA bit so we always have 2 bits. */
+ return extract32(tcr, 30, 1) * 3;
+ }
+}
+
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
ARMMMUIdx mmu_idx, bool data)
{
@@ -12679,6 +12689,36 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env,
int el, int fp_el,
}
}
+ if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
+ /*
+ * Set MTE_ACTIVE if any access may be Checked, and leave clear
+ * if all accesses must be Unchecked:
+ * 1) If no TBI, then there are no tags in the address to check,
+ * 2) If Tag Check Override, then all accesses are Unchecked,
+ * 3) If Tag Check Fail == 0, then Checked access have no effect,
+ * 4) If no Allocation Tag Access, then all accesses are Unchecked.
+ */
+ if (allocation_tag_access_enabled(env, el, sctlr)) {
+ flags = FIELD_DP32(flags, TBFLAG_A64, ATA, 1);
+ if (tbid
+ && !(env->pstate & PSTATE_TCO)
+ && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
+ flags = FIELD_DP32(flags, TBFLAG_A64, MTE_ACTIVE, 1);
+ }
+ }
+ /* And again for unprivileged accesses, if required. */
+ if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
+ && tbid
+ && !(env->pstate & PSTATE_TCO)
+ && (sctlr & SCTLR_TCF0)
+ && allocation_tag_access_enabled(env, 0, sctlr)) {
+ flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
+ }
+ /* Cache TCMA as well as TBI. */
+ flags = FIELD_DP32(flags, TBFLAG_A64, TCMA,
+ aa64_va_parameter_tcma(tcr, mmu_idx));
+ }
+
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index efdfd50fb6..717cb96a40 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14183,6 +14183,7 @@ static void
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
+ dc->tcma = FIELD_EX32(tb_flags, TBFLAG_A64, TCMA);
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
#if !defined(CONFIG_USER_ONLY)
dc->user = (dc->current_el == 0);
@@ -14194,6 +14195,9 @@ static void
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->bt = FIELD_EX32(tb_flags, TBFLAG_A64, BT);
dc->btype = FIELD_EX32(tb_flags, TBFLAG_A64, BTYPE);
dc->unpriv = FIELD_EX32(tb_flags, TBFLAG_A64, UNPRIV);
+ dc->ata = FIELD_EX32(tb_flags, TBFLAG_A64, ATA);
+ dc->mte_active[0] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE_ACTIVE);
+ dc->mte_active[1] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE0_ACTIVE);
dc->vec_len = 0;
dc->vec_stride = 0;
dc->cp_regs = arm_cpu->cp_regs;
--
2.25.1
- [PATCH v8 00/45] target/arm: Implement ARMv8.5-MemTag, system mode, Richard Henderson, 2020/06/23
- [PATCH v8 02/45] target/arm: Improve masking of SCR RES0 bits, Richard Henderson, 2020/06/23
- [PATCH v8 03/45] target/arm: Add support for MTE to SCTLR_ELx, Richard Henderson, 2020/06/23
- [PATCH v8 01/45] target/arm: Add isar tests for mte, Richard Henderson, 2020/06/23
- [PATCH v8 04/45] target/arm: Add support for MTE to HCR_EL2 and SCR_EL3, Richard Henderson, 2020/06/23
- [PATCH v8 05/45] target/arm: Rename DISAS_UPDATE to DISAS_UPDATE_EXIT, Richard Henderson, 2020/06/23
- [PATCH v8 06/45] target/arm: Add DISAS_UPDATE_NOCHAIN, Richard Henderson, 2020/06/23
- [PATCH v8 07/45] target/arm: Add MTE system registers, Richard Henderson, 2020/06/23
- [PATCH v8 08/45] target/arm: Add MTE bits to tb_flags,
Richard Henderson <=
- [PATCH v8 09/45] target/arm: Implement the IRG instruction, Richard Henderson, 2020/06/23
- [PATCH v8 10/45] target/arm: Revise decoding for disas_add_sub_imm, Richard Henderson, 2020/06/23
- [PATCH v8 11/45] target/arm: Implement the ADDG, SUBG instructions, Richard Henderson, 2020/06/23
- [PATCH v8 12/45] target/arm: Implement the GMI instruction, Richard Henderson, 2020/06/23
- [PATCH v8 13/45] target/arm: Implement the SUBP instruction, Richard Henderson, 2020/06/23
- [PATCH v8 14/45] target/arm: Define arm_cpu_do_unaligned_access for user-only, Richard Henderson, 2020/06/23
- [PATCH v8 16/45] target/arm: Implement the STGP instruction, Richard Henderson, 2020/06/23