All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: "Torbjörn SVENSSON" <torbjorn.svensson@foss.st.com>
Cc: <qemu-devel@nongnu.org>,
	 Peter Maydell <peter.maydell@linaro.org>, <qemu-arm@nongnu.org>
Subject: Re: [PATCH 3/3] target/arm: implement v8.1-m PAC support
Date: Wed, 27 May 2026 14:55:48 +0100	[thread overview]
Message-ID: <875x49x8gr.fsf@draig.linaro.org> (raw)
In-Reply-To: <20260518-pr-pacbti-v1-3-8932a885b03d@foss.st.com> ("Torbjörn SVENSSON"'s message of "Mon, 18 May 2026 18:14:01 +0200")

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


  reply	other threads:[~2026-05-27 13:56 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=875x49x8gr.fsf@draig.linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=torbjorn.svensson@foss.st.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.