target/arm/tcg/mte_helper.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
MTX is always a pair of bits, one for each half of the address space.
Testing it like a boolean is incorrect.
Introduce raw_mte_check, a mirror of the similar mte_check function
that applies when MTX is passed in MTEDESC.
Fixes: 8912ceced815 ("target/arm: load on canonical tag loads ext bits")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/tcg/mte_helper.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
index 04c637a9e2..616c395cb3 100644
--- a/target/arm/tcg/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
@@ -374,6 +374,12 @@ int load_tag1(uint64_t ptr, uint8_t *mem)
return extract32(*mem, ofs, 4);
}
+/* Like mtx_check, but simple mtx bit pair instead of MTEDESC. */
+static bool raw_mtx_check(unsigned mtx, unsigned bit55)
+{
+ return (mtx >> bit55) & 1;
+}
+
uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt, uint32_t mtx)
{
int mmu_idx = arm_env_mmu_index(env);
@@ -387,9 +393,11 @@ uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt, uint32_t mtx)
/* Load if page supports tags. */
if (mem) {
rtag = load_tag1(ptr, mem);
- } else if (mtx) {
- uint64_t bit55 = extract64(ptr, 55, 1);
- rtag = 0xF * bit55;
+ } else {
+ bool bit55 = extract64(ptr, 55, 1);
+ if (raw_mtx_check(mtx, bit55)) {
+ rtag = 0xF * bit55;
+ }
}
return address_with_allocation_tag(xt, rtag);
@@ -444,7 +452,7 @@ static inline void do_stg(CPUARMState *env, uint64_t ptr, uint64_t xt,
/* Store if page supports tags. */
if (mem) {
store1(ptr, mem, allocation_tag_from_addr(xt));
- } else if (mtx) {
+ } else if (raw_mtx_check(mtx, extract64(ptr, 55, 1))) {
canonical_tag_write_fail(env, ptr, ra);
}
}
@@ -477,6 +485,7 @@ static inline void do_st2g(CPUARMState *env, uint64_t ptr, uint64_t xt,
uint8_t *mem1, *mem2;
check_tag_aligned(env, ptr, ra);
+ mtx = raw_mtx_check(mtx, extract64(ptr, 55, 1));
/*
* Trap if accessing an invalid page(s).
@@ -561,8 +570,8 @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr, uint32_t mtx)
/* The tag is squashed to zero if the page does not support tags. */
if (!tag_mem) {
/* Load canonical value if mtx is set (untagged memory region) */
- if (mtx) {
- bool bit55 = extract64(ptr, 55, 1);
+ bool bit55 = extract64(ptr, 55, 1);
+ if (raw_mtx_check(mtx, bit55)) {
ret = extract64(-bit55, 0, 1 << gm_bs);
shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4;
return ret << shift;
@@ -630,7 +639,7 @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val, uint32_t mtx)
*/
if (!tag_mem) {
/* Storing tags to canonically tagged region: fault. */
- if (mtx) {
+ if (raw_mtx_check(mtx, extract64(ptr, 55, 1))) {
canonical_tag_write_fail(env, ptr, ra);
}
return;
@@ -687,7 +696,7 @@ void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val,
if (mem) {
int tag_pair = (val & 0xf) * 0x11;
memset(mem, tag_pair, tag_bytes);
- } else if (mtx) {
+ } else if (raw_mtx_check(mtx, extract64(ptr, 55, 1))) {
canonical_tag_write_fail(env, ptr, ra);
}
}
--
2.43.0
On 18/7/26 01:22, Richard Henderson wrote:
> MTX is always a pair of bits, one for each half of the address space.
> Testing it like a boolean is incorrect.
>
> Introduce raw_mte_check, a mirror of the similar mte_check function
> that applies when MTX is passed in MTEDESC.
>
> Fixes: 8912ceced815 ("target/arm: load on canonical tag loads ext bits")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/tcg/mte_helper.c | 25 +++++++++++++++++--------
> 1 file changed, 17 insertions(+), 8 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
© 2016 - 2026 Red Hat, Inc.