[PATCH v2 0/2] target/arm: implement FEAT_RNG_TRAP

Jason Wright posted 2 patches 6 days, 16 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260524002617.69593-1-wrigjl@proton.me
Maintainers: Peter Maydell <peter.maydell@linaro.org>
There is a newer version of this series
target/arm/cpu-features.h |  5 +++++
target/arm/helper.c       | 26 +++++++++++++++++++++++---
target/arm/tcg/cpu64.c    |  1 +
3 files changed, 29 insertions(+), 3 deletions(-)
[PATCH v2 0/2] target/arm: implement FEAT_RNG_TRAP
Posted by Jason Wright 6 days, 16 hours ago
Implement FEAT_RNG_TRAP for RNDR/RNDRRS and enable it on cortex-max.

v2:
  - access_rndr: return CP_ACCESS_UNDEFINED when FEAT_RNG_TRAP is
    present but FEAT_RNG is not and the trap is disabled (Richard
    Henderson)
  - Register rndr_reginfo when either FEAT_RNG or FEAT_RNG_TRAP is
    implemented, not only FEAT_RNG (Richard Henderson)
  - Fix document number typo in Patch 1 commit message

Jason Wright (2):
  target/arm: implement FEAT_RNG_TRAP for RNDR/RNDRRS
  target/arm: advertise FEAT_RNG_TRAP on cortex-max

 target/arm/cpu-features.h |  5 +++++
 target/arm/helper.c       | 26 +++++++++++++++++++++++---
 target/arm/tcg/cpu64.c    |  1 +
 3 files changed, 29 insertions(+), 3 deletions(-)

-- 
2.50.1 (Apple Git-155)
[PATCH v3 0/2] target/arm: implement FEAT_RNG_TRAP
Posted by Jason Wright 1 day, 22 hours ago
Implement FEAT_RNG_TRAP for RNDR/RNDRRS and enable it on cortex-max.

v3:
  - helper.c: give ID_AA64ISAR0_EL1 a readfn so that ID_AA64ISAR0_EL1.RNDR
    reads as 1 whenever SCR_EL3.TRNDR is set, regardless of whether
    FEAT_RNG is implemented (Peter Maydell)
  - cpu64.c: keep the ID_AA64PFR1 fields in register bit-field order;
    RNDR_TRAP now sits after SME and before CSV2_FRAC (Peter Maydell)
  - docs: list FEAT_RNG_TRAP in docs/system/arm/emulation.rst (Peter
    Maydell)

v2:
  - access_rndr: return CP_ACCESS_UNDEFINED when FEAT_RNG_TRAP is
    present but FEAT_RNG is not and the trap is disabled (Richard
    Henderson)
  - Register rndr_reginfo when either FEAT_RNG or FEAT_RNG_TRAP is
    implemented, not only FEAT_RNG (Richard Henderson)
  - Fix document number typo in Patch 1 commit message

Jason Wright (2):
  target/arm: implement FEAT_RNG_TRAP for RNDR/RNDRRS
  target/arm: advertise FEAT_RNG_TRAP on cortex-max

 docs/system/arm/emulation.rst |  1 +
 target/arm/cpu-features.h     |  5 +++
 target/arm/helper.c           | 58 ++++++++++++++++++++++++++++++++---
 target/arm/tcg/cpu64.c        |  1 +
 4 files changed, 60 insertions(+), 5 deletions(-)

-- 
2.50.1 (Apple Git-155)
Re: [PATCH v3 0/2] target/arm: implement FEAT_RNG_TRAP
Posted by Peter Maydell 1 day, 8 hours ago
On Thu, 28 May 2026 at 19:19, Jason Wright <wrigjl@proton.me> wrote:
>
> Implement FEAT_RNG_TRAP for RNDR/RNDRRS and enable it on cortex-max.
>
> v3:
>   - helper.c: give ID_AA64ISAR0_EL1 a readfn so that ID_AA64ISAR0_EL1.RNDR
>     reads as 1 whenever SCR_EL3.TRNDR is set, regardless of whether
>     FEAT_RNG is implemented (Peter Maydell)
>   - cpu64.c: keep the ID_AA64PFR1 fields in register bit-field order;
>     RNDR_TRAP now sits after SME and before CSV2_FRAC (Peter Maydell)
>   - docs: list FEAT_RNG_TRAP in docs/system/arm/emulation.rst (Peter
>     Maydell)
>
> v2:
>   - access_rndr: return CP_ACCESS_UNDEFINED when FEAT_RNG_TRAP is
>     present but FEAT_RNG is not and the trap is disabled (Richard
>     Henderson)
>   - Register rndr_reginfo when either FEAT_RNG or FEAT_RNG_TRAP is
>     implemented, not only FEAT_RNG (Richard Henderson)
>   - Fix document number typo in Patch 1 commit message
>
> Jason Wright (2):
>   target/arm: implement FEAT_RNG_TRAP for RNDR/RNDRRS
>   target/arm: advertise FEAT_RNG_TRAP on cortex-max



Applied to target-arm.next, thanks.

-- PMM
[PATCH v3 1/2] target/arm: implement FEAT_RNG_TRAP for RNDR/RNDRRS
Posted by Jason Wright 1 day, 22 hours ago
Add an .accessfn to the RNDR and RNDRRS system registers that traps
reads to EL3 when SCR_EL3.TRNDR is set, as required by FEAT_RNG_TRAP.
Mark SCR_EL3.TRNDR (bit 40) as a writable field in scr_write() when
the CPU advertises the feature. The pseudocode in DDI0487 revision M.b
shows the trap firing from EL0, EL1, EL2, and EL3, so there is no
check of arm_current_el().

When FEAT_RNG_TRAP is implemented without FEAT_RNG, an RNDR/RNDRRS read
with SCR_EL3.TRNDR=0 should UNDEF rather than succeed; handle that case
in access_rndr(). Register the rndr_reginfo CP reg entries whenever either
FEAT_RNG or FEAT_RNG_TRAP is implemented, so the accessfn fires even on a
FEAT_RNG_TRAP-only CPU.

When SCR_EL3.TRNDR is set, ID_AA64ISAR0_EL1.RNDR reads as 1 regardless
of whether FEAT_RNG is implemented; give ID_AA64ISAR0_EL1 a readfn so it
reports this at runtime, as we already do for ID_AA64PFR0_EL1.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wright <wrigjl@proton.me>
---
 target/arm/cpu-features.h |  5 ++++
 target/arm/helper.c       | 58 +++++++++++++++++++++++++++++++++++----
 2 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index f9c979d20b..1279343540 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -908,6 +908,11 @@ static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
     return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RNDR) != 0;
 }
 
+static inline bool isar_feature_aa64_rng_trap(const ARMISARegisters *id)
+{
+    return FIELD_EX64_IDREG(id, ID_AA64PFR1, RNDR_TRAP) != 0;
+}
+
 static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
 {
     return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TLB) == 2;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 34487eeaa3..9dd8fdfa41 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -790,6 +790,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
         if (cpu_isar_feature(aa64_fpmr, cpu)) {
             valid_mask |= SCR_ENFPM;
         }
+        if (cpu_isar_feature(aa64_rng_trap, cpu)) {
+            valid_mask |= SCR_TRNDR;
+        }
     } else {
         valid_mask &= ~(SCR_RW | SCR_ST);
         if (cpu_isar_feature(aa32_ras, cpu)) {
@@ -5170,6 +5173,21 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
     }
     return pfr0;
 }
+
+static uint64_t id_aa64isar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    ARMCPU *cpu = env_archcpu(env);
+    uint64_t isar0 = GET_IDREG(&cpu->isar, ID_AA64ISAR0);
+
+    /*
+     * When FEAT_RNG_TRAP is active (SCR_EL3.TRNDR set), ID_AA64ISAR0_EL1.RNDR
+     * reads as 1 regardless of whether FEAT_RNG is implemented.
+     */
+    if (env->cp15.scr_el3 & SCR_TRNDR) {
+        isar0 = FIELD_DP64(isar0, ID_AA64ISAR0, RNDR, 1);
+    }
+    return isar0;
+}
 #endif
 
 /*
@@ -5304,6 +5322,22 @@ static const ARMCPRegInfo pauth_reginfo[] = {
       .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
 };
 
+static CPAccessResult access_rndr(CPUARMState *env, const ARMCPRegInfo *ri,
+                                  bool isread)
+{
+    if (env->cp15.scr_el3 & SCR_TRNDR) {
+        return CP_ACCESS_TRAP_EL3;
+    }
+    /*
+     * Note that FEAT_RNG_TRAP may be implemented without FEAT_RNG.
+     * In that case, if the trap is not enabled, the read undefs.
+     */
+    if (!cpu_isar_feature(aa64_rndr, env_archcpu(env))) {
+        return CP_ACCESS_UNDEFINED;
+    }
+    return CP_ACCESS_OK;
+}
+
 static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     Error *err = NULL;
@@ -5335,11 +5369,11 @@ static const ARMCPRegInfo rndr_reginfo[] = {
     { .name = "RNDR", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
       .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
-      .access = PL0_R, .readfn = rndr_readfn },
+      .access = PL0_R, .accessfn = access_rndr, .readfn = rndr_readfn },
     { .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
       .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
-      .access = PL0_R, .readfn = rndr_readfn },
+      .access = PL0_R, .accessfn = access_rndr, .readfn = rndr_readfn },
 };
 
 static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -6522,11 +6556,24 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .access = PL1_R, .type = ARM_CP_CONST,
               .accessfn = access_tid3,
               .resetvalue = 0 },
+            /*
+             * ID_AA64ISAR0_EL1 is not a plain ARM_CP_CONST in system
+             * emulation because the RNDR field depends on SCR_EL3.TRNDR
+             * at read time when FEAT_RNG_TRAP is implemented.
+             */
             { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
-              .access = PL1_R, .type = ARM_CP_CONST,
+              .access = PL1_R,
+#ifdef CONFIG_USER_ONLY
+              .type = ARM_CP_CONST,
+              .resetvalue = GET_IDREG(isar, ID_AA64ISAR0)
+#else
+              .type = ARM_CP_NO_RAW,
               .accessfn = access_tid3,
-              .resetvalue = GET_IDREG(isar, ID_AA64ISAR0)},
+              .readfn = id_aa64isar0_read,
+              .writefn = arm_cp_write_ignore
+#endif
+            },
             { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
               .access = PL1_R, .type = ARM_CP_CONST,
@@ -7454,7 +7501,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     if (cpu_isar_feature(aa64_pauth, cpu)) {
         define_arm_cp_regs(cpu, pauth_reginfo);
     }
-    if (cpu_isar_feature(aa64_rndr, cpu)) {
+    if (cpu_isar_feature(aa64_rndr, cpu) ||
+        cpu_isar_feature(aa64_rng_trap, cpu)) {
         define_arm_cp_regs(cpu, rndr_reginfo);
     }
     /* Data Cache clean instructions up to PoP */
-- 
2.50.1 (Apple Git-155)
Re: [PATCH v3 1/2] target/arm: implement FEAT_RNG_TRAP for RNDR/RNDRRS
Posted by Richard Henderson 1 day, 21 hours ago
On 5/28/26 11:19, Jason Wright wrote:
> Add an .accessfn to the RNDR and RNDRRS system registers that traps
> reads to EL3 when SCR_EL3.TRNDR is set, as required by FEAT_RNG_TRAP.
> Mark SCR_EL3.TRNDR (bit 40) as a writable field in scr_write() when
> the CPU advertises the feature. The pseudocode in DDI0487 revision M.b
> shows the trap firing from EL0, EL1, EL2, and EL3, so there is no
> check of arm_current_el().
> 
> When FEAT_RNG_TRAP is implemented without FEAT_RNG, an RNDR/RNDRRS read
> with SCR_EL3.TRNDR=0 should UNDEF rather than succeed; handle that case
> in access_rndr(). Register the rndr_reginfo CP reg entries whenever either
> FEAT_RNG or FEAT_RNG_TRAP is implemented, so the accessfn fires even on a
> FEAT_RNG_TRAP-only CPU.
> 
> When SCR_EL3.TRNDR is set, ID_AA64ISAR0_EL1.RNDR reads as 1 regardless
> of whether FEAT_RNG is implemented; give ID_AA64ISAR0_EL1 a readfn so it
> reports this at runtime, as we already do for ID_AA64PFR0_EL1.
> 
> Suggested-by: Richard Henderson<richard.henderson@linaro.org>
> Suggested-by: Peter Maydell<peter.maydell@linaro.org>
> Signed-off-by: Jason Wright<wrigjl@proton.me>
> ---
>   target/arm/cpu-features.h |  5 ++++
>   target/arm/helper.c       | 58 +++++++++++++++++++++++++++++++++++----
>   2 files changed, 58 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
[PATCH v3 2/2] target/arm: advertise FEAT_RNG_TRAP on cortex-max
Posted by Jason Wright 1 day, 22 hours ago
Set ID_AA64PFR1.RNDR_TRAP=1 on the max CPU model so guests and
firmware detect FEAT_RNG_TRAP, per the Arm Architecture Reference
Manual for A-profile architecture (DDI 0487), and document the feature
as emulated in docs/system/arm/emulation.rst.

Signed-off-by: Jason Wright <wrigjl@proton.me>
---
 docs/system/arm/emulation.rst | 1 +
 target/arm/tcg/cpu64.c        | 1 +
 2 files changed, 2 insertions(+)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index e44b3016be..9ccc20b696 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -135,6 +135,7 @@ the following architecture extensions:
 - FEAT_RME (Realm Management Extension) (NB: support status in QEMU is experimental)
 - FEAT_RME_GPC2 (RME Granule Protection Check 2 Extension)
 - FEAT_RNG (Random number generator)
+- FEAT_RNG_TRAP (Trapping support for RNDR/RNDRRS)
 - FEAT_RPRES (Increased precision of FRECPE and FRSQRTE)
 - FEAT_S1PIE (Stage 1 permission indirections)
 - FEAT_S2PIE (Stage 2 permission indirections)
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index a377f67b9c..6d82139015 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1292,6 +1292,7 @@ void aarch64_max_tcg_initfn(Object *obj)
     t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3);       /* FEAT_MTE3 */
     t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0);  /* FEAT_RASv1p1 + FEAT_DoubleFault */
     t = FIELD_DP64(t, ID_AA64PFR1, SME, 2);       /* FEAT_SME2 */
+    t = FIELD_DP64(t, ID_AA64PFR1, RNDR_TRAP, 1); /* FEAT_RNG_TRAP */
     t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
     t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1);       /* FEAT_NMI */
     t = FIELD_DP64(t, ID_AA64PFR1, GCS, 1);       /* FEAT_GCS */
-- 
2.50.1 (Apple Git-155)
Re: [PATCH v3 2/2] target/arm: advertise FEAT_RNG_TRAP on cortex-max
Posted by Richard Henderson 1 day, 21 hours ago
On 5/28/26 11:19, Jason Wright wrote:
> Set ID_AA64PFR1.RNDR_TRAP=1 on the max CPU model so guests and
> firmware detect FEAT_RNG_TRAP, per the Arm Architecture Reference
> Manual for A-profile architecture (DDI 0487), and document the feature
> as emulated in docs/system/arm/emulation.rst.
> 
> Signed-off-by: Jason Wright<wrigjl@proton.me>
> ---
>   docs/system/arm/emulation.rst | 1 +
>   target/arm/tcg/cpu64.c        | 1 +
>   2 files changed, 2 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~