target/arm: Fix testing of raw mtx value
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> Message-id: 20260717161430.37264-1-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Richard Henderson committed
Jul 20, 2026 at 19:05 UTC
1f8aa4b6af88e2df4792b9a22782a6b0435b864e
1 file changed
+17
-8
target/arm/tcg/mte_helper.c
+17
-8
@@ -317,6 +317,12 @@ int load_tag1(uint64_t ptr, uint8_t *mem)
317
return extract32(*mem, ofs, 4);
318
}
319
320
+/* Like mtx_check, but simple mtx bit pair instead of MTEDESC. */
321
+static bool raw_mtx_check(unsigned mtx, unsigned bit55)
322
+{
323
+ return (mtx >> bit55) & 1;
324
+}
325
+
326
uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt, uint32_t mtx)
327
{
328
int mmu_idx = arm_env_mmu_index(env);
@@ -330,9 +336,11 @@ uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt, uint32_t mtx)
336
/* Load if page supports tags. */
337
if (mem) {
338
rtag = load_tag1(ptr, mem);
333
- } else if (mtx) {
334
- uint64_t bit55 = extract64(ptr, 55, 1);
335
- rtag = 0xF * bit55;
339
+ } else {
340
+ bool bit55 = extract64(ptr, 55, 1);
341
+ if (raw_mtx_check(mtx, bit55)) {
342
+ rtag = 0xF * bit55;
343
+ }
344
}
345
346
return address_with_allocation_tag(xt, rtag);
@@ -387,7 +395,7 @@ static inline void do_stg(CPUARMState *env, uint64_t ptr, uint64_t xt,
395
/* Store if page supports tags. */
396
if (mem) {
397
store1(ptr, mem, allocation_tag_from_addr(xt));
390
- } else if (mtx) {
398
+ } else if (raw_mtx_check(mtx, extract64(ptr, 55, 1))) {
399
canonical_tag_write_fail(env, ptr, ra);
400
}
401
}
@@ -420,6 +428,7 @@ static inline void do_st2g(CPUARMState *env, uint64_t ptr, uint64_t xt,
428
uint8_t *mem1, *mem2;
429
430
check_tag_aligned(env, ptr, ra);
431
+ mtx = raw_mtx_check(mtx, extract64(ptr, 55, 1));
432
433
/*
434
* Trap if accessing an invalid page(s).
@@ -504,8 +513,8 @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr, uint32_t mtx)
513
/* The tag is squashed to zero if the page does not support tags. */
514
if (!tag_mem) {
515
/* Load canonical value if mtx is set (untagged memory region) */
507
- if (mtx) {
508
- bool bit55 = extract64(ptr, 55, 1);
516
+ bool bit55 = extract64(ptr, 55, 1);
517
+ if (raw_mtx_check(mtx, bit55)) {
518
ret = extract64(-bit55, 0, 1 << gm_bs);
519
shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4;
520
return ret << shift;
@@ -573,7 +582,7 @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val, uint32_t mtx)
582
*/
583
if (!tag_mem) {
584
/* Storing tags to canonically tagged region: fault. */
576
- if (mtx) {
585
+ if (raw_mtx_check(mtx, extract64(ptr, 55, 1))) {
586
canonical_tag_write_fail(env, ptr, ra);
587
}
588
return;
@@ -630,7 +639,7 @@ void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val,
639
if (mem) {
640
int tag_pair = (val & 0xf) * 0x11;
641
memset(mem, tag_pair, tag_bytes);
633
- } else if (mtx) {
642
+ } else if (raw_mtx_check(mtx, extract64(ptr, 55, 1))) {
643
canonical_tag_write_fail(env, ptr, ra);
644
}
645
}