mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-10 11:04:58 -06:00
target/arm: Implement the HFGITR_EL2.ERET trap
Implement the HFGITR_EL2.ERET fine-grained trap. This traps execution from AArch64 EL1 of ERET, ERETAA and ERETAB. The trap is reported with a syndrome value of 0x1a. The trap must take precedence over a possible pointer-authentication trap for ERETAA and ERETAB. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Fuad Tabba <tabba@google.com> Message-id: 20230130182459.3309057-21-peter.maydell@linaro.org Message-id: 20230127175507.2895013-21-peter.maydell@linaro.org
This commit is contained in:
parent
950037e280
commit
5572f7557f
5 changed files with 26 additions and 0 deletions
|
@ -3245,6 +3245,7 @@ FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
|
||||||
FIELD(TBFLAG_A64, SVL, 24, 4)
|
FIELD(TBFLAG_A64, SVL, 24, 4)
|
||||||
/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
|
/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
|
||||||
FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
|
FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
|
||||||
|
FIELD(TBFLAG_A64, FGT_ERET, 29, 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers for using the above.
|
* Helpers for using the above.
|
||||||
|
|
|
@ -12065,6 +12065,9 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
|
||||||
|
|
||||||
if (arm_fgt_active(env, el)) {
|
if (arm_fgt_active(env, el)) {
|
||||||
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
|
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
|
||||||
|
if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
|
||||||
|
DP_TBFLAG_A64(flags, FGT_ERET, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
|
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
|
||||||
|
|
|
@ -48,6 +48,7 @@ enum arm_exception_class {
|
||||||
EC_AA64_SMC = 0x17,
|
EC_AA64_SMC = 0x17,
|
||||||
EC_SYSTEMREGISTERTRAP = 0x18,
|
EC_SYSTEMREGISTERTRAP = 0x18,
|
||||||
EC_SVEACCESSTRAP = 0x19,
|
EC_SVEACCESSTRAP = 0x19,
|
||||||
|
EC_ERETTRAP = 0x1a,
|
||||||
EC_SMETRAP = 0x1d,
|
EC_SMETRAP = 0x1d,
|
||||||
EC_INSNABORT = 0x20,
|
EC_INSNABORT = 0x20,
|
||||||
EC_INSNABORT_SAME_EL = 0x21,
|
EC_INSNABORT_SAME_EL = 0x21,
|
||||||
|
@ -215,6 +216,15 @@ static inline uint32_t syn_sve_access_trap(void)
|
||||||
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
|
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* eret_op is bits [1:0] of the ERET instruction, so:
|
||||||
|
* 0 for ERET, 2 for ERETAA, 3 for ERETAB.
|
||||||
|
*/
|
||||||
|
static inline uint32_t syn_erettrap(int eret_op)
|
||||||
|
{
|
||||||
|
return (EC_ERETTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL | eret_op;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
|
static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
|
||||||
{
|
{
|
||||||
return (EC_SMETRAP << ARM_EL_EC_SHIFT)
|
return (EC_SMETRAP << ARM_EL_EC_SHIFT)
|
||||||
|
|
|
@ -2385,6 +2385,10 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
if (op4 != 0) {
|
if (op4 != 0) {
|
||||||
goto do_unallocated;
|
goto do_unallocated;
|
||||||
}
|
}
|
||||||
|
if (s->fgt_eret) {
|
||||||
|
gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
dst = tcg_temp_new_i64();
|
dst = tcg_temp_new_i64();
|
||||||
tcg_gen_ld_i64(dst, cpu_env,
|
tcg_gen_ld_i64(dst, cpu_env,
|
||||||
offsetof(CPUARMState, elr_el[s->current_el]));
|
offsetof(CPUARMState, elr_el[s->current_el]));
|
||||||
|
@ -2398,6 +2402,11 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
if (rn != 0x1f || op4 != 0x1f) {
|
if (rn != 0x1f || op4 != 0x1f) {
|
||||||
goto do_unallocated;
|
goto do_unallocated;
|
||||||
}
|
}
|
||||||
|
/* The FGT trap takes precedence over an auth trap. */
|
||||||
|
if (s->fgt_eret) {
|
||||||
|
gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
dst = tcg_temp_new_i64();
|
dst = tcg_temp_new_i64();
|
||||||
tcg_gen_ld_i64(dst, cpu_env,
|
tcg_gen_ld_i64(dst, cpu_env,
|
||||||
offsetof(CPUARMState, elr_el[s->current_el]));
|
offsetof(CPUARMState, elr_el[s->current_el]));
|
||||||
|
@ -14742,6 +14751,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
|
||||||
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
|
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
|
||||||
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
|
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
|
||||||
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
|
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
|
||||||
|
dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
|
||||||
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
|
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
|
||||||
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
|
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
|
||||||
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
|
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
|
||||||
|
|
|
@ -132,6 +132,8 @@ typedef struct DisasContext {
|
||||||
bool mve_no_pred;
|
bool mve_no_pred;
|
||||||
/* True if fine-grained traps are active */
|
/* True if fine-grained traps are active */
|
||||||
bool fgt_active;
|
bool fgt_active;
|
||||||
|
/* True if fine-grained trap on ERET is enabled */
|
||||||
|
bool fgt_eret;
|
||||||
/*
|
/*
|
||||||
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
|
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
|
||||||
* < 0, set by the current instruction.
|
* < 0, set by the current instruction.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue