@samitouri / QOSamiQemu / commits / 46100e93c6

target/arm: skip tag bit bounds check if MTX is on

Virtual address canonicity checks should ignore mismatch in tag bits during translation step if MTX is set. This mismatch is checked during the tag check instead, in that case. Signed-off-by: Gabriel Brookman <brookmangabriel@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260529-feat-mte4-v7-11-ccbd3c14eb3c@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Gabriel Brookman committed May 29, 2026 at 12:52 UTC 46100e93c62e474c3f1e93a4fc0d2c723f1756d0
3 files changed +36 -6
target/arm/helper.c
+5 -1
@@ -9795,7 +9795,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
9795 {
9796 uint64_t tcr = regime_tcr(env, mmu_idx);
9797 bool epd, hpd, tsz_oob, ds, ha, hd, pie = false;
9798 - bool aie = false;
9798 + bool mtx, aie = false;
9799 int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
9800 ARMGranuleSize gran;
9801 ARMCPU *cpu = env_archcpu(env);
@@ -9832,6 +9832,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
9832 ha = extract32(tcr, 21, 1) && cpu_isar_feature(aa64_hafs, cpu);
9833 hd = extract32(tcr, 22, 1) && cpu_isar_feature(aa64_hdbs, cpu);
9834 ds = extract64(tcr, 32, 1);
9835 + mtx = extract64(tcr, 33, 1) && cpu_isar_feature(aa64_mte_mtx, cpu);
9836 } else {
9837 bool e0pd;
9838
@@ -9847,6 +9848,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
9848 sh = extract32(tcr, 12, 2);
9849 hpd = extract64(tcr, 41, 1);
9850 e0pd = extract64(tcr, 55, 1);
9851 + mtx = extract64(tcr, 60, 1) && cpu_isar_feature(aa64_mte_mtx, cpu);
9852 } else {
9853 tsz = extract32(tcr, 16, 6);
9854 gran = tg1_to_gran_size(extract32(tcr, 30, 2));
@@ -9854,6 +9856,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
9856 sh = extract32(tcr, 28, 2);
9857 hpd = extract64(tcr, 42, 1);
9858 e0pd = extract64(tcr, 56, 1);
9859 + mtx = extract64(tcr, 61, 1) && cpu_isar_feature(aa64_mte_mtx, cpu);
9860 }
9861 ps = extract64(tcr, 32, 3);
9862 ha = extract64(tcr, 39, 1) && cpu_isar_feature(aa64_hafs, cpu);
@@ -9953,6 +9956,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
9956 .gran = gran,
9957 .pie = pie,
9958 .aie = aie,
9959 + .mtx = mtx,
9960 };
9961 }
9962
target/arm/internals.h
+1
@@ -1430,6 +1430,7 @@ typedef struct ARMVAParameters {
1430 ARMGranuleSize gran : 2;
1431 bool pie : 1;
1432 bool aie : 1;
1433 + bool mtx : 1;
1434 } ARMVAParameters;
1435
1436 /**
target/arm/ptw.c
+30 -5
@@ -1951,9 +1951,18 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
1951 * validation to do here.
1952 */
1953 if (inputsize < addrsize) {
1954 - uint64_t top_bits = sextract64(address, inputsize,
1955 - addrsize - inputsize);
1956 - if (-top_bits != param.select) {
1954 + /*
1955 + * If MTX is enabled, bits 56-59 aren't checked for canonicity
1956 + * during translation, since they will later be checked during
1957 + * the tag check step.
1958 + */
1959 +
1960 + uint64_t cmp_mask = MAKE_64BIT_MASK(inputsize, addrsize - inputsize);
1961 +
1962 + if (param.mtx) {
1963 + cmp_mask &= ~MAKE_64BIT_MASK(56, 4);
1964 + }
1965 + if ((address ^ -param.select) & cmp_mask) {
1966 /* The gap between the two regions is a Translation fault */
1967 goto do_translation_fault;
1968 }
@@ -3514,15 +3523,31 @@ static bool get_phys_addr_disabled(CPUARMState *env,
3523 int pamax = arm_pamax(env_archcpu(env));
3524 uint64_t tcr = env->cp15.tcr_el[r_el];
3525 int addrtop, tbi;
3526 + bool bit55;
3527
3528 tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
3529 if (access_type == MMU_INST_FETCH) {
3530 tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
3531 }
3522 - tbi = (tbi >> extract64(address, 55, 1)) & 1;
3532 + bit55 = extract64(address, 55, 1);
3533 + tbi = (tbi >> bit55) & 1;
3534 addrtop = (tbi ? 55 : 63);
3535
3525 - if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
3536 + /*
3537 + * With MTX enabled, bits 56-59 are not checked according to
3538 + * AArch64.S1DisabledOutput.
3539 + */
3540 + uint64_t cmp_mask = MAKE_64BIT_MASK(pamax, addrtop - pamax + 1);
3541 +
3542 + if (access_type != MMU_INST_FETCH &&
3543 + cpu_isar_feature(aa64_mte_mtx, env_archcpu(env))) {
3544 + int mtx = aa64_va_parameter_mtx(tcr, mmu_idx);
3545 + if (mtx & (1 << bit55)) {
3546 + cmp_mask &= ~MAKE_64BIT_MASK(56, 4);
3547 + }
3548 + }
3549 +
3550 + if (address & cmp_mask) {
3551 fi->type = ARMFault_AddressSize;
3552 fi->level = 0;
3553 fi->stage2 = false;