aboutsummaryrefslogtreecommitdiff
path: root/target/arm/tcg
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-06-06 10:19:38 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-06-06 10:19:38 +0100
commit523da6b963455ce0a0e8d572d98d9cd91f952785 (patch)
tree4b95da865b533ed03dd841baa32d61fef17fb1ed /target/arm/tcg
parent3b97520c86e704b0533627c26b98173b71834bad (diff)
downloadqemu-523da6b963455ce0a0e8d572d98d9cd91f952785.zip
qemu-523da6b963455ce0a0e8d572d98d9cd91f952785.tar.gz
qemu-523da6b963455ce0a0e8d572d98d9cd91f952785.tar.bz2
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>
Diffstat (limited to 'target/arm/tcg')
-rw-r--r--target/arm/tcg/mte_helper.c18
-rw-r--r--target/arm/tcg/translate-a64.c2
2 files changed, 20 insertions, 0 deletions
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
index a4f3f92..9c64def 100644
--- a/target/arm/tcg/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
@@ -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)
{
+ /*
+ * 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());
}
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 0b60069..77073a9 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -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, TCMA, s->tcma);
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);
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, TCMA, s->tcma);
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);
ret = tcg_temp_new_i64();