Signed-off-by: Richard Henderson richard.henderson@linaro.org --- target/arm/cpu.h | 2 ++ target/arm/translate.h | 4 ++++ target/arm/helper.c | 22 +++++++++++++++------- target/arm/translate-a64.c | 2 ++ 4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 6211e21046..f2d8bf357c 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2989,6 +2989,8 @@ FIELD(TBFLAG_A64, TBI1, 1, 1) FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2) FIELD(TBFLAG_A64, ZCR_LEN, 4, 4) FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1) +FIELD(TBFLAG_A64, BT, 9, 1) +FIELD(TBFLAG_A64, BTYPE, 10, 2)
static inline bool bswap_code(bool sctlr_b) { diff --git a/target/arm/translate.h b/target/arm/translate.h index d8a8bb4e9c..aa59888393 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -70,6 +70,10 @@ typedef struct DisasContext { bool ss_same_el; /* True if v8.3-PAuth is active. */ 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; /* 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/helper.c b/target/arm/helper.c index 4bf2db2cc4..e23d31edee 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -13073,6 +13073,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;
*pc = env->pc; flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1); @@ -13109,6 +13110,12 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len); }
+ if (current_el == 0) { + /* FIXME: ARMv8.1-VHE S2 translation regime. */ + sctlr = env->cp15.sctlr_el[1]; + } else { + sctlr = env->cp15.sctlr_el[current_el]; + } if (cpu_isar_feature(aa64_pauth, cpu)) { /* * In order to save space in flags, we record only whether @@ -13116,17 +13123,18 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, * a nop, or "active" when some action must be performed. * The decision of which action to take is left to a helper. */ - uint64_t sctlr; - if (current_el == 0) { - /* FIXME: ARMv8.1-VHE S2 translation regime. */ - sctlr = env->cp15.sctlr_el[1]; - } else { - sctlr = env->cp15.sctlr_el[current_el]; - } if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) { flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1); } } + + if (cpu_isar_feature(aa64_bti, cpu)) { + /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */ + if (sctlr & (current_el == 0 ? SCTLR_BT0 : SCTLR_BT1)) { + flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1); + } + flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype); + } } 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 8a6c597362..dbe2ed7565 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -13802,6 +13802,8 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase, dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL); dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16; 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->vec_len = 0; dc->vec_stride = 0; dc->cp_regs = arm_cpu->cp_regs;