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 <brookmangabriel@gmail.com>
---
target/arm/internals.h | 5 ++++-
target/arm/tcg/pauth_helper.c | 14 +++++++++++++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 2c4369cc16..71d8b419e2 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1820,7 +1820,10 @@ 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 */
+ return mask & ~(-(uint64_t)param.mtx & MAKE_64BIT_MASK(56, 4));
}
/* 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..08dd230614 100644
--- a/target/arm/tcg/pauth_helper.c
+++ b/target/arm/tcg/pauth_helper.c
@@ -342,9 +342,12 @@ 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 (param.mtx && !param.tbi) {
+ ext_ptr = deposit64(ext_ptr, 60, 4, ext);
+ }
pac = pauth_computepac(env, ext_ptr, modifier, *key);
@@ -377,6 +380,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 +432,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.52.0