[PATCH] target/arm: fix TTA instruction S bit for IDAU-exempt addresses

Alexandre Frey posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/ZR6PR04MB44238851A057F385D7EECEAD3599AE2@ZR6PR04MB442388.eurprd04.prod.outlook.com
Maintainers: Peter Maydell <peter.maydell@linaro.org>
target/arm/tcg/m_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] target/arm: fix TTA instruction S bit for IDAU-exempt addresses
Posted by Alexandre Frey 1 month ago
The TTA (Test Target Alternate Domain) instruction is specific to
ARMv8-M processors with the Security Extension (TrustZone). It allows
Secure code to query the security attributes and access permissions of
a memory address as seen from the Non-secure domain, and is typically
used by Secure code to validate pointers received from Non-secure
callers before dereferencing them.

The TTA instruction incorrectly reports the S bit (bit 22) of the
result register for IDAU-exempt addresses when executed from Secure
state.

According to the ARMv8-M Architecture Reference Manual (DDI0553B.z),
the TTResp() pseudocode (E2.1.408) always calls SecurityCheck() with
the current security state, regardless of the alt flag:

  sAttributes = SecurityCheck(address, FALSE, IsSecure());

The alt flag only affects which MPU bank is queried for the R/RW/MREGION
fields. It does not affect the SAU/IDAU security attribute lookup that
determines the S bit.

For an IDAU-exempt address, SecurityCheck() (E2.1.366) sets:

  result.ns = !isSecure;  // isSecure = current CPU security state

So TTA executed from Secure state on an IDAU-exempt address should
return S=1. This is confirmed by testing on real Cortex-M33 hardware.

QEMU currently passes targetsec (which is flipped to !env->v7m.secure
when alt=true) to v8m_security_lookup(), causing the IDAU-exempt path
to set sattrs->ns = TRUE and return S=0 instead.

Fix this by always passing the current security state to
v8m_security_lookup(), as the spec requires.

Signed-off-by: Alexandre Frey <alexandre.frey@nxp.com>
---
 target/arm/tcg/m_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
index f4ba93b..12ec191 100644
--- a/target/arm/tcg/m_helper.c
+++ b/target/arm/tcg/m_helper.c
@@ -2870,7 +2870,7 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
 
     if (env->v7m.secure) {
         v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
-                            targetsec, &sattrs);
+                            env->v7m.secure, &sattrs);
         nsr = sattrs.ns && r;
         nsrw = sattrs.ns && rw;
     } else {
-- 
2.43.0
Re: [PATCH] target/arm: fix TTA instruction S bit for IDAU-exempt addresses
Posted by Peter Maydell 1 month ago
On Wed, 26 Aug 2026 at 17:55, Alexandre Frey <alexandre.frey@nxp.com> wrote:
>
> The TTA (Test Target Alternate Domain) instruction is specific to
> ARMv8-M processors with the Security Extension (TrustZone). It allows
> Secure code to query the security attributes and access permissions of
> a memory address as seen from the Non-secure domain, and is typically
> used by Secure code to validate pointers received from Non-secure
> callers before dereferencing them.
>
> The TTA instruction incorrectly reports the S bit (bit 22) of the
> result register for IDAU-exempt addresses when executed from Secure
> state.
>
> According to the ARMv8-M Architecture Reference Manual (DDI0553B.z),
> the TTResp() pseudocode (E2.1.408) always calls SecurityCheck() with
> the current security state, regardless of the alt flag:
>
>   sAttributes = SecurityCheck(address, FALSE, IsSecure());
>
> The alt flag only affects which MPU bank is queried for the R/RW/MREGION
> fields. It does not affect the SAU/IDAU security attribute lookup that
> determines the S bit.
>
> For an IDAU-exempt address, SecurityCheck() (E2.1.366) sets:
>
>   result.ns = !isSecure;  // isSecure = current CPU security state
>
> So TTA executed from Secure state on an IDAU-exempt address should
> return S=1. This is confirmed by testing on real Cortex-M33 hardware.
>
> QEMU currently passes targetsec (which is flipped to !env->v7m.secure
> when alt=true) to v8m_security_lookup(), causing the IDAU-exempt path
> to set sattrs->ns = TRUE and return S=0 instead.
>
> Fix this by always passing the current security state to
> v8m_security_lookup(), as the spec requires.
>
> Signed-off-by: Alexandre Frey <alexandre.frey@nxp.com>
> ---
>  target/arm/tcg/m_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
> index f4ba93b..12ec191 100644
> --- a/target/arm/tcg/m_helper.c
> +++ b/target/arm/tcg/m_helper.c
> @@ -2870,7 +2870,7 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
>
>      if (env->v7m.secure) {
>          v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
> -                            targetsec, &sattrs);
> +                            env->v7m.secure, &sattrs);
>          nsr = sattrs.ns && r;
>          nsrw = sattrs.ns && rw;
>      } else {

Applied to target-arm.next, thanks (and cc'd for stable backports).
I added a brief comment
        /* Note that security check is done as Secure even if alt is true */
for the benefit of future readers of the function.

thanks
-- PMM