As described in the section on MTX, tag bits should not be used to store or compute the PAC when MTX is set. See also Authenticate(), InsertPAC(), and Strip().
Signed-off-by: Gabriel Brookman <[email protected]> Reviewed-by: Richard Henderson <[email protected]> --- target/arm/internals.h | 12 +++++++++++- target/arm/tcg/pauth_helper.c | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index d313d36603..31b7e1c85e 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1809,7 +1809,17 @@ static inline uint64_t pauth_ptr_mask(ARMVAParameters param) int bot_pac_bit = 64 - param.tsz; int top_pac_bit = 64 - 8 * param.tbi; - return MAKE_64BIT_MASK(bot_pac_bit, top_pac_bit - bot_pac_bit); + uint64_t mask = MAKE_64BIT_MASK(bot_pac_bit, top_pac_bit - bot_pac_bit); + + /* + * If mtx is enabled, second nibble is not part of PAC. See + * InsertPAC(). + */ + if (param.mtx) { + mask &= ~MAKE_64BIT_MASK(56, 4); + } + + return mask; } /* Add the cpreg definitions for debug related system registers */ diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c index 67c0d59d9e..3d83ca4c3c 100644 --- a/target/arm/tcg/pauth_helper.c +++ b/target/arm/tcg/pauth_helper.c @@ -342,9 +342,16 @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier, } /* Build a pointer with known good extension bits. */ - top_bit = 64 - 8 * param.tbi; + top_bit = 64 - 8 * (param.tbi || param.mtx); bot_bit = 64 - param.tsz; ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext); + /* + * If mtx is active but not tbi, then the top 4 bits are replaced with the + * ext bit, while leaving bits 56-59 alone. See InsertPAC(). + */ + if (param.mtx && !param.tbi) { + ext_ptr = deposit64(ext_ptr, 60, 4, ext); + } pac = pauth_computepac(env, ext_ptr, modifier, *key); @@ -377,6 +384,11 @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier, if (param.tbi) { ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1); pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1); + } else if (param.mtx) { + ptr &= ~(MAKE_64BIT_MASK(60, 4) | + MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1)); + pac &= MAKE_64BIT_MASK(60, 4) | + MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1); } else { ptr &= MAKE_64BIT_MASK(0, bot_bit); pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit)); @@ -424,6 +436,10 @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier, cmp_mask = MAKE_64BIT_MASK(bot_bit, top_bit - bot_bit); cmp_mask &= ~MAKE_64BIT_MASK(55, 1); + if (param.mtx) { + cmp_mask &= ~MAKE_64BIT_MASK(56, 4); + } + if (pauth_feature >= PauthFeat_2) { ARMPauthFeature fault_feature = is_combined ? PauthFeat_FPACCOMBINED : PauthFeat_FPAC; -- 2.54.0
