According to ARM ARM, section "Memory Tagging Region Types", loading tags from canonically tagged regions should use the canonical tags, not allocation tags.
Signed-off-by: Gabriel Brookman <[email protected]> --- target/arm/tcg/mte_helper.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c index 513ee8d6a1..ddb68e11fc 100644 --- a/target/arm/tcg/mte_helper.c +++ b/target/arm/tcg/mte_helper.c @@ -279,9 +279,14 @@ uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt) mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_LOAD, 1, MMU_DATA_LOAD, GETPC()); - /* Load if page supports tags. */ + /* Load if page supports tags. Set to canonical value if MTX is set. */ if (mem) { - rtag = load_tag1(ptr, mem); + uint64_t bit55 = extract64(ptr, 55, 1); + if (mtx_check(env, bit55)) { + rtag = 0xF * bit55; + } else { + rtag = load_tag1(ptr, mem); + } } return address_with_allocation_tag(xt, rtag); @@ -444,6 +449,11 @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr) return 0; } + if (mtx_check(env, extract64(ptr, 55, 1))) { + shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4; + return (~0) << shift; + } + /* * The ordering of elements within the word corresponds to * a little-endian operation. Computation of shift comes from -- 2.51.2
