@samitouri / QOSamiQemu / commits / 1f8aa4b6af

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 }