* [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code
@ 2026-05-18 16:13 Torbjörn SVENSSON
2026-05-18 16:13 ` [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu Torbjörn SVENSSON
` (4 more replies)
0 siblings, 5 replies; 14+ messages in thread
From: Torbjörn SVENSSON @ 2026-05-18 16:13 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Torbjörn SVENSSON
Testing an arm-none-eabi GCC toolchain using QEMU gives unpredictable
test results for some test cases. In the GCC testsuite function
check_effective_target_arm_pacbti_hw, the testsuite tries to identify
if the target supports PACBTI instructions. The test consists of:
__attribute__ ((naked)) int
main (void)
{
asm ("pac r12, lr, sp");
asm ("mov r0, #0");
asm ("autg r12, lr, sp");
asm ("bx lr");
}
Running the above code in QEMU will cause LR to get corrupted.
The reson for the corruption is that AUTG overlaps with the SMMLA
instruction, and SMMLA will write the result to Rn, that for
`AUTG R12, LR, SP` happens to match `LR`.
The solution to the above problem is to define the following new
Cortex-M instructions in QEMU:
* AUT
* AUTG
* BXAUT
* PAC
* PACBTI
* PACG
This patch series only implements the pointer authentication code part
of PACBTI. The branch target identification part is not implemented.
Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
---
Torbjörn SVENSSON (3):
target/arm/tcg: define cortex-m85 cpu
target/arm/tcg: add PAC related instructions
target/arm: implement v8.1-m PAC support
target/arm/cpu-features.h | 6 ++
target/arm/internals.h | 2 +
target/arm/tcg/cpu-v7m.c | 40 +++++++++++++
target/arm/tcg/m_helper.c | 17 ++++++
target/arm/tcg/t32.decode | 21 ++++++-
target/arm/tcg/translate.c | 138 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 221 insertions(+), 3 deletions(-)
---
base-commit: ac6721b88df944ade0048822b2b74210f543d656
change-id: 20260518-pr-pacbti-366d7acbe1be
Best regards,
--
Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu 2026-05-18 16:13 [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjörn SVENSSON @ 2026-05-18 16:13 ` Torbjörn SVENSSON 2026-05-27 13:21 ` Alex Bennée 2026-05-28 10:22 ` Peter Maydell 2026-05-18 16:14 ` [PATCH 2/3] target/arm/tcg: add PAC related instructions Torbjörn SVENSSON ` (3 subsequent siblings) 4 siblings, 2 replies; 14+ messages in thread From: Torbjörn SVENSSON @ 2026-05-18 16:13 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Torbjörn SVENSSON Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> --- target/arm/tcg/cpu-v7m.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c index dc249ce1f1..5cfda232cd 100644 --- a/target/arm/tcg/cpu-v7m.c +++ b/target/arm/tcg/cpu-v7m.c @@ -237,6 +237,44 @@ static void cortex_m55_initfn(Object *obj) cpu->ctr = 0x8303c003; } +static void cortex_m85_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; + + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_V8_1M); + set_feature(&cpu->env, ARM_FEATURE_M); + set_feature(&cpu->env, ARM_FEATURE_M_MAIN); + set_feature(&cpu->env, ARM_FEATURE_M_SECURITY); + set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); + cpu->midr = 0x411fd230; /* r1p0 */ + cpu->revidr = 0; + cpu->pmsav7_dregion = 16; + cpu->sau_sregion = 8; + /* These are the MVFR* values for the FPU + full MVE configuration */ + cpu->isar.mvfr0 = 0x10110221; + cpu->isar.mvfr1 = 0x12100211; + cpu->isar.mvfr2 = 0x00000040; + SET_IDREG(isar, ID_PFR0, 0x20000030); + SET_IDREG(isar, ID_PFR1, 0x00000230); + SET_IDREG(isar, ID_DFR0, 0x10200000); + SET_IDREG(isar, ID_AFR0, 0x00000000); + SET_IDREG(isar, ID_MMFR0, 0x00111040); + SET_IDREG(isar, ID_MMFR1, 0x00000000); + SET_IDREG(isar, ID_MMFR2, 0x01000000); + SET_IDREG(isar, ID_MMFR3, 0x00000011); + SET_IDREG(isar, ID_ISAR0, 0x01103110); + SET_IDREG(isar, ID_ISAR1, 0x02212000); + SET_IDREG(isar, ID_ISAR2, 0x20232232); + SET_IDREG(isar, ID_ISAR3, 0x01111131); + SET_IDREG(isar, ID_ISAR4, 0x01310132); + SET_IDREG(isar, ID_ISAR5, 0x00000000); + SET_IDREG(isar, ID_ISAR6, 0x00000000); + SET_IDREG(isar, CLIDR, 0x00000000); /* caches not implemented */ + cpu->ctr = 0x8303c003; +} + static const TCGCPUOps arm_v7m_tcg_ops = { /* ARM processors have a weak memory model */ .guest_default_memory_order = 0, @@ -290,6 +328,8 @@ static const ARMCPUInfo arm_v7m_cpus[] = { .class_init = arm_v7m_class_init }, { .name = "cortex-m55", .initfn = cortex_m55_initfn, .class_init = arm_v7m_class_init }, + { .name = "cortex-m85", .initfn = cortex_m85_initfn, + .class_init = arm_v7m_class_init }, }; static void arm_v7m_cpu_register_types(void) -- 2.43.0 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu 2026-05-18 16:13 ` [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu Torbjörn SVENSSON @ 2026-05-27 13:21 ` Alex Bennée 2026-05-28 10:22 ` Peter Maydell 1 sibling, 0 replies; 14+ messages in thread From: Alex Bennée @ 2026-05-27 13:21 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, Peter Maydell, qemu-arm Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> writes: Can you mention the TRM in the commit: https://developer.arm.com/documentation/101924/0100/ > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > --- > target/arm/tcg/cpu-v7m.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 40 insertions(+) > > diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c > index dc249ce1f1..5cfda232cd 100644 > --- a/target/arm/tcg/cpu-v7m.c > +++ b/target/arm/tcg/cpu-v7m.c > @@ -237,6 +237,44 @@ static void cortex_m55_initfn(Object *obj) > cpu->ctr = 0x8303c003; > } > > +static void cortex_m85_initfn(Object *obj) > +{ > + ARMCPU *cpu = ARM_CPU(obj); > + ARMISARegisters *isar = &cpu->isar; > + > + set_feature(&cpu->env, ARM_FEATURE_V8); > + set_feature(&cpu->env, ARM_FEATURE_V8_1M); > + set_feature(&cpu->env, ARM_FEATURE_M); > + set_feature(&cpu->env, ARM_FEATURE_M_MAIN); > + set_feature(&cpu->env, ARM_FEATURE_M_SECURITY); > + set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); > + cpu->midr = 0x411fd230; /* r1p0 */ > + cpu->revidr = 0; > + cpu->pmsav7_dregion = 16; > + cpu->sau_sregion = 8; > + /* These are the MVFR* values for the FPU + full MVE configuration */ > + cpu->isar.mvfr0 = 0x10110221; > + cpu->isar.mvfr1 = 0x12100211; > + cpu->isar.mvfr2 = 0x00000040; > + SET_IDREG(isar, ID_PFR0, 0x20000030); > + SET_IDREG(isar, ID_PFR1, 0x00000230); > + SET_IDREG(isar, ID_DFR0, 0x10200000); > + SET_IDREG(isar, ID_AFR0, 0x00000000); > + SET_IDREG(isar, ID_MMFR0, 0x00111040); > + SET_IDREG(isar, ID_MMFR1, 0x00000000); > + SET_IDREG(isar, ID_MMFR2, 0x01000000); > + SET_IDREG(isar, ID_MMFR3, 0x00000011); > + SET_IDREG(isar, ID_ISAR0, 0x01103110); > + SET_IDREG(isar, ID_ISAR1, 0x02212000); > + SET_IDREG(isar, ID_ISAR2, 0x20232232); > + SET_IDREG(isar, ID_ISAR3, 0x01111131); > + SET_IDREG(isar, ID_ISAR4, 0x01310132); > + SET_IDREG(isar, ID_ISAR5, 0x00000000); The TRM specifies this as 0x00100000 and you set this to in 3/3 to: SET_IDREG(isar, ID_ISAR5, 0x00200000); /* PACBTI=implementation defined */ which isn't one of the available config options. We'd rather not present a CPU that can't exist. With that said for A-profile we do offer the control knob of pauth-impdef (which is the default for -cpu max). We could add similar logic to aarch64_cpu_pauth_finalize to cpu32 to allow the user to actively tune their emulation speed. > + SET_IDREG(isar, ID_ISAR6, 0x00000000); > + SET_IDREG(isar, CLIDR, 0x00000000); /* caches not implemented */ > + cpu->ctr = 0x8303c003; > +} > + > static const TCGCPUOps arm_v7m_tcg_ops = { > /* ARM processors have a weak memory model */ > .guest_default_memory_order = 0, > @@ -290,6 +328,8 @@ static const ARMCPUInfo arm_v7m_cpus[] = { > .class_init = arm_v7m_class_init }, > { .name = "cortex-m55", .initfn = cortex_m55_initfn, > .class_init = arm_v7m_class_init }, > + { .name = "cortex-m85", .initfn = cortex_m85_initfn, > + .class_init = arm_v7m_class_init }, > }; > > static void arm_v7m_cpu_register_types(void) -- Alex Bennée Virtualisation Tech Lead @ Linaro ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu 2026-05-18 16:13 ` [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu Torbjörn SVENSSON 2026-05-27 13:21 ` Alex Bennée @ 2026-05-28 10:22 ` Peter Maydell 1 sibling, 0 replies; 14+ messages in thread From: Peter Maydell @ 2026-05-28 10:22 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, qemu-arm On Mon, 18 May 2026 at 17:16, Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> wrote: > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > --- > target/arm/tcg/cpu-v7m.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 40 insertions(+) This patch should go last in the series -- first add all the new features the CPU needs, and only then add the new CPU, so there isn't a window where the user can select the new CPU type but it isn't completely implemented yet. > diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c > index dc249ce1f1..5cfda232cd 100644 > --- a/target/arm/tcg/cpu-v7m.c > +++ b/target/arm/tcg/cpu-v7m.c > @@ -237,6 +237,44 @@ static void cortex_m55_initfn(Object *obj) > cpu->ctr = 0x8303c003; > } > > +static void cortex_m85_initfn(Object *obj) > +{ > + ARMCPU *cpu = ARM_CPU(obj); > + ARMISARegisters *isar = &cpu->isar; > + > + set_feature(&cpu->env, ARM_FEATURE_V8); > + set_feature(&cpu->env, ARM_FEATURE_V8_1M); > + set_feature(&cpu->env, ARM_FEATURE_M); > + set_feature(&cpu->env, ARM_FEATURE_M_MAIN); > + set_feature(&cpu->env, ARM_FEATURE_M_SECURITY); > + set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); > + cpu->midr = 0x411fd230; /* r1p0 */ The most recent release is r1p1, so we might as well model that: 0x411fd231. thanks -- PMM ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/3] target/arm/tcg: add PAC related instructions 2026-05-18 16:13 [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjörn SVENSSON 2026-05-18 16:13 ` [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu Torbjörn SVENSSON @ 2026-05-18 16:14 ` Torbjörn SVENSSON 2026-05-27 13:33 ` Alex Bennée 2026-05-28 10:40 ` Peter Maydell 2026-05-18 16:14 ` [PATCH 3/3] target/arm: implement v8.1-m PAC support Torbjörn SVENSSON ` (2 subsequent siblings) 4 siblings, 2 replies; 14+ messages in thread From: Torbjörn SVENSSON @ 2026-05-18 16:14 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Torbjörn SVENSSON This commit adds the pointer authentication instructions from the Arm v8.1-m PACBTI extension. While the instructions are properly recognized, they are all NOPs. Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> --- target/arm/tcg/t32.decode | 21 +++++++++++++--- target/arm/tcg/translate.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/target/arm/tcg/t32.decode b/target/arm/tcg/t32.decode index 49b8d0037e..a885eed101 100644 --- a/target/arm/tcg/t32.decode +++ b/target/arm/tcg/t32.decode @@ -263,6 +263,7 @@ BFCI 1111 0011 011 0 .... 0 ... .... ..0..... @bfi @s0_rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &s_rrrr s=0 @s0_rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &s_rrrr ra=0 s=0 @rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &rrrr +@rna0m .... .... .... rn:4 ra:4 .... .... rm:4 &rrrr rd=0 @rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &rrrr ra=0 @rndm .... .... .... rn:4 .... rd:4 .... rm:4 &rrr @rdm .... .... .... .... .... rd:4 .... rm:4 &rr @@ -319,9 +320,18 @@ SMLALDX 1111 1011 1100 .... .... .... 1101 .... @rnadm SMLSLD 1111 1011 1101 .... .... .... 1100 .... @rnadm SMLSLDX 1111 1011 1101 .... .... .... 1101 .... @rnadm -SMMLA 1111 1011 0101 .... .... .... 0000 .... @rnadm -SMMLAR 1111 1011 0101 .... .... .... 0001 .... @rnadm -SMMLS 1111 1011 0110 .... .... .... 0000 .... @rnadm +{ + AUTG 1111 1011 0101 .... .... 1111 0000 .... @rna0m + SMMLA 1111 1011 0101 .... .... .... 0000 .... @rnadm +} +{ + BXAUT 1111 1011 0101 .... .... 1111 0001 .... @rna0m + SMMLAR 1111 1011 0101 .... .... .... 0001 .... @rnadm +} +{ + PACG 1111 1011 0110 .... 1111 .... 0000 .... @rndm + SMMLS 1111 1011 0110 .... .... .... 0000 .... @rnadm +} SMMLSR 1111 1011 0110 .... .... .... 0001 .... @rnadm SDIV 1111 1011 1001 .... 1111 .... 1111 .... @rndm @@ -375,6 +385,11 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm # SEVL 1111 0011 1010 1111 1000 0000 0000 0101 ESB 1111 0011 1010 1111 1000 0000 0001 0000 + + # v8.1-m PACBTI extention + AUT 1111 0011 1010 1111 1000 0000 0010 1101 + PAC 1111 0011 1010 1111 1000 0000 0001 1101 + PACBTI 1111 0011 1010 1111 1000 0000 0000 1101 ] # The canonical nop ends in 0000 0000, but the whole rest diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index c744b16345..ae1351ef03 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -5012,6 +5012,68 @@ static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a) return op_smmla(s, a, true, true); } +static bool trans_PAC(DisasContext *s, arg_empty *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + + /* Handle as if PACBTI is disabled. */ + return true; +} + +static bool trans_PACBTI(DisasContext *s, arg_empty *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + + /* todo: reset EPSR.B to 0 */ + + /* Handle as if PACBTI is disabled. */ + return true; +} + +static bool trans_PACG(DisasContext *s, arg_rrr *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + + /* Handle as if PACBTI is disabled. */ + return true; +} + +static bool trans_BXAUT(DisasContext *s, arg_rrrr *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + + /* Handle as if PACBTI is disabled. */ + return true; +} + +static bool trans_AUT(DisasContext *s, arg_empty *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + + /* Handle as if PACBTI is disabled. */ + return true; +} + +static bool trans_AUTG(DisasContext *s, arg_rrrr *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + + /* Handle as if PACBTI is disabled. */ + return true; +} + static bool op_div(DisasContext *s, arg_rrr *a, bool u) { TCGv_i32 t1, t2; -- 2.43.0 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] target/arm/tcg: add PAC related instructions 2026-05-18 16:14 ` [PATCH 2/3] target/arm/tcg: add PAC related instructions Torbjörn SVENSSON @ 2026-05-27 13:33 ` Alex Bennée 2026-05-28 10:40 ` Peter Maydell 1 sibling, 0 replies; 14+ messages in thread From: Alex Bennée @ 2026-05-27 13:33 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, Peter Maydell, qemu-arm Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> writes: > This commit adds the pointer authentication instructions from the Arm > v8.1-m PACBTI extension. > While the instructions are properly recognized, they are all NOPs. > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > --- > target/arm/tcg/t32.decode | 21 +++++++++++++--- > target/arm/tcg/translate.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 80 insertions(+), 3 deletions(-) > > diff --git a/target/arm/tcg/t32.decode b/target/arm/tcg/t32.decode > index 49b8d0037e..a885eed101 100644 > --- a/target/arm/tcg/t32.decode > +++ b/target/arm/tcg/t32.decode > @@ -263,6 +263,7 @@ BFCI 1111 0011 011 0 .... 0 ... .... ..0..... @bfi > @s0_rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &s_rrrr s=0 > @s0_rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &s_rrrr ra=0 s=0 > @rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &rrrr > +@rna0m .... .... .... rn:4 ra:4 .... .... rm:4 &rrrr rd=0 > @rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &rrrr ra=0 > @rndm .... .... .... rn:4 .... rd:4 .... rm:4 &rrr > @rdm .... .... .... .... .... rd:4 .... rm:4 &rr > @@ -319,9 +320,18 @@ SMLALDX 1111 1011 1100 .... .... .... 1101 .... @rnadm > SMLSLD 1111 1011 1101 .... .... .... 1100 .... @rnadm > SMLSLDX 1111 1011 1101 .... .... .... 1101 .... @rnadm > > -SMMLA 1111 1011 0101 .... .... .... 0000 .... @rnadm > -SMMLAR 1111 1011 0101 .... .... .... 0001 .... @rnadm > -SMMLS 1111 1011 0110 .... .... .... 0000 .... @rnadm > +{ > + AUTG 1111 1011 0101 .... .... 1111 0000 .... @rna0m > + SMMLA 1111 1011 0101 .... .... .... 0000 .... @rnadm > +} > +{ > + BXAUT 1111 1011 0101 .... .... 1111 0001 .... @rna0m > + SMMLAR 1111 1011 0101 .... .... .... 0001 .... @rnadm > +} > +{ > + PACG 1111 1011 0110 .... 1111 .... 0000 .... @rndm > + SMMLS 1111 1011 0110 .... .... .... 0000 .... @rnadm > +} > SMMLSR 1111 1011 0110 .... .... .... 0001 .... @rnadm > > SDIV 1111 1011 1001 .... 1111 .... 1111 .... @rndm > @@ -375,6 +385,11 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm > # SEVL 1111 0011 1010 1111 1000 0000 0000 0101 > > ESB 1111 0011 1010 1111 1000 0000 0001 0000 > + > + # v8.1-m PACBTI extention > + AUT 1111 0011 1010 1111 1000 0000 0010 1101 > + PAC 1111 0011 1010 1111 1000 0000 0001 1101 > + PACBTI 1111 0011 1010 1111 1000 0000 0000 1101 > ] > > # The canonical nop ends in 0000 0000, but the whole rest > diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c > index c744b16345..ae1351ef03 100644 > --- a/target/arm/tcg/translate.c > +++ b/target/arm/tcg/translate.c > @@ -5012,6 +5012,68 @@ static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a) > return op_smmla(s, a, true, true); > } > > +static bool trans_PAC(DisasContext *s, arg_empty *a) > +{ > + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { > + return false; > + } These are the wrong feature tests. I would bring the isar_feature_aa32_m_pacbti from 3/3 into this patch and invert the logic in the same way the a64 does: if (dc_isar_feature(aa32_m_pacbti, s)) { /* treat as NOP for now */ return true; } return false; -- Alex Bennée Virtualisation Tech Lead @ Linaro ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] target/arm/tcg: add PAC related instructions 2026-05-18 16:14 ` [PATCH 2/3] target/arm/tcg: add PAC related instructions Torbjörn SVENSSON 2026-05-27 13:33 ` Alex Bennée @ 2026-05-28 10:40 ` Peter Maydell 1 sibling, 0 replies; 14+ messages in thread From: Peter Maydell @ 2026-05-28 10:40 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, qemu-arm On Mon, 18 May 2026 at 17:16, Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> wrote: > > This commit adds the pointer authentication instructions from the Arm > v8.1-m PACBTI extension. > While the instructions are properly recognized, they are all NOPs. > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> I think it's worth mentioning in the commit message that we previously decoded these as SMMLA, and that changing what we do is OK because for v7A and v8A these SMMLA etc encodings say that Rd == 0b1111 is UNPREDICTABLE. > --- > target/arm/tcg/t32.decode | 21 +++++++++++++--- > target/arm/tcg/translate.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 80 insertions(+), 3 deletions(-) > > diff --git a/target/arm/tcg/t32.decode b/target/arm/tcg/t32.decode > index 49b8d0037e..a885eed101 100644 > --- a/target/arm/tcg/t32.decode > +++ b/target/arm/tcg/t32.decode > @@ -263,6 +263,7 @@ BFCI 1111 0011 011 0 .... 0 ... .... ..0..... @bfi > @s0_rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &s_rrrr s=0 > @s0_rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &s_rrrr ra=0 s=0 > @rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &rrrr > +@rna0m .... .... .... rn:4 ra:4 .... .... rm:4 &rrrr rd=0 > @rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &rrrr ra=0 > @rndm .... .... .... rn:4 .... rd:4 .... rm:4 &rrr > @rdm .... .... .... .... .... rd:4 .... rm:4 &rr > @@ -319,9 +320,18 @@ SMLALDX 1111 1011 1100 .... .... .... 1101 .... @rnadm > SMLSLD 1111 1011 1101 .... .... .... 1100 .... @rnadm > SMLSLDX 1111 1011 1101 .... .... .... 1101 .... @rnadm > > -SMMLA 1111 1011 0101 .... .... .... 0000 .... @rnadm > -SMMLAR 1111 1011 0101 .... .... .... 0001 .... @rnadm > -SMMLS 1111 1011 0110 .... .... .... 0000 .... @rnadm > +{ > + AUTG 1111 1011 0101 .... .... 1111 0000 .... @rna0m > + SMMLA 1111 1011 0101 .... .... .... 0000 .... @rnadm > +} > +{ > + BXAUT 1111 1011 0101 .... .... 1111 0001 .... @rna0m > + SMMLAR 1111 1011 0101 .... .... .... 0001 .... @rnadm > +} > +{ > + PACG 1111 1011 0110 .... 1111 .... 0000 .... @rndm > + SMMLS 1111 1011 0110 .... .... .... 0000 .... @rnadm > +} > SMMLSR 1111 1011 0110 .... .... .... 0001 .... @rnadm > > SDIV 1111 1011 1001 .... 1111 .... 1111 .... @rndm > @@ -375,6 +385,11 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm > # SEVL 1111 0011 1010 1111 1000 0000 0000 0101 > > ESB 1111 0011 1010 1111 1000 0000 0001 0000 > + > + # v8.1-m PACBTI extention > + AUT 1111 0011 1010 1111 1000 0000 0010 1101 > + PAC 1111 0011 1010 1111 1000 0000 0001 1101 > + PACBTI 1111 0011 1010 1111 1000 0000 0000 1101 > ] > > # The canonical nop ends in 0000 0000, but the whole rest > diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c > index c744b16345..ae1351ef03 100644 > --- a/target/arm/tcg/translate.c > +++ b/target/arm/tcg/translate.c > @@ -5012,6 +5012,68 @@ static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a) > return op_smmla(s, a, true, true); > } > > +static bool trans_PAC(DisasContext *s, arg_empty *a) > +{ > + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { > + return false; > + } > + > + /* Handle as if PACBTI is disabled. */ > + return true; > +} I think the patchset would be clearer if we implemented the insns (in whatever combinations make sense) in the same patches as we add their decode, rather than adding decode only in one patch and then implementation later. thanks -- PMM ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/3] target/arm: implement v8.1-m PAC support 2026-05-18 16:13 [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjörn SVENSSON 2026-05-18 16:13 ` [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu Torbjörn SVENSSON 2026-05-18 16:14 ` [PATCH 2/3] target/arm/tcg: add PAC related instructions Torbjörn SVENSSON @ 2026-05-18 16:14 ` Torbjörn SVENSSON 2026-05-27 13:55 ` Alex Bennée 2026-05-28 10:43 ` Peter Maydell 2026-05-27 7:36 ` [PING] [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjorn SVENSSON 2026-05-28 10:50 ` Peter Maydell 4 siblings, 2 replies; 14+ messages in thread From: Torbjörn SVENSSON @ 2026-05-18 16:14 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Torbjörn SVENSSON The algorithm used for hashing is a simple XOR between the pointer and the modifier using the "implementation defined" scheme. Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> --- target/arm/cpu-features.h | 6 +++ target/arm/internals.h | 2 + target/arm/tcg/cpu-v7m.c | 2 +- target/arm/tcg/m_helper.c | 17 ++++++++ target/arm/tcg/translate.c | 98 ++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 113 insertions(+), 12 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 4e44245a8b..60bd7a0765 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -114,6 +114,7 @@ FIELD(ID_ISAR5, AES, 4, 4) FIELD(ID_ISAR5, SHA1, 8, 4) FIELD(ID_ISAR5, SHA2, 12, 4) FIELD(ID_ISAR5, CRC32, 16, 4) +FIELD(ID_ISAR5, PACBTI, 20, 4) FIELD(ID_ISAR5, RDM, 24, 4) FIELD(ID_ISAR5, VCMA, 28, 4) @@ -583,6 +584,11 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) return FIELD_EX32_IDREG(id, ID_PFR1, SECURITY) >= 3; } +static inline bool isar_feature_aa32_m_pacbti(const ARMISARegisters *id) +{ + return FIELD_EX32_IDREG(id, ID_ISAR5, PACBTI) != 0; +} + static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) { /* Sadly this is encoded differently for A-profile and M-profile */ diff --git a/target/arm/internals.h b/target/arm/internals.h index 00830b1724..cbb0a1d8fc 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -90,6 +90,8 @@ FIELD(V7M_CONTROL, NPRIV, 0, 1) FIELD(V7M_CONTROL, SPSEL, 1, 1) FIELD(V7M_CONTROL, FPCA, 2, 1) FIELD(V7M_CONTROL, SFPA, 3, 1) +FIELD(V7M_CONTROL, PAC_EN, 6, 1) +FIELD(V7M_CONTROL, UPAC_EN, 7, 1) /* Bit definitions for v7M exception return payload */ FIELD(V7M_EXCRET, ES, 0, 1) diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c index 5cfda232cd..3beb2b23fa 100644 --- a/target/arm/tcg/cpu-v7m.c +++ b/target/arm/tcg/cpu-v7m.c @@ -269,7 +269,7 @@ static void cortex_m85_initfn(Object *obj) SET_IDREG(isar, ID_ISAR2, 0x20232232); SET_IDREG(isar, ID_ISAR3, 0x01111131); SET_IDREG(isar, ID_ISAR4, 0x01310132); - SET_IDREG(isar, ID_ISAR5, 0x00000000); + SET_IDREG(isar, ID_ISAR5, 0x00200000); /* PACBTI=implementation defined */ SET_IDREG(isar, ID_ISAR6, 0x00000000); SET_IDREG(isar, CLIDR, 0x00000000); /* caches not implemented */ cpu->ctr = 0x8303c003; diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c index f2059ed8b0..1160fe8d87 100644 --- a/target/arm/tcg/m_helper.c +++ b/target/arm/tcg/m_helper.c @@ -2658,6 +2658,15 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK; env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK; } + + /* Only update PAC_EN / UPAC_EN if PACBTI is implemented. */ + if (cpu_isar_feature(aa32_m_pacbti, env_archcpu(env))) { + uint32_t enable_mask = + R_V7M_CONTROL_PAC_EN_MASK | R_V7M_CONTROL_UPAC_EN_MASK; + env->v7m.control[M_REG_NS] &= ~enable_mask; + env->v7m.control[M_REG_NS] |= val & enable_mask; + } + return; case 0x98: /* SP_NS */ { @@ -2784,6 +2793,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK; } } + + /* Only update PAC_EN / UPAC_EN if PACBTI is implemented. */ + if (cpu_isar_feature(aa32_m_pacbti, env_archcpu(env))) { + uint32_t enable_mask = + R_V7M_CONTROL_PAC_EN_MASK | R_V7M_CONTROL_UPAC_EN_MASK; + env->v7m.control[env->v7m.secure] &= ~enable_mask; + env->v7m.control[env->v7m.secure] |= val & enable_mask; + } break; default: bad_reg: diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index ae1351ef03..e13119b33b 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -5012,26 +5012,80 @@ static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a) return op_smmla(s, a, true, true); } +static void arm_gen_test_pac_enabled(DisasContext *s, TCGLabel *label) +{ + int bank = s->v8m_secure ? M_REG_S : M_REG_NS; + int mask = IS_USER(s) + ? R_V7M_CONTROL_UPAC_EN_MASK + : R_V7M_CONTROL_PAC_EN_MASK; + TCGv_i32 temp = load_cpu_field(v7m.control[bank]); + tcg_gen_brcondi_i32(TCG_COND_TSTEQ, temp, mask, label); +} + +static TCGv_i32 op_create_pac_hash(DisasContext *s, int rn, int rm) +{ + TCGv_i32 res = tcg_temp_new_i32(); + TCGv_i64 ext_ptr = tcg_temp_new_i64(); + TCGv_i64 modifier = tcg_temp_new_i64(); + TCGv_i64 temp = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(ext_ptr, load_reg(s, rn)); + tcg_gen_extu_i32_i64(modifier, load_reg(s, rm)); + + /* + * This a very simple implementation that just xor the two + * inputs. The goal is not to replicate any of the predefined + * hashing functions, but use a simple check. + */ + tcg_gen_xor_i64(temp, ext_ptr, modifier); + + /* Return the lower word */ + tcg_gen_extrl_i64_i32(res, temp); + return res; +} + +static bool op_pacg(DisasContext *s, arg_rrr *a) +{ + TCGv_i32 temp; + TCGLabel *done = gen_new_label(); + + arm_gen_test_pac_enabled(s, done); + + temp = op_create_pac_hash(s, a->rn, a->rm); + store_reg(s, a->rd, temp); + + gen_set_label(done); + return true; +} + static bool trans_PAC(DisasContext *s, arg_empty *a) { + arg_rrr arg; + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { return false; } - /* Handle as if PACBTI is disabled. */ - return true; + arg.rd = 0xc; /* R12 */ + arg.rn = 0xe; /* LR */ + arg.rm = 0xd; /* SP */ + return op_pacg(s, &arg); } static bool trans_PACBTI(DisasContext *s, arg_empty *a) { + arg_rrr arg; + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { return false; } /* todo: reset EPSR.B to 0 */ - /* Handle as if PACBTI is disabled. */ - return true; + arg.rd = 0xc; /* R12 */ + arg.rn = 0xe; /* LR */ + arg.rm = 0xd; /* SP */ + return op_pacg(s, &arg); } static bool trans_PACG(DisasContext *s, arg_rrr *a) @@ -5040,7 +5094,26 @@ static bool trans_PACG(DisasContext *s, arg_rrr *a) return false; } - /* Handle as if PACBTI is disabled. */ + return op_pacg(s, a); +} + +static bool op_autg(DisasContext *s, arg_rrrr *a, int set_pc_from_reg) +{ + TCGv_i32 expected_pac_hash, actual_pac_hash; + TCGLabel *done = gen_new_label(); + TCGLabel *fail = delay_exception(s, EXCP_INVSTATE, syn_uncategorized()); + + arm_gen_test_pac_enabled(s, done); + + expected_pac_hash = load_reg(s, a->ra); + actual_pac_hash = op_create_pac_hash(s, a->rn, a->rm); + tcg_gen_brcond_i32(TCG_COND_NE, expected_pac_hash, actual_pac_hash, fail); + + gen_set_label(done); + if (set_pc_from_reg >= 0) { + gen_bx_excret(s, load_reg(s, set_pc_from_reg)); + } + return true; } @@ -5050,18 +5123,22 @@ static bool trans_BXAUT(DisasContext *s, arg_rrrr *a) return false; } - /* Handle as if PACBTI is disabled. */ - return true; + return op_autg(s, a, a->rn); } static bool trans_AUT(DisasContext *s, arg_empty *a) { + arg_rrrr arg; + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { return false; } - /* Handle as if PACBTI is disabled. */ - return true; + arg.rd = 0; /* unused */ + arg.ra = 0xc; /* R12 */ + arg.rn = 0xe; /* LR */ + arg.rm = 0xd; /* SP */ + return op_autg(s, &arg, -1); } static bool trans_AUTG(DisasContext *s, arg_rrrr *a) @@ -5070,8 +5147,7 @@ static bool trans_AUTG(DisasContext *s, arg_rrrr *a) return false; } - /* Handle as if PACBTI is disabled. */ - return true; + return op_autg(s, a, -1); } static bool op_div(DisasContext *s, arg_rrr *a, bool u) -- 2.43.0 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/3] target/arm: implement v8.1-m PAC support 2026-05-18 16:14 ` [PATCH 3/3] target/arm: implement v8.1-m PAC support Torbjörn SVENSSON @ 2026-05-27 13:55 ` Alex Bennée 2026-05-27 16:38 ` Peter Maydell 2026-05-28 10:43 ` Peter Maydell 1 sibling, 1 reply; 14+ messages in thread From: Alex Bennée @ 2026-05-27 13:55 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, Peter Maydell, qemu-arm Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> writes: > The algorithm used for hashing is a simple XOR between the pointer > and the modifier using the "implementation defined" scheme. > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > --- > target/arm/cpu-features.h | 6 +++ > target/arm/internals.h | 2 + > target/arm/tcg/cpu-v7m.c | 2 +- > target/arm/tcg/m_helper.c | 17 ++++++++ > target/arm/tcg/translate.c | 98 ++++++++++++++++++++++++++++++++++++++++------ > 5 files changed, 113 insertions(+), 12 deletions(-) > > diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h > index 4e44245a8b..60bd7a0765 100644 > --- a/target/arm/cpu-features.h > +++ b/target/arm/cpu-features.h > @@ -114,6 +114,7 @@ FIELD(ID_ISAR5, AES, 4, 4) > FIELD(ID_ISAR5, SHA1, 8, 4) > FIELD(ID_ISAR5, SHA2, 12, 4) > FIELD(ID_ISAR5, CRC32, 16, 4) > +FIELD(ID_ISAR5, PACBTI, 20, 4) > FIELD(ID_ISAR5, RDM, 24, 4) > FIELD(ID_ISAR5, VCMA, 28, 4) > > @@ -583,6 +584,11 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) > return FIELD_EX32_IDREG(id, ID_PFR1, SECURITY) >= 3; > } > > +static inline bool isar_feature_aa32_m_pacbti(const ARMISARegisters *id) > +{ > + return FIELD_EX32_IDREG(id, ID_ISAR5, PACBTI) != 0; > +} See isar_feature_aa64_pauth and friends. > + > static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) > { > /* Sadly this is encoded differently for A-profile and M-profile */ > diff --git a/target/arm/internals.h b/target/arm/internals.h > index 00830b1724..cbb0a1d8fc 100644 > --- a/target/arm/internals.h > +++ b/target/arm/internals.h > @@ -90,6 +90,8 @@ FIELD(V7M_CONTROL, NPRIV, 0, 1) > FIELD(V7M_CONTROL, SPSEL, 1, 1) > FIELD(V7M_CONTROL, FPCA, 2, 1) > FIELD(V7M_CONTROL, SFPA, 3, 1) > +FIELD(V7M_CONTROL, PAC_EN, 6, 1) > +FIELD(V7M_CONTROL, UPAC_EN, 7, 1) Hmm my copy of the v7m Arm ARM doesn't include these bits... But I can see it online: https://developer.arm.com/documentation/109576/0100/Pointer-Authentication-Code/Enabling-pointer-authentication?lang=en > > /* Bit definitions for v7M exception return payload */ > FIELD(V7M_EXCRET, ES, 0, 1) > diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c > index 5cfda232cd..3beb2b23fa 100644 > --- a/target/arm/tcg/cpu-v7m.c > +++ b/target/arm/tcg/cpu-v7m.c > @@ -269,7 +269,7 @@ static void cortex_m85_initfn(Object *obj) > SET_IDREG(isar, ID_ISAR2, 0x20232232); > SET_IDREG(isar, ID_ISAR3, 0x01111131); > SET_IDREG(isar, ID_ISAR4, 0x01310132); > - SET_IDREG(isar, ID_ISAR5, 0x00000000); > + SET_IDREG(isar, ID_ISAR5, 0x00200000); /* PACBTI=implementation defined */ > SET_IDREG(isar, ID_ISAR6, 0x00000000); > SET_IDREG(isar, CLIDR, 0x00000000); /* caches not implemented */ > cpu->ctr = 0x8303c003; > diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c > index f2059ed8b0..1160fe8d87 100644 > --- a/target/arm/tcg/m_helper.c > +++ b/target/arm/tcg/m_helper.c > @@ -2658,6 +2658,15 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) > env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK; > env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK; > } > + > + /* Only update PAC_EN / UPAC_EN if PACBTI is implemented. */ > + if (cpu_isar_feature(aa32_m_pacbti, env_archcpu(env))) { > + uint32_t enable_mask = > + R_V7M_CONTROL_PAC_EN_MASK | R_V7M_CONTROL_UPAC_EN_MASK; > + env->v7m.control[M_REG_NS] &= ~enable_mask; > + env->v7m.control[M_REG_NS] |= val & enable_mask; Hmm I was going to suggest looking at FIELD_DP32 but it looks like this is following the existing style. > + } > + > return; > case 0x98: /* SP_NS */ > { > @@ -2784,6 +2793,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) > env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK; > } > } > + > + /* Only update PAC_EN / UPAC_EN if PACBTI is implemented. */ > + if (cpu_isar_feature(aa32_m_pacbti, env_archcpu(env))) { > + uint32_t enable_mask = > + R_V7M_CONTROL_PAC_EN_MASK | R_V7M_CONTROL_UPAC_EN_MASK; > + env->v7m.control[env->v7m.secure] &= ~enable_mask; > + env->v7m.control[env->v7m.secure] |= val & enable_mask; > + } > break; > default: > bad_reg: > diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c > index ae1351ef03..e13119b33b 100644 > --- a/target/arm/tcg/translate.c > +++ b/target/arm/tcg/translate.c > @@ -5012,26 +5012,80 @@ static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a) > return op_smmla(s, a, true, true); > } > > +static void arm_gen_test_pac_enabled(DisasContext *s, TCGLabel *label) > +{ > + int bank = s->v8m_secure ? M_REG_S : M_REG_NS; > + int mask = IS_USER(s) > + ? R_V7M_CONTROL_UPAC_EN_MASK > + : R_V7M_CONTROL_PAC_EN_MASK; > + TCGv_i32 temp = load_cpu_field(v7m.control[bank]); > + tcg_gen_brcondi_i32(TCG_COND_TSTEQ, temp, mask, label); > +} > + > +static TCGv_i32 op_create_pac_hash(DisasContext *s, int rn, int rm) > +{ > + TCGv_i32 res = tcg_temp_new_i32(); > + TCGv_i64 ext_ptr = tcg_temp_new_i64(); > + TCGv_i64 modifier = tcg_temp_new_i64(); > + TCGv_i64 temp = tcg_temp_new_i64(); > + > + tcg_gen_extu_i32_i64(ext_ptr, load_reg(s, rn)); > + tcg_gen_extu_i32_i64(modifier, load_reg(s, rm)); > + > + /* > + * This a very simple implementation that just xor the two > + * inputs. The goal is not to replicate any of the predefined > + * hashing functions, but use a simple check. > + */ > + tcg_gen_xor_i64(temp, ext_ptr, modifier); > + > + /* Return the lower word */ > + tcg_gen_extrl_i64_i32(res, temp); > + return res; Is it really needed here? Could you not create an equivalent of pauth_computepac for m-profile and use the architected helpers or fall-back to the xxhash impl? Is does mean a helper call but it would keep more in common with the A-profile code. > +} > + > +static bool op_pacg(DisasContext *s, arg_rrr *a) > +{ > + TCGv_i32 temp; > + TCGLabel *done = gen_new_label(); > + > + arm_gen_test_pac_enabled(s, done); > + > + temp = op_create_pac_hash(s, a->rn, a->rm); > + store_reg(s, a->rd, temp); > + > + gen_set_label(done); > + return true; > +} > + > static bool trans_PAC(DisasContext *s, arg_empty *a) > { > + arg_rrr arg; > + > if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { > return false; > } > > - /* Handle as if PACBTI is disabled. */ > - return true; > + arg.rd = 0xc; /* R12 */ > + arg.rn = 0xe; /* LR */ > + arg.rm = 0xd; /* SP */ > + return op_pacg(s, &arg); > } > > static bool trans_PACBTI(DisasContext *s, arg_empty *a) > { > + arg_rrr arg; > + > if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { > return false; > } > > /* todo: reset EPSR.B to 0 */ > > - /* Handle as if PACBTI is disabled. */ > - return true; > + arg.rd = 0xc; /* R12 */ > + arg.rn = 0xe; /* LR */ > + arg.rm = 0xd; /* SP */ > + return op_pacg(s, &arg); > } > > static bool trans_PACG(DisasContext *s, arg_rrr *a) > @@ -5040,7 +5094,26 @@ static bool trans_PACG(DisasContext *s, arg_rrr *a) > return false; > } > > - /* Handle as if PACBTI is disabled. */ > + return op_pacg(s, a); > +} > + > +static bool op_autg(DisasContext *s, arg_rrrr *a, int set_pc_from_reg) > +{ > + TCGv_i32 expected_pac_hash, actual_pac_hash; > + TCGLabel *done = gen_new_label(); > + TCGLabel *fail = delay_exception(s, EXCP_INVSTATE, syn_uncategorized()); > + > + arm_gen_test_pac_enabled(s, done); > + > + expected_pac_hash = load_reg(s, a->ra); > + actual_pac_hash = op_create_pac_hash(s, a->rn, a->rm); > + tcg_gen_brcond_i32(TCG_COND_NE, expected_pac_hash, actual_pac_hash, fail); > + > + gen_set_label(done); > + if (set_pc_from_reg >= 0) { > + gen_bx_excret(s, load_reg(s, set_pc_from_reg)); > + } > + > return true; > } > > @@ -5050,18 +5123,22 @@ static bool trans_BXAUT(DisasContext *s, arg_rrrr *a) > return false; > } > > - /* Handle as if PACBTI is disabled. */ > - return true; > + return op_autg(s, a, a->rn); > } > > static bool trans_AUT(DisasContext *s, arg_empty *a) > { > + arg_rrrr arg; > + > if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { > return false; > } > > - /* Handle as if PACBTI is disabled. */ > - return true; > + arg.rd = 0; /* unused */ > + arg.ra = 0xc; /* R12 */ > + arg.rn = 0xe; /* LR */ > + arg.rm = 0xd; /* SP */ > + return op_autg(s, &arg, -1); > } > > static bool trans_AUTG(DisasContext *s, arg_rrrr *a) > @@ -5070,8 +5147,7 @@ static bool trans_AUTG(DisasContext *s, arg_rrrr *a) > return false; > } > > - /* Handle as if PACBTI is disabled. */ > - return true; > + return op_autg(s, a, -1); > } > > static bool op_div(DisasContext *s, arg_rrr *a, bool u) -- Alex Bennée Virtualisation Tech Lead @ Linaro ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/3] target/arm: implement v8.1-m PAC support 2026-05-27 13:55 ` Alex Bennée @ 2026-05-27 16:38 ` Peter Maydell 0 siblings, 0 replies; 14+ messages in thread From: Peter Maydell @ 2026-05-27 16:38 UTC (permalink / raw) To: Alex Bennée; +Cc: Torbjörn SVENSSON, qemu-devel, qemu-arm On Wed, 27 May 2026 at 14:55, Alex Bennée <alex.bennee@linaro.org> wrote: > > Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> writes: > > > The algorithm used for hashing is a simple XOR between the pointer > > and the modifier using the "implementation defined" scheme. > > > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > > @@ -90,6 +90,8 @@ FIELD(V7M_CONTROL, NPRIV, 0, 1) > > FIELD(V7M_CONTROL, SPSEL, 1, 1) > > FIELD(V7M_CONTROL, FPCA, 2, 1) > > FIELD(V7M_CONTROL, SFPA, 3, 1) > > +FIELD(V7M_CONTROL, PAC_EN, 6, 1) > > +FIELD(V7M_CONTROL, UPAC_EN, 7, 1) > > Hmm my copy of the v7m Arm ARM doesn't include these bits... If you're looking at the v7M Arm ARM that's the wrong one. You want the v8M Arm ARM; most recent rev is DDI0553 B.z. https://developer.arm.com/documentation/ddi0553/latest/ -- PMM ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/3] target/arm: implement v8.1-m PAC support 2026-05-18 16:14 ` [PATCH 3/3] target/arm: implement v8.1-m PAC support Torbjörn SVENSSON 2026-05-27 13:55 ` Alex Bennée @ 2026-05-28 10:43 ` Peter Maydell 1 sibling, 0 replies; 14+ messages in thread From: Peter Maydell @ 2026-05-28 10:43 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, qemu-arm On Mon, 18 May 2026 at 17:16, Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> wrote: > > The algorithm used for hashing is a simple XOR between the pointer > and the modifier using the "implementation defined" scheme. > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > --- > target/arm/cpu-features.h | 6 +++ > target/arm/internals.h | 2 + > target/arm/tcg/cpu-v7m.c | 2 +- > target/arm/tcg/m_helper.c | 17 ++++++++ > target/arm/tcg/translate.c | 98 ++++++++++++++++++++++++++++++++++++++++------ > 5 files changed, 113 insertions(+), 12 deletions(-) > > static bool trans_PAC(DisasContext *s, arg_empty *a) > { > + arg_rrr arg; > + > if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { > return false; > } > > - /* Handle as if PACBTI is disabled. */ > - return true; > + arg.rd = 0xc; /* R12 */ > + arg.rn = 0xe; /* LR */ > + arg.rm = 0xd; /* SP */ Generally it's better to do this kind of thing in the decode file rather than the trans function, so that this function get s passed an arg_rrr with the right values filled in rather than having to synthesize them. > + return op_pacg(s, &arg); > } thanks -- PMM ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PING] [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code 2026-05-18 16:13 [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjörn SVENSSON ` (2 preceding siblings ...) 2026-05-18 16:14 ` [PATCH 3/3] target/arm: implement v8.1-m PAC support Torbjörn SVENSSON @ 2026-05-27 7:36 ` Torbjorn SVENSSON 2026-05-27 12:58 ` Alex Bennée 2026-05-28 10:50 ` Peter Maydell 4 siblings, 1 reply; 14+ messages in thread From: Torbjorn SVENSSON @ 2026-05-27 7:36 UTC (permalink / raw) To: qemu-devel, qemu-arm; +Cc: Peter Maydell, Richard Henderson Gentle ping! :) There is apparently also a ticket for this work (that I did not see before I sent the patches): https://linaro.atlassian.net/browse/QEMU-444 On 2026-05-18 18:13, Torbjörn SVENSSON wrote: > Testing an arm-none-eabi GCC toolchain using QEMU gives unpredictable > test results for some test cases. In the GCC testsuite function > check_effective_target_arm_pacbti_hw, the testsuite tries to identify > if the target supports PACBTI instructions. The test consists of: > > __attribute__ ((naked)) int > main (void) > { > asm ("pac r12, lr, sp"); > asm ("mov r0, #0"); > asm ("autg r12, lr, sp"); > asm ("bx lr"); > } > > Running the above code in QEMU will cause LR to get corrupted. > The reson for the corruption is that AUTG overlaps with the SMMLA > instruction, and SMMLA will write the result to Rn, that for > `AUTG R12, LR, SP` happens to match `LR`. The above statement is not entirely true. SMMLA is writing the result to Rd and that happens to match PC, not Rn and LR. Sorry for the confusion this might have caused. Kind regards, Torbjörn > The solution to the above problem is to define the following new > Cortex-M instructions in QEMU: > > * AUT > * AUTG > * BXAUT > * PAC > * PACBTI > * PACG > > This patch series only implements the pointer authentication code part > of PACBTI. The branch target identification part is not implemented. > > Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> > --- > Torbjörn SVENSSON (3): > target/arm/tcg: define cortex-m85 cpu > target/arm/tcg: add PAC related instructions > target/arm: implement v8.1-m PAC support > > target/arm/cpu-features.h | 6 ++ > target/arm/internals.h | 2 + > target/arm/tcg/cpu-v7m.c | 40 +++++++++++++ > target/arm/tcg/m_helper.c | 17 ++++++ > target/arm/tcg/t32.decode | 21 ++++++- > target/arm/tcg/translate.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 221 insertions(+), 3 deletions(-) > --- > base-commit: ac6721b88df944ade0048822b2b74210f543d656 > change-id: 20260518-pr-pacbti-366d7acbe1be > > Best regards, ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PING] [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code 2026-05-27 7:36 ` [PING] [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjorn SVENSSON @ 2026-05-27 12:58 ` Alex Bennée 0 siblings, 0 replies; 14+ messages in thread From: Alex Bennée @ 2026-05-27 12:58 UTC (permalink / raw) To: Torbjorn SVENSSON; +Cc: qemu-devel, qemu-arm, Peter Maydell, Richard Henderson Torbjorn SVENSSON <torbjorn.svensson@foss.st.com> writes: > Gentle ping! :) > > There is apparently also a ticket for this work (that I did not see before I sent the patches): https://linaro.atlassian.net/browse/QEMU-444 > The Linaro tickets are public (because we work directly upstream) although the existence of a ticket should not imply that we plan to work on it. We create tickets for most of the Arm CPU features so we can track dependencies, what is left to do and when others have patches that need review. Our actual planned roadmap can be seen here: https://linaro.atlassian.net/wiki/spaces/QEMU/overview > > On 2026-05-18 18:13, Torbjörn SVENSSON wrote: >> Testing an arm-none-eabi GCC toolchain using QEMU gives unpredictable >> test results for some test cases. In the GCC testsuite function >> check_effective_target_arm_pacbti_hw, the testsuite tries to identify >> if the target supports PACBTI instructions. The test consists of: >> __attribute__ ((naked)) int >> main (void) >> { >> asm ("pac r12, lr, sp"); >> asm ("mov r0, #0"); >> asm ("autg r12, lr, sp"); >> asm ("bx lr"); >> } >> Running the above code in QEMU will cause LR to get corrupted. >> The reson for the corruption is that AUTG overlaps with the SMMLA >> instruction, and SMMLA will write the result to Rn, that for >> `AUTG R12, LR, SP` happens to match `LR`. > > The above statement is not entirely true. > SMMLA is writing the result to Rd and that happens to match PC, not Rn and LR. > Sorry for the confusion this might have caused. > > Kind regards, > Torbjörn > >> The solution to the above problem is to define the following new >> Cortex-M instructions in QEMU: >> * AUT >> * AUTG >> * BXAUT >> * PAC >> * PACBTI >> * PACG >> This patch series only implements the pointer authentication code >> part >> of PACBTI. The branch target identification part is not implemented. >> Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> >> --- >> Torbjörn SVENSSON (3): >> target/arm/tcg: define cortex-m85 cpu >> target/arm/tcg: add PAC related instructions >> target/arm: implement v8.1-m PAC support >> target/arm/cpu-features.h | 6 ++ >> target/arm/internals.h | 2 + >> target/arm/tcg/cpu-v7m.c | 40 +++++++++++++ >> target/arm/tcg/m_helper.c | 17 ++++++ >> target/arm/tcg/t32.decode | 21 ++++++- >> target/arm/tcg/translate.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ >> 6 files changed, 221 insertions(+), 3 deletions(-) >> --- >> base-commit: ac6721b88df944ade0048822b2b74210f543d656 >> change-id: 20260518-pr-pacbti-366d7acbe1be >> Best regards, -- Alex Bennée Virtualisation Tech Lead @ Linaro ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code 2026-05-18 16:13 [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjörn SVENSSON ` (3 preceding siblings ...) 2026-05-27 7:36 ` [PING] [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjorn SVENSSON @ 2026-05-28 10:50 ` Peter Maydell 4 siblings, 0 replies; 14+ messages in thread From: Peter Maydell @ 2026-05-28 10:50 UTC (permalink / raw) To: Torbjörn SVENSSON; +Cc: qemu-devel, qemu-arm On Mon, 18 May 2026 at 17:16, Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> wrote: > > Testing an arm-none-eabi GCC toolchain using QEMU gives unpredictable > test results for some test cases. In the GCC testsuite function > check_effective_target_arm_pacbti_hw, the testsuite tries to identify > if the target supports PACBTI instructions. The test consists of: > > __attribute__ ((naked)) int > main (void) > { > asm ("pac r12, lr, sp"); > asm ("mov r0, #0"); > asm ("autg r12, lr, sp"); > asm ("bx lr"); > } > > Running the above code in QEMU will cause LR to get corrupted. > The reson for the corruption is that AUTG overlaps with the SMMLA > instruction, and SMMLA will write the result to Rn, that for > `AUTG R12, LR, SP` happens to match `LR`. If the test case is expecting to be able to run on any M-profile CPU, this is a bug in the test case. The AUTG instruction is specified as being UNPREDICTABLE if the DSP extension is implemented and the PACBTI extension is not (and to UNDEF if neither extension is implemented). (We could consider making the QEMU behaviour for these UNPREDICTABLE cases in SMMLA etc be "UNDEF" rather than "write to the PC/LR"; we choose to handle this kind of UNPREDICTABLE decode that way for other insns already.) > The solution to the above problem is to define the following new > Cortex-M instructions in QEMU: > > * AUT > * AUTG > * BXAUT > * PAC > * PACBTI > * PACG > > This patch series only implements the pointer authentication code part > of PACBTI. The branch target identification part is not implemented. I think that overall we need the full PACBTI implemented -- we can't advertise it in the CPU ID registers but only implement part of it, or only implement it for user-mode and not for system mode. thanks -- PMM ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-05-28 10:51 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-18 16:13 [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjörn SVENSSON 2026-05-18 16:13 ` [PATCH 1/3] target/arm/tcg: define cortex-m85 cpu Torbjörn SVENSSON 2026-05-27 13:21 ` Alex Bennée 2026-05-28 10:22 ` Peter Maydell 2026-05-18 16:14 ` [PATCH 2/3] target/arm/tcg: add PAC related instructions Torbjörn SVENSSON 2026-05-27 13:33 ` Alex Bennée 2026-05-28 10:40 ` Peter Maydell 2026-05-18 16:14 ` [PATCH 3/3] target/arm: implement v8.1-m PAC support Torbjörn SVENSSON 2026-05-27 13:55 ` Alex Bennée 2026-05-27 16:38 ` Peter Maydell 2026-05-28 10:43 ` Peter Maydell 2026-05-27 7:36 ` [PING] [PATCH 0/3] target/arm: add support for Cortex-M pointer authentication code Torbjorn SVENSSON 2026-05-27 12:58 ` Alex Bennée 2026-05-28 10:50 ` Peter Maydell
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.