[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [PATCH v3 04/28] target/arm: Add MTE_ACTIVE to tb_flags
From: |
Richard Henderson |
Subject: |
[Qemu-arm] [PATCH v3 04/28] target/arm: Add MTE_ACTIVE to tb_flags |
Date: |
Mon, 11 Feb 2019 15:52:34 -0800 |
When MTE is fully enabled, i.e. access to tags are enabled and
tag checks affect the PE, then arrange to perform the check
while stripping the TBI.
The check is not yet implemented, just the plumbing to that point.
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
v2: Clean TBI bits exactly.
Fix license to lgpl 2.1.
v3: Remove stub helper_mte_check; moved to a later patch.
---
target/arm/cpu.h | 12 +++++++++
target/arm/internals.h | 18 ++++++++++++++
target/arm/translate.h | 2 ++
target/arm/helper.c | 51 ++++++++++++++++++++++++++++++--------
target/arm/translate-a64.c | 1 +
5 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 20be9fb53a..2776df6981 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1215,6 +1215,7 @@ void pmu_init(ARMCPU *cpu);
#define PSTATE_BTYPE (3U << 10)
#define PSTATE_IL (1U << 20)
#define PSTATE_SS (1U << 21)
+#define PSTATE_TCO (1U << 25)
#define PSTATE_V (1U << 28)
#define PSTATE_C (1U << 29)
#define PSTATE_Z (1U << 30)
@@ -3071,6 +3072,7 @@ FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
FIELD(TBFLAG_A64, BT, 9, 1)
FIELD(TBFLAG_A64, BTYPE, 10, 2)
FIELD(TBFLAG_A64, TBID, 12, 2)
+FIELD(TBFLAG_A64, MTE_ACTIVE, 14, 1)
static inline bool bswap_code(bool sctlr_b)
{
@@ -3361,6 +3363,16 @@ static inline bool isar_feature_aa64_bti(const
ARMISARegisters *id)
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
}
+static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
+}
+
+static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
+}
+
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 587a1ddf58..6c018e773c 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -983,4 +983,22 @@ 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;
+}
+
#endif
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 33af50a13f..5a101e1c6d 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -70,6 +70,8 @@ typedef struct DisasContext {
bool ss_same_el;
/* True if v8.3-PAuth is active. */
bool pauth_active;
+ /* True if v8.5-MTE tag checks affect the PE. */
+ bool mte_active;
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
bool bt;
/*
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d4abbb5076..e73bdbf041 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1862,6 +1862,9 @@ static void scr_write(CPUARMState *env, const
ARMCPRegInfo *ri, uint64_t value)
if (cpu_isar_feature(aa64_pauth, cpu)) {
valid_mask |= SCR_API | SCR_APK;
}
+ if (cpu_isar_feature(aa64_mte, cpu)) {
+ valid_mask |= SCR_ATA;
+ }
/* Clear all-context RES0 bits. */
value &= valid_mask;
@@ -4056,22 +4059,31 @@ static void sctlr_write(CPUARMState *env, const
ARMCPRegInfo *ri,
{
ARMCPU *cpu = arm_env_get_cpu(env);
- if (raw_read(env, ri) == value) {
- /* Skip the TLB flush if nothing actually changed; Linux likes
- * to do a lot of pointless SCTLR writes.
- */
- return;
- }
-
if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
/* M bit is RAZ/WI for PMSA with no MPU implemented */
value &= ~SCTLR_M;
}
- raw_write(env, ri, value);
+ if (!cpu_isar_feature(aa64_mte, cpu)) {
+ if (ri->opc1 == 6) { /* SCTLR_EL3 */
+ value &= ~(SCTLR_ITFSB | SCTLR_TCF | SCTLR_ATA);
+ } else {
+ value &= ~(SCTLR_ITFSB | SCTLR_TCF0 | SCTLR_TCF |
+ SCTLR_ATA0 | SCTLR_ATA);
+ }
+ }
+
/* ??? Lots of these bits are not implemented. */
- /* This may enable/disable the MMU, so do a TLB flush. */
- tlb_flush(CPU(cpu));
+
+ if (raw_read(env, ri) != value) {
+ /*
+ * This may enable/disable the MMU, so do a TLB flush.
+ * Skip the TLB flush if nothing actually changed;
+ * Linux likes to do a lot of pointless SCTLR writes.
+ */
+ raw_write(env, ri, value);
+ tlb_flush(CPU(cpu));
+ }
}
static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -4564,6 +4576,9 @@ static void hcr_write(CPUARMState *env, const
ARMCPRegInfo *ri, uint64_t value)
if (cpu_isar_feature(aa64_pauth, cpu)) {
valid_mask |= HCR_API | HCR_APK;
}
+ if (cpu_isar_feature(aa64_mte, cpu)) {
+ valid_mask |= HCR_ATA;
+ }
/* Clear RES0 bits. */
value &= valid_mask;
@@ -13756,6 +13771,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env,
target_ulong *pc,
if (is_a64(env)) {
ARMCPU *cpu = arm_env_get_cpu(env);
uint64_t sctlr;
+ int tbid;
*pc = env->pc;
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
@@ -13764,7 +13780,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env,
target_ulong *pc,
{
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
- int tbii, tbid;
+ int tbii;
/* FIXME: ARMv8.1-VHE S2 translation regime. */
if (regime_el(env, stage1) < 2) {
@@ -13817,6 +13833,19 @@ void cpu_get_tb_cpu_state(CPUARMState *env,
target_ulong *pc,
}
flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
}
+
+ /*
+ * If MTE is enabled, and tag checks affect the PE,
+ * then we check the tag as we strip the TBI field.
+ * Note that if TBI is disabled, all accesses are unchecked.
+ */
+ if (tbid
+ && cpu_isar_feature(aa64_mte, cpu)
+ && allocation_tag_access_enabled(env, current_el, sctlr)
+ && !(env->pstate & PSTATE_TCO)
+ && (sctlr & (current_el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
+ flags = FIELD_DP32(flags, TBFLAG_A64, MTE_ACTIVE, 1);
+ }
} else {
*pc = env->regs[15];
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index ba139bba26..3950067b79 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14041,6 +14041,7 @@ static void
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
dc->bt = FIELD_EX32(tb_flags, TBFLAG_A64, BT);
dc->btype = FIELD_EX32(tb_flags, TBFLAG_A64, BTYPE);
+ dc->mte_active = FIELD_EX32(tb_flags, TBFLAG_A64, MTE_ACTIVE);
dc->vec_len = 0;
dc->vec_stride = 0;
dc->cp_regs = arm_cpu->cp_regs;
--
2.17.2
- [Qemu-arm] [PATCH v3 00/28] target/arm: Implement ARMv8.5-MemTag, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 01/28] target/arm: Split out arm_sctlr, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 02/28] target/arm: Split helper_msr_i_pstate into 3, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 03/28] target/arm: Add clear_pstate_bits, share gen_ss_advance, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 04/28] target/arm: Add MTE_ACTIVE to tb_flags,
Richard Henderson <=
- [Qemu-arm] [PATCH v3 05/28] target/arm: Extract TCMA with ARMVAParameters, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 10/28] target/arm: Implement the IRG instruction, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 18/28] target/arm: Implement the access tag cache flushes, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 14/28] target/arm: Define arm_cpu_do_unaligned_access for CONFIG_USER_ONLY, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 06/28] target/arm: Add MTE system registers, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 20/28] target/arm: Implement data cache set allocation tags, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 12/28] target/arm: Implement the GMI instruction, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 13/28] target/arm: Implement the SUBP instruction, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 07/28] target/arm: Assert no manual change to CACHED_PSTATE_BITS, Richard Henderson, 2019/02/11
- [Qemu-arm] [PATCH v3 21/28] target/arm: Set PSTATE.TCO on exception entry, Richard Henderson, 2019/02/11