mirror of https://github.com/xemu-project/xemu.git
target/arm: Check alignment in helper_mte_check
Fixes a bug in that with SCTLR.A set, we should raise any alignment fault before raising any MTE check fault. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230530191438.411344-15-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
3b97520c86
commit
523da6b963
|
@ -1242,7 +1242,8 @@ FIELD(MTEDESC, MIDX, 0, 4)
|
||||||
FIELD(MTEDESC, TBI, 4, 2)
|
FIELD(MTEDESC, TBI, 4, 2)
|
||||||
FIELD(MTEDESC, TCMA, 6, 2)
|
FIELD(MTEDESC, TCMA, 6, 2)
|
||||||
FIELD(MTEDESC, WRITE, 8, 1)
|
FIELD(MTEDESC, WRITE, 8, 1)
|
||||||
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
|
FIELD(MTEDESC, ALIGN, 9, 3)
|
||||||
|
FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
|
||||||
|
|
||||||
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
|
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
|
||||||
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
|
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
|
||||||
|
|
|
@ -785,6 +785,24 @@ uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra)
|
||||||
|
|
||||||
uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
|
uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* R_XCHFJ: Alignment check not caused by memory type is priority 1,
|
||||||
|
* higher than any translation fault. When MTE is disabled, tcg
|
||||||
|
* performs the alignment check during the code generated for the
|
||||||
|
* memory access. With MTE enabled, we must check this here before
|
||||||
|
* raising any translation fault in allocation_tag_mem.
|
||||||
|
*/
|
||||||
|
unsigned align = FIELD_EX32(desc, MTEDESC, ALIGN);
|
||||||
|
if (unlikely(align)) {
|
||||||
|
align = (1u << align) - 1;
|
||||||
|
if (unlikely(ptr & align)) {
|
||||||
|
int idx = FIELD_EX32(desc, MTEDESC, MIDX);
|
||||||
|
bool w = FIELD_EX32(desc, MTEDESC, WRITE);
|
||||||
|
MMUAccessType type = w ? MMU_DATA_STORE : MMU_DATA_LOAD;
|
||||||
|
arm_cpu_do_unaligned_access(env_cpu(env), ptr, type, idx, GETPC());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mte_check(env, desc, ptr, GETPC());
|
return mte_check(env, desc, ptr, GETPC());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,7 @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
|
||||||
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
|
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
|
||||||
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
|
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
|
||||||
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
|
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
|
||||||
|
desc = FIELD_DP32(desc, MTEDESC, ALIGN, get_alignment_bits(memop));
|
||||||
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, memop_size(memop) - 1);
|
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, memop_size(memop) - 1);
|
||||||
|
|
||||||
ret = tcg_temp_new_i64();
|
ret = tcg_temp_new_i64();
|
||||||
|
@ -295,6 +296,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
|
||||||
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
|
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
|
||||||
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
|
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
|
||||||
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
|
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
|
||||||
|
desc = FIELD_DP32(desc, MTEDESC, ALIGN, get_alignment_bits(single_mop));
|
||||||
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
|
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
|
||||||
|
|
||||||
ret = tcg_temp_new_i64();
|
ret = tcg_temp_new_i64();
|
||||||
|
|
Loading…
Reference in New Issue