qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu
@ 2025-07-11 14:08 Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 1/6] target/arm: Add the MECEn SCR_EL3 bit Gustavo Romero
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

Since v4:

- Moved MECID_WIDTH from cpu.h to internal.h
- Fixed stray ';'s in access and write functions
- Use of GET_IDREG/FIELD_DP64/SET_IDREG for setting feature in ID regs
- Sorted correctly isar_feature_aa64_* AA64MMFR3 tests
- Simplified/unified accessfn for cache instructions
- Fixed how cache instruction-related registers are registered in the cpu

Since v5:

- Fixed missing checks for ARM_FEATURE_EL3 in sctlr2_el2_access and
  tcr2_el2_access functions

Since v6:
 
- Added missing feature checks in aliases[] that made 'make check' fail in v6 (pmm)
- Set feature bits in SCR_EL3 in arm_emulate_firmware_reset for Linux (pmm)
- Rebased on pmm's target-arm.next

v1: https://mail.gnu.org/archive/html/qemu-devel/2025-06/msg04598.html 
v2: https://mail.gnu.org/archive/html/qemu-devel/2025-07/msg01799.html
v3: https://mail.gnu.org/archive/html/qemu-devel/2025-07/msg02338.html
v4: https://mail.gnu.org/archive/html/qemu-devel/2025-07/msg02488.html
v5: https://mail.gnu.org/archive/html/qemu-devel/2025-07/msg02689.html
v6: https://mail.gnu.org/archive/html/qemu-devel/2025-07/msg02731.html


This series adds support for all FEAT_MEC registers and cache instructions to
the Arm64 max CPU.

It includes the FEAT_MEC registers and cache maintenance instructions, but does
not modify the translation regimes to support the MECIDs, so no encryption is
supported yet. However, software stacks that rely on FEAT_MEC should work
properly at this point.

I'm currently exploring possibilities to support FEAT_MEC encryption (or
obfuscation, for testing purposes) in QEMU for the various translation regimes
on arm64, hence the encryption part of FEAT_MEC will be contributed later and is
not targeted for QEMU 10.1.


Cheers,
Gustavo

Gustavo Romero (6):
  target/arm: Add the MECEn SCR_EL3 bit
  target/arm: Add FEAT_MEC registers
  target/arm: Add FEAT_SCTLR2
  target/arm: Add FEAT_TCR2
  target/arm: Implement FEAT_MEC cache instructions
  target/arm: Advertise FEAT_MEC in cpu max

 docs/system/arm/emulation.rst |   5 +
 target/arm/cpu-features.h     |  15 +++
 target/arm/cpu.c              |   9 ++
 target/arm/cpu.h              |  27 ++++
 target/arm/helper.c           | 236 ++++++++++++++++++++++++++++++++++
 target/arm/internals.h        |  23 ++++
 target/arm/tcg/cpu64.c        |   7 +-
 7 files changed, 321 insertions(+), 1 deletion(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v7 1/6] target/arm: Add the MECEn SCR_EL3 bit
  2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
@ 2025-07-11 14:08 ` Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 2/6] target/arm: Add FEAT_MEC registers Gustavo Romero
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

The MECEn bit in SCR_EL3 enables access to the EL2 MECID registers from
EL2, so add it to the SCR mask list to use it later on.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index dc9b6dce4c..ffc91d6b49 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1713,6 +1713,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_TRNDR             (1ULL << 40)
 #define SCR_ENTP2             (1ULL << 41)
 #define SCR_GPF               (1ULL << 48)
+#define SCR_MECEN             (1ULL << 49)
 #define SCR_NSE               (1ULL << 62)
 
 /* Return the current FPSCR value.  */
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 2/6] target/arm: Add FEAT_MEC registers
  2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 1/6] target/arm: Add the MECEn SCR_EL3 bit Gustavo Romero
@ 2025-07-11 14:08 ` Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 3/6] target/arm: Add FEAT_SCTLR2 Gustavo Romero
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

Add all FEAT_MEC registers.

To work properly, FEAT_MEC also depends on FEAT_SCTLR2 and FEAT_TCR2,
which are not implemented in this commit. The bits in SCTLR2 and TCR2
control which translation regimes use MECIDs, and determine which MECID
is selected and will be implemented in subsequent commits.

FEAT_MEC also requires two new cache management instructions, not
included in this commit, that will be implemented in a subsequent commit.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu-features.h |  5 +++
 target/arm/cpu.c          |  3 ++
 target/arm/cpu.h          |  9 +++++
 target/arm/helper.c       | 70 +++++++++++++++++++++++++++++++++++++++
 target/arm/internals.h    |  3 ++
 5 files changed, 90 insertions(+)

diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 5876162428..72b6fd9b27 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -904,6 +904,11 @@ static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
     return FIELD_EX64_IDREG(id, ID_AA64MMFR2, NV) >= 2;
 }
 
+static inline bool isar_feature_aa64_mec(const ARMISARegisters *id)
+{
+    return FIELD_EX64_IDREG(id, ID_AA64MMFR3, MEC) != 0;
+}
+
 static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
 {
     return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 4 &&
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 08c43f674a..8da8d13e4c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -645,6 +645,9 @@ void arm_emulate_firmware_reset(CPUState *cpustate, int target_el)
             if (cpu_isar_feature(aa64_fgt, cpu)) {
                 env->cp15.scr_el3 |= SCR_FGTEN;
             }
+            if (cpu_isar_feature(aa64_mec, cpu)) {
+                env->cp15.scr_el3 |= SCR_MECEN;
+            }
         }
 
         if (target_el == 2) {
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ffc91d6b49..e3975e687e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -576,6 +576,15 @@ typedef struct CPUArchState {
 
         /* NV2 register */
         uint64_t vncr_el2;
+
+        /* MEC registers */
+        uint64_t mecid_p0_el2;
+        uint64_t mecid_a0_el2;
+        uint64_t mecid_p1_el2;
+        uint64_t mecid_a1_el2;
+        uint64_t mecid_rl_a_el3;
+        uint64_t vmecid_p_el2;
+        uint64_t vmecid_a_el2;
     } cp15;
 
     struct {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0c1299ff84..bb974647ba 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5196,6 +5196,72 @@ static const ARMCPRegInfo nmi_reginfo[] = {
       .resetfn = arm_cp_reset_ignore },
 };
 
+static CPAccessResult mecid_access(CPUARMState *env,
+                                   const ARMCPRegInfo *ri, bool isread)
+{
+    int el = arm_current_el(env);
+
+    if (el == 2) {
+        if (arm_security_space(env) != ARMSS_Realm) {
+	    return CP_ACCESS_UNDEFINED;
+	}
+
+        if (!(env->cp15.scr_el3 & SCR_MECEN)) {
+            return CP_ACCESS_TRAP_EL3;
+        }
+    }
+
+    return CP_ACCESS_OK;
+}
+
+static void mecid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
+{
+    value = extract64(value, 0, MECID_WIDTH);
+    raw_write(env, ri, value);
+}
+
+static const ARMCPRegInfo mec_reginfo[] = {
+    { .name = "MECIDR_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 7, .crn = 10, .crm = 8,
+      .access = PL2_R, .type = ARM_CP_CONST, .resetvalue = MECID_WIDTH - 1 },
+    { .name = "MECID_P0_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 0, .crn = 10, .crm = 8,
+      .access = PL2_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.mecid_p0_el2) },
+    { .name = "MECID_A0_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 1, .crn = 10, .crm = 8,
+      .access = PL2_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.mecid_a0_el2) },
+    { .name = "MECID_P1_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 2, .crn = 10, .crm = 8,
+      .access = PL2_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.mecid_p1_el2) },
+    { .name = "MECID_A1_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 3, .crn = 10, .crm = 8,
+      .access = PL2_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.mecid_a1_el2) },
+    { .name = "MECID_RL_A_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 6, .opc2 = 1, .crn = 10, .crm = 10,
+      .access = PL3_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.mecid_rl_a_el3) },
+    { .name = "VMECID_P_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 0, .crn = 10, .crm = 9,
+      .access = PL2_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.vmecid_p_el2) },
+    { .name = "VMECID_A_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 1, .crn = 10, .crm = 9,
+      .access = PL2_RW, .accessfn = mecid_access,
+      .writefn = mecid_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.vmecid_a_el2) },
+};
+
 #ifndef CONFIG_USER_ONLY
 /*
  * We don't know until after realize whether there's a GICv3
@@ -7223,6 +7289,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, nmi_reginfo);
     }
 
+    if (cpu_isar_feature(aa64_mec, cpu)) {
+        define_arm_cp_regs(cpu, mec_reginfo);
+    }
+
     if (cpu_isar_feature(any_predinv, cpu)) {
         define_arm_cp_regs(cpu, predinv_reginfo);
     }
diff --git a/target/arm/internals.h b/target/arm/internals.h
index c4765e4489..43cddd95b4 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1987,4 +1987,7 @@ void vfp_clear_float_status_exc_flags(CPUARMState *env);
 void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask);
 bool arm_pan_enabled(CPUARMState *env);
 
+/* Used in FEAT_MEC to set the MECIDWidthm1 field in the MECIDR_EL2 register. */
+#define MECID_WIDTH 16
+
 #endif
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 3/6] target/arm: Add FEAT_SCTLR2
  2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 1/6] target/arm: Add the MECEn SCR_EL3 bit Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 2/6] target/arm: Add FEAT_MEC registers Gustavo Romero
@ 2025-07-11 14:08 ` Gustavo Romero
       [not found]   ` <09497926-db8a-4475-b361-7e8338597326@linaro.org>
  2025-07-11 14:08 ` [PATCH v7 4/6] target/arm: Add FEAT_TCR2 Gustavo Romero
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

Add FEAT_SCTLR2, which introduces the SCTLR2_EL1, SCTLR2_EL2, and
SCTLR2_EL3 registers. These registers are extensions of the SCTLR_ELx
ones.

Because the bits in these registers depend on other CPU features, and
only FEAT_MEC is supported at the moment, this commit only implements
the EMEC bits in CTLR2_EL2 and SCTLR2_EL3.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 docs/system/arm/emulation.rst |  1 +
 target/arm/cpu-features.h     |  5 +++
 target/arm/cpu.c              |  3 ++
 target/arm/cpu.h              | 15 +++++++
 target/arm/helper.c           | 80 +++++++++++++++++++++++++++++++++++
 target/arm/internals.h        |  1 +
 target/arm/tcg/cpu64.c        |  5 ++-
 7 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 890dc6fee2..66043b0747 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -121,6 +121,7 @@ the following architecture extensions:
 - FEAT_RPRES (Increased precision of FRECPE and FRSQRTE)
 - FEAT_S2FWB (Stage 2 forced Write-Back)
 - FEAT_SB (Speculation Barrier)
+- FEAT_SCTLR2 (Extension to SCTLR_ELx)
 - FEAT_SEL2 (Secure EL2)
 - FEAT_SHA1 (SHA1 instructions)
 - FEAT_SHA256 (SHA256 instructions)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 72b6fd9b27..a5fc2ca572 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -904,6 +904,11 @@ static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
     return FIELD_EX64_IDREG(id, ID_AA64MMFR2, NV) >= 2;
 }
 
+static inline bool isar_feature_aa64_sctlr2(const ARMISARegisters *id)
+{
+    return FIELD_EX64_IDREG(id, ID_AA64MMFR3, SCTLRX) != 0;
+}
+
 static inline bool isar_feature_aa64_mec(const ARMISARegisters *id)
 {
     return FIELD_EX64_IDREG(id, ID_AA64MMFR3, MEC) != 0;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 8da8d13e4c..2a89dc90c0 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -645,6 +645,9 @@ void arm_emulate_firmware_reset(CPUState *cpustate, int target_el)
             if (cpu_isar_feature(aa64_fgt, cpu)) {
                 env->cp15.scr_el3 |= SCR_FGTEN;
             }
+            if (cpu_isar_feature(aa64_sctlr2, cpu)) {
+                env->cp15.scr_el3 |= SCR_SCTLR2EN;
+            }
             if (cpu_isar_feature(aa64_mec, cpu)) {
                 env->cp15.scr_el3 |= SCR_MECEN;
             }
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e3975e687e..af83a16b7e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -337,6 +337,7 @@ typedef struct CPUArchState {
             };
             uint64_t sctlr_el[4];
         };
+        uint64_t sctlr2_el[4]; /* Extension to System control register. */
         uint64_t vsctlr; /* Virtualization System control register. */
         uint64_t cpacr_el1; /* Architectural feature access control register */
         uint64_t cptr_el[4];  /* ARMv8 feature trap registers */
@@ -1429,6 +1430,19 @@ void pmu_init(ARMCPU *cpu);
 #define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
 #define SCTLR_TIDCP   (1ULL << 63) /* FEAT_TIDCP1 */
 
+#define SCTLR2_EMEC (1ULL << 1) /* FEAT_MEC */
+#define SCTLR2_NMEA (1ULL << 2) /* FEAT_DoubleFault2 */
+#define SCTLR2_ENADERR (1ULL << 3) /* FEAT_ADERR */
+#define SCTLR2_ENANERR (1ULL << 4) /* FEAT_ANERR */
+#define SCTLR2_EASE (1ULL << 5) /* FEAT_DoubleFault2 */
+#define SCTLR2_ENIDCP128 (1ULL << 6) /* FEAT_SYSREG128 */
+#define SCTLR2_ENPACM (1ULL << 7) /* FEAT_PAuth_LR */
+#define SCTLR2_ENPACM0 (1ULL << 8 /* FEAT_PAuth_LR */
+#define SCTLR2_CPTA (1ULL << 9) /* FEAT_CPA2 */
+#define SCTLR2_CPTA0 (1ULL << 10) /* FEAT_CPA2 */
+#define SCTLR2_CPTM (1ULL << 11) /* FEAT_CPA2 */
+#define SCTLR2_CPTM0 (1ULL << 12) /* FEAT_CAP2 */
+
 #define CPSR_M (0x1fU)
 #define CPSR_T (1U << 5)
 #define CPSR_F (1U << 6)
@@ -1721,6 +1735,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_HXEN              (1ULL << 38)
 #define SCR_TRNDR             (1ULL << 40)
 #define SCR_ENTP2             (1ULL << 41)
+#define SCR_SCTLR2EN          (1ULL << 44)
 #define SCR_GPF               (1ULL << 48)
 #define SCR_MECEN             (1ULL << 49)
 #define SCR_NSE               (1ULL << 62)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bb974647ba..6c32bfcae5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4513,6 +4513,8 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
     static const struct E2HAlias aliases[] = {
         { K(3, 0,  1, 0, 0), K(3, 4,  1, 0, 0), K(3, 5, 1, 0, 0),
           "SCTLR", "SCTLR_EL2", "SCTLR_EL12" },
+        { K(3, 0,  1, 0, 3), K(3, 4,  1, 0, 3), K(3, 5, 1, 0, 3),
+          "SCTLR2_EL1", "SCTLR2_EL2", "SCTLR2_EL12", isar_feature_aa64_sctlr2 },
         { K(3, 0,  1, 0, 2), K(3, 4,  1, 1, 2), K(3, 5, 1, 0, 2),
           "CPACR", "CPTR_EL2", "CPACR_EL12" },
         { K(3, 0,  2, 0, 0), K(3, 4,  2, 0, 0), K(3, 5, 2, 0, 0),
@@ -6060,6 +6062,80 @@ static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
       .resetvalue = 0 },
 };
 
+static CPAccessResult sctlr2_el2_access(CPUARMState *env,
+                                        const ARMCPRegInfo *ri,
+                                        bool isread)
+{
+    if (arm_current_el(env) < 3
+        && arm_feature(env, ARM_FEATURE_EL3)
+        && !(env->cp15.scr_el3 & SCR_SCTLR2EN)) {
+        return CP_ACCESS_TRAP_EL3;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult sctlr2_el1_access(CPUARMState *env,
+                                        const ARMCPRegInfo *ri,
+                                        bool isread)
+{
+    CPAccessResult ret = access_tvm_trvm(env, ri, isread);
+    if (ret != CP_ACCESS_OK) {
+        return ret;
+    }
+    if (arm_current_el(env) < 2 && !(arm_hcrx_el2_eff(env) & HCRX_SCTLR2EN)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    return sctlr2_el2_access(env, ri, isread);
+}
+
+static void sctlr2_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    /* This register does not control any feature yet. */
+}
+
+static void sctlr2_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    uint64_t valid_mask = 0;
+
+    if (cpu_isar_feature(aa64_mec, env_archcpu(env))) {
+        valid_mask |= SCTLR2_EMEC;
+    }
+    value &= valid_mask;
+    raw_write(env, ri, value);
+}
+
+static void sctlr2_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    uint64_t valid_mask = 0;
+
+    if (cpu_isar_feature(aa64_mec, env_archcpu(env))) {
+        valid_mask |= SCTLR2_EMEC;
+    }
+    value &= valid_mask;
+    raw_write(env, ri, value);
+}
+
+static const ARMCPRegInfo sctlr2_reginfo[] = {
+    { .name = "SCTLR2_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .opc2 = 3, .crn = 1, .crm = 0,
+      .access = PL1_RW, .accessfn = sctlr2_el1_access,
+      .writefn = sctlr2_el1_write, .fgt = FGT_SCTLR_EL1,
+      .nv2_redirect_offset = 0x278 | NV2_REDIR_NV1,
+      .fieldoffset = offsetof(CPUARMState, cp15.sctlr2_el[1]) },
+    { .name = "SCTLR2_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 3, .crn = 1, .crm = 0,
+      .access = PL2_RW, .accessfn = sctlr2_el2_access,
+      .writefn = sctlr2_el2_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.sctlr2_el[2]) },
+    { .name = "SCTLR2_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 6, .opc2 = 3, .crn = 1, .crm = 0,
+      .access = PL3_RW, .writefn = sctlr2_el3_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.sctlr2_el[3]) },
+};
+
 void register_cp_regs_for_features(ARMCPU *cpu)
 {
     /* Register all the coprocessor registers based on feature bits */
@@ -7293,6 +7369,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, mec_reginfo);
     }
 
+    if (cpu_isar_feature(aa64_sctlr2, cpu)) {
+        define_arm_cp_regs(cpu, sctlr2_reginfo);
+    }
+
     if (cpu_isar_feature(any_predinv, cpu)) {
         define_arm_cp_regs(cpu, predinv_reginfo);
     }
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 43cddd95b4..d60d235b19 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -232,6 +232,7 @@ FIELD(VTCR, SL2, 33, 1)
 #define HCRX_CMOW     (1ULL << 9)
 #define HCRX_MCE2     (1ULL << 10)
 #define HCRX_MSCEN    (1ULL << 11)
+#define HCRX_SCTLR2EN (1ULL << 15)
 
 #define HPFAR_NS      (1ULL << 63)
 
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 35cddbafa4..f4efff03a5 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1247,7 +1247,10 @@ void aarch64_max_tcg_initfn(Object *obj)
     t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1);     /* FEAT_E0PD */
     SET_IDREG(isar, ID_AA64MMFR2, t);
 
-    FIELD_DP64_IDREG(isar, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
+    t = GET_IDREG(isar, ID_AA64MMFR3);
+    t = FIELD_DP64(t, ID_AA64MMFR3, SCTLRX, 1);     /* FEAT_SCTLR2 */
+    t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
+    SET_IDREG(isar, ID_AA64MMFR3, t);
 
     t = GET_IDREG(isar, ID_AA64ZFR0);
     t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 2);    /* FEAT_SVE2p1 */
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 4/6] target/arm: Add FEAT_TCR2
  2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
                   ` (2 preceding siblings ...)
  2025-07-11 14:08 ` [PATCH v7 3/6] target/arm: Add FEAT_SCTLR2 Gustavo Romero
@ 2025-07-11 14:08 ` Gustavo Romero
  2025-07-13 21:59   ` Richard Henderson
  2025-07-11 14:08 ` [PATCH v7 5/6] target/arm: Implement FEAT_MEC cache instructions Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 6/6] target/arm: Advertise FEAT_MEC in cpu max Gustavo Romero
  5 siblings, 1 reply; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

Add FEAT_TCR2, which introduces the TCR2_EL1 and TCR2_EL2 registers.
These registers are extensions of the TCR_ELx registers and provide
top-level control of the EL10 and EL20 translation regimes.

Since the bits in these registers depend on other CPU features, and only
FEAT_MEC is supported at the moment, the FEAT_TCR2 only implements the
AMEC bits for now.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
---
 docs/system/arm/emulation.rst |  1 +
 target/arm/cpu-features.h     |  5 +++
 target/arm/cpu.c              |  3 ++
 target/arm/cpu.h              |  2 ++
 target/arm/helper.c           | 62 +++++++++++++++++++++++++++++++++++
 target/arm/internals.h        | 19 +++++++++++
 target/arm/tcg/cpu64.c        |  1 +
 7 files changed, 93 insertions(+)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 66043b0747..1c597d8673 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -149,6 +149,7 @@ the following architecture extensions:
 - FEAT_SPECRES (Speculation restriction instructions)
 - FEAT_SSBS (Speculative Store Bypass Safe)
 - FEAT_SSBS2 (MRS and MSR instructions for SSBS version 2)
+- FEAT_TCR2 (Support for TCR2_ELx)
 - FEAT_TGran16K (Support for 16KB memory translation granule size at stage 1)
 - FEAT_TGran4K (Support for 4KB memory translation granule size at stage 1)
 - FEAT_TGran64K (Support for 64KB memory translation granule size at stage 1)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index a5fc2ca572..9579d93cec 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -904,6 +904,11 @@ static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
     return FIELD_EX64_IDREG(id, ID_AA64MMFR2, NV) >= 2;
 }
 
+static inline bool isar_feature_aa64_tcr2(const ARMISARegisters *id)
+{
+    return FIELD_EX64_IDREG(id, ID_AA64MMFR3, TCRX) != 0;
+}
+
 static inline bool isar_feature_aa64_sctlr2(const ARMISARegisters *id)
 {
     return FIELD_EX64_IDREG(id, ID_AA64MMFR3, SCTLRX) != 0;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2a89dc90c0..34638ea100 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -645,6 +645,9 @@ void arm_emulate_firmware_reset(CPUState *cpustate, int target_el)
             if (cpu_isar_feature(aa64_fgt, cpu)) {
                 env->cp15.scr_el3 |= SCR_FGTEN;
             }
+            if (cpu_isar_feature(aa64_tcr2, cpu)) {
+               env->cp15.scr_el3 |= SCR_TCR2EN;
+            }
             if (cpu_isar_feature(aa64_sctlr2, cpu)) {
                 env->cp15.scr_el3 |= SCR_SCTLR2EN;
             }
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index af83a16b7e..5156120b50 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -366,6 +366,7 @@ typedef struct CPUArchState {
         uint64_t vsttbr_el2; /* Secure Virtualization Translation Table. */
         /* MMU translation table base control. */
         uint64_t tcr_el[4];
+        uint64_t tcr2_el[3];
         uint64_t vtcr_el2; /* Virtualization Translation Control.  */
         uint64_t vstcr_el2; /* Secure Virtualization Translation Control. */
         uint32_t c2_data; /* MPU data cacheable bits.  */
@@ -1735,6 +1736,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_HXEN              (1ULL << 38)
 #define SCR_TRNDR             (1ULL << 40)
 #define SCR_ENTP2             (1ULL << 41)
+#define SCR_TCR2EN            (1ULL << 43)
 #define SCR_SCTLR2EN          (1ULL << 44)
 #define SCR_GPF               (1ULL << 48)
 #define SCR_MECEN             (1ULL << 49)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6c32bfcae5..973b276d90 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4523,6 +4523,8 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
           "TTBR1_EL1", "TTBR1_EL2", "TTBR1_EL12" },
         { K(3, 0,  2, 0, 2), K(3, 4,  2, 0, 2), K(3, 5, 2, 0, 2),
           "TCR_EL1", "TCR_EL2", "TCR_EL12" },
+        { K(3, 0,  2, 0, 3), K(3, 4,  2, 0, 3), K(3, 5, 2, 0, 3),
+          "TCR2_EL1", "TCR2_EL2", "TCR2_EL12", isar_feature_aa64_tcr2 },
         { K(3, 0,  4, 0, 0), K(3, 4,  4, 0, 0), K(3, 5, 4, 0, 0),
           "SPSR_EL1", "SPSR_EL2", "SPSR_EL12" },
         { K(3, 0,  4, 0, 1), K(3, 4,  4, 0, 1), K(3, 5, 4, 0, 1),
@@ -6136,6 +6138,62 @@ static const ARMCPRegInfo sctlr2_reginfo[] = {
       .fieldoffset = offsetof(CPUARMState, cp15.sctlr2_el[3]) },
 };
 
+static CPAccessResult tcr2_el2_access(CPUARMState *env, const ARMCPRegInfo *ri,
+                                      bool isread)
+{
+    if (arm_current_el(env) < 3
+        && arm_feature(env, ARM_FEATURE_EL3)
+        && !(env->cp15.scr_el3 & SCR_TCR2EN)) {
+        return CP_ACCESS_TRAP_EL3;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult tcr2_el1_access(CPUARMState *env, const ARMCPRegInfo *ri,
+                                      bool isread)
+{
+    CPAccessResult ret = access_tvm_trvm(env, ri, isread);
+    if (ret != CP_ACCESS_OK) {
+        return ret;
+    }
+    if (arm_current_el(env) < 2 && !(arm_hcrx_el2_eff(env) & HCRX_TCR2EN)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    return tcr2_el2_access(env, ri, isread);
+}
+
+static void tcr2_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
+{
+    /* This register does not control any feature yet. */
+}
+
+static void tcr2_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
+{
+    uint64_t valid_mask = 0;
+
+    if (cpu_isar_feature(aa64_mec, env_archcpu(env))) {
+        valid_mask |= TCR2_AMEC0 | TCR2_AMEC1;
+    }
+    value &= valid_mask;
+    raw_write(env, ri, value);
+}
+
+static const ARMCPRegInfo tcr2_reginfo[] = {
+    { .name = "TCR2_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .opc2 = 3, .crn = 2, .crm = 0,
+      .access = PL1_RW, .accessfn = tcr2_el1_access,
+      .writefn = tcr2_el1_write, .fgt = FGT_TCR_EL1,
+      .nv2_redirect_offset = 0x270 | NV2_REDIR_NV1,
+      .fieldoffset = offsetof(CPUARMState, cp15.tcr2_el[1]) },
+    { .name = "TCR2_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 4, .opc2 = 3, .crn = 2, .crm = 0,
+      .access = PL2_RW, .accessfn = tcr2_el2_access,
+      .writefn = tcr2_el2_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.tcr2_el[2]) },
+};
+
 void register_cp_regs_for_features(ARMCPU *cpu)
 {
     /* Register all the coprocessor registers based on feature bits */
@@ -7373,6 +7431,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, sctlr2_reginfo);
     }
 
+    if (cpu_isar_feature(aa64_tcr2, cpu)) {
+        define_arm_cp_regs(cpu, tcr2_reginfo);
+    }
+
     if (cpu_isar_feature(any_predinv, cpu)) {
         define_arm_cp_regs(cpu, predinv_reginfo);
     }
diff --git a/target/arm/internals.h b/target/arm/internals.h
index d60d235b19..6c1112e641 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -201,6 +201,24 @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
 #define TTBCR_SH1    (1U << 28)
 #define TTBCR_EAE    (1U << 31)
 
+#define TCR2_PNCH    (1ULL << 0)
+#define TCR2_PIE     (1ULL << 1)
+#define TCR2_E0POE   (1ULL << 2)
+#define TCR2_POE     (1ULL << 3)
+#define TCR2_AIE     (1ULL << 4)
+#define TCR2_D128    (1ULL << 5)
+#define TCR2_PTTWI   (1ULL << 10)
+#define TCR2_HAFT    (1ULL << 11)
+#define TCR2_AMEC0   (1ULL << 12)
+#define TCR2_AMEC1   (1ULL << 13)
+#define TCR2_DISCH0  (1ULL << 14)
+#define TCR2_DISCH1  (1ULL << 15)
+#define TCR2_A2      (1ULL << 16)
+#define TCR2_FNG0    (1ULL << 17)
+#define TCR2_FNG1    (1ULL << 18)
+#define TCR2_FNGNA0  (1ULL << 20)
+#define TCR2_FNGNA1  (1ULL << 21)
+
 FIELD(VTCR, T0SZ, 0, 6)
 FIELD(VTCR, SL0, 6, 2)
 FIELD(VTCR, IRGN0, 8, 2)
@@ -232,6 +250,7 @@ FIELD(VTCR, SL2, 33, 1)
 #define HCRX_CMOW     (1ULL << 9)
 #define HCRX_MCE2     (1ULL << 10)
 #define HCRX_MSCEN    (1ULL << 11)
+#define HCRX_TCR2EN   (1ULL << 14)
 #define HCRX_SCTLR2EN (1ULL << 15)
 
 #define HPFAR_NS      (1ULL << 63)
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index f4efff03a5..4eb51420ef 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1248,6 +1248,7 @@ void aarch64_max_tcg_initfn(Object *obj)
     SET_IDREG(isar, ID_AA64MMFR2, t);
 
     t = GET_IDREG(isar, ID_AA64MMFR3);
+    t = FIELD_DP64(t, ID_AA64MMFR3, TCRX, 1);       /* FEAT_TCR2 */
     t = FIELD_DP64(t, ID_AA64MMFR3, SCTLRX, 1);     /* FEAT_SCTLR2 */
     t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
     SET_IDREG(isar, ID_AA64MMFR3, t);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 5/6] target/arm: Implement FEAT_MEC cache instructions
  2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
                   ` (3 preceding siblings ...)
  2025-07-11 14:08 ` [PATCH v7 4/6] target/arm: Add FEAT_TCR2 Gustavo Romero
@ 2025-07-11 14:08 ` Gustavo Romero
  2025-07-11 14:08 ` [PATCH v7 6/6] target/arm: Advertise FEAT_MEC in cpu max Gustavo Romero
  5 siblings, 0 replies; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

This commit implements the two cache maintenance instructions introduced
by FEAT_MEC, DC CIPAE and DC CIGDPAE.

Because QEMU does not model the cache topology, all cache maintenance
instructions are implemented as NOPs, hence these new instructions are
implemented as NOPs too.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 973b276d90..ce981191b3 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5225,6 +5225,18 @@ static void mecid_write(CPUARMState *env, const ARMCPRegInfo *ri,
     raw_write(env, ri, value);
 }
 
+static CPAccessResult cipae_access(CPUARMState *env, const ARMCPRegInfo *ri,
+                                   bool isread)
+{
+    switch (arm_security_space(env)) {
+    case ARMSS_Root:  /* EL3 */
+    case ARMSS_Realm: /* Realm EL2 */
+        return CP_ACCESS_OK;
+    default:
+        return CP_ACCESS_UNDEFINED;
+    }
+}
+
 static const ARMCPRegInfo mec_reginfo[] = {
     { .name = "MECIDR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .opc2 = 7, .crn = 10, .crm = 8,
@@ -5264,6 +5276,15 @@ static const ARMCPRegInfo mec_reginfo[] = {
       .access = PL2_RW, .accessfn = mecid_access,
       .writefn = mecid_write,
       .fieldoffset = offsetof(CPUARMState, cp15.vmecid_a_el2) },
+    { .name = "DC_CIPAE", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 14, .opc2 = 0,
+      .access = PL2_W, .accessfn = cipae_access, .type = ARM_CP_NOP },
+};
+
+static const ARMCPRegInfo mec_mte_reginfo[] = {
+    { .name = "DC_CIGDPAE", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 14, .opc2 = 7,
+      .access = PL2_W, .accessfn = cipae_access, .type = ARM_CP_NOP },
 };
 
 #ifndef CONFIG_USER_ONLY
@@ -7425,6 +7446,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 
     if (cpu_isar_feature(aa64_mec, cpu)) {
         define_arm_cp_regs(cpu, mec_reginfo);
+        if (cpu_isar_feature(aa64_mte, cpu)) {
+            define_arm_cp_regs(cpu, mec_mte_reginfo);
+        }
     }
 
     if (cpu_isar_feature(aa64_sctlr2, cpu)) {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 6/6] target/arm: Advertise FEAT_MEC in cpu max
  2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
                   ` (4 preceding siblings ...)
  2025-07-11 14:08 ` [PATCH v7 5/6] target/arm: Implement FEAT_MEC cache instructions Gustavo Romero
@ 2025-07-11 14:08 ` Gustavo Romero
  5 siblings, 0 replies; 14+ messages in thread
From: Gustavo Romero @ 2025-07-11 14:08 UTC (permalink / raw)
  To: qemu-arm, richard.henderson, alex.bennee, peter.maydell
  Cc: qemu-devel, gustavo.romero

Advertise FEAT_MEC in AA64MMFR3 ID register for the Arm64 cpu max as a
first step to fully support FEAT_MEC.

The FEAT_MEC is an extension to FEAT_RME that implements multiple
Memory Encryption Contexts (MEC) so the memory in a realm can be
encrypted and accessing it from the wrong encryption context is not
possible. An encryption context allow the selection of a memory
encryption engine.

At this point, no real memory encryption is supported, but software
stacks that rely on FEAT_MEC to run should work properly.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 docs/system/arm/emulation.rst | 3 +++
 target/arm/tcg/cpu64.c        | 1 +
 2 files changed, 4 insertions(+)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 1c597d8673..d207a9f266 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -89,6 +89,9 @@ the following architecture extensions:
 - FEAT_LSE (Large System Extensions)
 - FEAT_LSE2 (Large System Extensions v2)
 - FEAT_LVA (Large Virtual Address space)
+- FEAT_MEC (Memory Encryption Contexts)
+
+  * This is a register-only implementation without encryption.
 - FEAT_MixedEnd (Mixed-endian support)
 - FEAT_MixedEndEL0 (Mixed-endian support at EL0)
 - FEAT_MOPS (Standardization of memory operations)
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 4eb51420ef..c54aa528c6 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1250,6 +1250,7 @@ void aarch64_max_tcg_initfn(Object *obj)
     t = GET_IDREG(isar, ID_AA64MMFR3);
     t = FIELD_DP64(t, ID_AA64MMFR3, TCRX, 1);       /* FEAT_TCR2 */
     t = FIELD_DP64(t, ID_AA64MMFR3, SCTLRX, 1);     /* FEAT_SCTLR2 */
+    t = FIELD_DP64(t, ID_AA64MMFR3, MEC, 1);        /* FEAT_MEC */
     t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
     SET_IDREG(isar, ID_AA64MMFR3, t);
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 3/6] target/arm: Add FEAT_SCTLR2
       [not found]   ` <09497926-db8a-4475-b361-7e8338597326@linaro.org>
@ 2025-07-13 16:27     ` Richard Henderson
  2025-07-14  5:43       ` Pierrick Bouvier
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2025-07-13 16:27 UTC (permalink / raw)
  To: Gustavo Romero, Pierrick Bouvier; +Cc: qemu-devel

On 7/11/25 23:02, Richard Henderson wrote:
> On 7/11/25 08:08, Gustavo Romero wrote:
>> Add FEAT_SCTLR2, which introduces the SCTLR2_EL1, SCTLR2_EL2, and
>> SCTLR2_EL3 registers. These registers are extensions of the SCTLR_ELx
>> ones.
>>
>> Because the bits in these registers depend on other CPU features, and
>> only FEAT_MEC is supported at the moment, this commit only implements
>> the EMEC bits in CTLR2_EL2 and SCTLR2_EL3.
>>
>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   docs/system/arm/emulation.rst |  1 +
>>   target/arm/cpu-features.h     |  5 +++
>>   target/arm/cpu.c              |  3 ++
>>   target/arm/cpu.h              | 15 +++++++
>>   target/arm/helper.c           | 80 +++++++++++++++++++++++++++++++++++
>>   target/arm/internals.h        |  1 +
>>   target/arm/tcg/cpu64.c        |  5 ++-
>>   7 files changed, 109 insertions(+), 1 deletion(-)
> 
> Bisect points to this patch as breaking
> 
> 45/60 qemu:func-thorough+func-aarch64-thorough+thorough / func-aarch64-aarch64_rme_sbsaref 
>         TIMEOUT        1200.01s   killed by signal 15 SIGTERM
> 46/60 qemu:func-thorough+func-aarch64-thorough+thorough / func-aarch64-aarch64_rme_virt 
>         TIMEOUT        1200.02s   killed by signal 15 SIGTERM
> 
> Try make check-functional-aarch64.

This is caused by the realm os being new enough to try to access SCTLR2, but the op-tee 
firmware is not new enough to enable access to SCTLR2.  So Realm EL2 unexpectedly but 
correctly traps to EL3, and the whole stack gets wedged:

2025-07-13 10:16:12,680: SMC_RMI_REALM_ACTIVATE
2025-07-13 10:16:12,680: 10045c6c000 > RMI_SUCCESS
2025-07-13 10:16:12,689: Unexpected exception on CPU #0:

Pierrick, I believe you built the rme test images.  Is there perhaps a newer version of 
the firmware that supports (at least) SCTLR2 and TCR2?


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 4/6] target/arm: Add FEAT_TCR2
  2025-07-11 14:08 ` [PATCH v7 4/6] target/arm: Add FEAT_TCR2 Gustavo Romero
@ 2025-07-13 21:59   ` Richard Henderson
  2025-07-14  6:21     ` Pierrick Bouvier
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2025-07-13 21:59 UTC (permalink / raw)
  To: Gustavo Romero, qemu-arm, Pierrick Bouvier; +Cc: qemu-devel

On 7/11/25 08:08, Gustavo Romero wrote:
> Add FEAT_TCR2, which introduces the TCR2_EL1 and TCR2_EL2 registers.
> These registers are extensions of the TCR_ELx registers and provide
> top-level control of the EL10 and EL20 translation regimes.
> 
> Since the bits in these registers depend on other CPU features, and only
> FEAT_MEC is supported at the moment, the FEAT_TCR2 only implements the
> AMEC bits for now.
> 
> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
This causes a regression in tests/functional/test_aarch64_device_passthrough.py, by 
continually trapping on an access to TCR2_EL1 while the HCRX_EL2 enable bit is not set.

Unlike the similar SCTRL2 failure, it's not 100% clear to me how the guest and nested 
guest kernels are related.  But it is clear that the outer kernel does not does not 
support TCR2_EL1 (and also doesn't manipulate ID_AA64MMFR3_EL1 to hide FEAT_TCR2), but the 
nested guest kernel does support TCR2_EL1.


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 3/6] target/arm: Add FEAT_SCTLR2
  2025-07-13 16:27     ` Richard Henderson
@ 2025-07-14  5:43       ` Pierrick Bouvier
  0 siblings, 0 replies; 14+ messages in thread
From: Pierrick Bouvier @ 2025-07-14  5:43 UTC (permalink / raw)
  To: Richard Henderson, Gustavo Romero; +Cc: qemu-devel

On 7/13/25 9:27 AM, Richard Henderson wrote:
> On 7/11/25 23:02, Richard Henderson wrote:
>> On 7/11/25 08:08, Gustavo Romero wrote:
>>> Add FEAT_SCTLR2, which introduces the SCTLR2_EL1, SCTLR2_EL2, and
>>> SCTLR2_EL3 registers. These registers are extensions of the SCTLR_ELx
>>> ones.
>>>
>>> Because the bits in these registers depend on other CPU features, and
>>> only FEAT_MEC is supported at the moment, this commit only implements
>>> the EMEC bits in CTLR2_EL2 and SCTLR2_EL3.
>>>
>>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
>>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>    docs/system/arm/emulation.rst |  1 +
>>>    target/arm/cpu-features.h     |  5 +++
>>>    target/arm/cpu.c              |  3 ++
>>>    target/arm/cpu.h              | 15 +++++++
>>>    target/arm/helper.c           | 80 +++++++++++++++++++++++++++++++++++
>>>    target/arm/internals.h        |  1 +
>>>    target/arm/tcg/cpu64.c        |  5 ++-
>>>    7 files changed, 109 insertions(+), 1 deletion(-)
>>
>> Bisect points to this patch as breaking
>>
>> 45/60 qemu:func-thorough+func-aarch64-thorough+thorough / func-aarch64-aarch64_rme_sbsaref
>>          TIMEOUT        1200.01s   killed by signal 15 SIGTERM
>> 46/60 qemu:func-thorough+func-aarch64-thorough+thorough / func-aarch64-aarch64_rme_virt
>>          TIMEOUT        1200.02s   killed by signal 15 SIGTERM
>>
>> Try make check-functional-aarch64.
> 
> This is caused by the realm os being new enough to try to access SCTLR2, but the op-tee
> firmware is not new enough to enable access to SCTLR2.  So Realm EL2 unexpectedly but
> correctly traps to EL3, and the whole stack gets wedged:
> 
> 2025-07-13 10:16:12,680: SMC_RMI_REALM_ACTIVATE
> 2025-07-13 10:16:12,680: 10045c6c000 > RMI_SUCCESS
> 2025-07-13 10:16:12,689: Unexpected exception on CPU #0:
> 
> Pierrick, I believe you built the rme test images.  Is there perhaps a newer version of
> the firmware that supports (at least) SCTLR2 and TCR2?
> 

It seems that TF-A has an option 'ENABLE_FEAT_SCTLR2'.
I will try to build with it, and current series, and see how it goes.

> 
> r~



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 4/6] target/arm: Add FEAT_TCR2
  2025-07-13 21:59   ` Richard Henderson
@ 2025-07-14  6:21     ` Pierrick Bouvier
  2025-07-14 12:58       ` Richard Henderson
  0 siblings, 1 reply; 14+ messages in thread
From: Pierrick Bouvier @ 2025-07-14  6:21 UTC (permalink / raw)
  To: Richard Henderson, Gustavo Romero, qemu-arm; +Cc: qemu-devel

On 7/13/25 2:59 PM, Richard Henderson wrote:
> On 7/11/25 08:08, Gustavo Romero wrote:
>> Add FEAT_TCR2, which introduces the TCR2_EL1 and TCR2_EL2 registers.
>> These registers are extensions of the TCR_ELx registers and provide
>> top-level control of the EL10 and EL20 translation regimes.
>>
>> Since the bits in these registers depend on other CPU features, and only
>> FEAT_MEC is supported at the moment, the FEAT_TCR2 only implements the
>> AMEC bits for now.
>>
>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
> This causes a regression in tests/functional/test_aarch64_device_passthrough.py, by
> continually trapping on an access to TCR2_EL1 while the HCRX_EL2 enable bit is not set.
> 
> Unlike the similar SCTRL2 failure, it's not 100% clear to me how the guest and nested
> guest kernels are related.  But it is clear that the outer kernel does not does not
> support TCR2_EL1 (and also doesn't manipulate ID_AA64MMFR3_EL1 to hide FEAT_TCR2), but the
> nested guest kernel does support TCR2_EL1.
> 

The same kernel is used for host and guest.
Maybe it's related to kvm support?

> 
> r~



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 4/6] target/arm: Add FEAT_TCR2
  2025-07-14  6:21     ` Pierrick Bouvier
@ 2025-07-14 12:58       ` Richard Henderson
  2025-07-14 13:36         ` Gustavo Romero
  2025-07-14 15:46         ` Pierrick Bouvier
  0 siblings, 2 replies; 14+ messages in thread
From: Richard Henderson @ 2025-07-14 12:58 UTC (permalink / raw)
  To: Pierrick Bouvier, Gustavo Romero, qemu-arm; +Cc: qemu-devel

On 7/14/25 00:21, Pierrick Bouvier wrote:
> On 7/13/25 2:59 PM, Richard Henderson wrote:
>> On 7/11/25 08:08, Gustavo Romero wrote:
>>> Add FEAT_TCR2, which introduces the TCR2_EL1 and TCR2_EL2 registers.
>>> These registers are extensions of the TCR_ELx registers and provide
>>> top-level control of the EL10 and EL20 translation regimes.
>>>
>>> Since the bits in these registers depend on other CPU features, and only
>>> FEAT_MEC is supported at the moment, the FEAT_TCR2 only implements the
>>> AMEC bits for now.
>>>
>>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
>> This causes a regression in tests/functional/test_aarch64_device_passthrough.py, by
>> continually trapping on an access to TCR2_EL1 while the HCRX_EL2 enable bit is not set.
>>
>> Unlike the similar SCTRL2 failure, it's not 100% clear to me how the guest and nested
>> guest kernels are related.  But it is clear that the outer kernel does not does not
>> support TCR2_EL1 (and also doesn't manipulate ID_AA64MMFR3_EL1 to hide FEAT_TCR2), but the
>> nested guest kernel does support TCR2_EL1.
>>
> 
> The same kernel is used for host and guest.
> Maybe it's related to kvm support?

Oops, no, the patch fails to enable HCRX_TCR2EN in hcrx_write or SCR_TCR2EN in scr_write.
The same is true for the previous patch with HCRX_SCTLR2EN and SCR_SCTLR2EN.


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 4/6] target/arm: Add FEAT_TCR2
  2025-07-14 12:58       ` Richard Henderson
@ 2025-07-14 13:36         ` Gustavo Romero
  2025-07-14 15:46         ` Pierrick Bouvier
  1 sibling, 0 replies; 14+ messages in thread
From: Gustavo Romero @ 2025-07-14 13:36 UTC (permalink / raw)
  To: Richard Henderson, Pierrick Bouvier, qemu-arm; +Cc: qemu-devel

Hi Richard,

On 7/14/25 09:58, Richard Henderson wrote:
> On 7/14/25 00:21, Pierrick Bouvier wrote:
>> On 7/13/25 2:59 PM, Richard Henderson wrote:
>>> On 7/11/25 08:08, Gustavo Romero wrote:
>>>> Add FEAT_TCR2, which introduces the TCR2_EL1 and TCR2_EL2 registers.
>>>> These registers are extensions of the TCR_ELx registers and provide
>>>> top-level control of the EL10 and EL20 translation regimes.
>>>>
>>>> Since the bits in these registers depend on other CPU features, and only
>>>> FEAT_MEC is supported at the moment, the FEAT_TCR2 only implements the
>>>> AMEC bits for now.
>>>>
>>>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
>>> This causes a regression in tests/functional/test_aarch64_device_passthrough.py, by
>>> continually trapping on an access to TCR2_EL1 while the HCRX_EL2 enable bit is not set.
>>>
>>> Unlike the similar SCTRL2 failure, it's not 100% clear to me how the guest and nested
>>> guest kernels are related.  But it is clear that the outer kernel does not does not
>>> support TCR2_EL1 (and also doesn't manipulate ID_AA64MMFR3_EL1 to hide FEAT_TCR2), but the
>>> nested guest kernel does support TCR2_EL1.
>>>
>>
>> The same kernel is used for host and guest.
>> Maybe it's related to kvm support?
> 
> Oops, no, the patch fails to enable HCRX_TCR2EN in hcrx_write or SCR_TCR2EN in scr_write.
> The same is true for the previous patch with HCRX_SCTLR2EN and SCR_SCTLR2EN.

Thanks for the investigation. I'm just taking a look at it right now. I'll send a v8 fixing it.


Cheers,
Gustavo


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 4/6] target/arm: Add FEAT_TCR2
  2025-07-14 12:58       ` Richard Henderson
  2025-07-14 13:36         ` Gustavo Romero
@ 2025-07-14 15:46         ` Pierrick Bouvier
  1 sibling, 0 replies; 14+ messages in thread
From: Pierrick Bouvier @ 2025-07-14 15:46 UTC (permalink / raw)
  To: Richard Henderson, Gustavo Romero, qemu-arm; +Cc: qemu-devel

On 7/14/25 5:58 AM, Richard Henderson wrote:
> On 7/14/25 00:21, Pierrick Bouvier wrote:
>> On 7/13/25 2:59 PM, Richard Henderson wrote:
>>> On 7/11/25 08:08, Gustavo Romero wrote:
>>>> Add FEAT_TCR2, which introduces the TCR2_EL1 and TCR2_EL2 registers.
>>>> These registers are extensions of the TCR_ELx registers and provide
>>>> top-level control of the EL10 and EL20 translation regimes.
>>>>
>>>> Since the bits in these registers depend on other CPU features, and only
>>>> FEAT_MEC is supported at the moment, the FEAT_TCR2 only implements the
>>>> AMEC bits for now.
>>>>
>>>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
>>> This causes a regression in tests/functional/test_aarch64_device_passthrough.py, by
>>> continually trapping on an access to TCR2_EL1 while the HCRX_EL2 enable bit is not set.
>>>
>>> Unlike the similar SCTRL2 failure, it's not 100% clear to me how the guest and nested
>>> guest kernels are related.  But it is clear that the outer kernel does not does not
>>> support TCR2_EL1 (and also doesn't manipulate ID_AA64MMFR3_EL1 to hide FEAT_TCR2), but the
>>> nested guest kernel does support TCR2_EL1.
>>>
>>
>> The same kernel is used for host and guest.
>> Maybe it's related to kvm support?
> 
> Oops, no, the patch fails to enable HCRX_TCR2EN in hcrx_write or SCR_TCR2EN in scr_write.
> The same is true for the previous patch with HCRX_SCTLR2EN and SCR_SCTLR2EN.
> 

Thanks for the investigation. Indeed, building TF-A with 
ENABLE_FEAT_TCR2 and ENABLE_FEAT_SCTRL2 didn't change anything.

It's possible that it's still needed to update test images though, so 
I'll try when Gustavo will post v8.

Thanks,
Pierrick

> 
> r~



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-07-14 16:48 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 14:08 [PATCH-for-10.1 v7 0/6] target/arm: Add FEAT_MEC to max cpu Gustavo Romero
2025-07-11 14:08 ` [PATCH v7 1/6] target/arm: Add the MECEn SCR_EL3 bit Gustavo Romero
2025-07-11 14:08 ` [PATCH v7 2/6] target/arm: Add FEAT_MEC registers Gustavo Romero
2025-07-11 14:08 ` [PATCH v7 3/6] target/arm: Add FEAT_SCTLR2 Gustavo Romero
     [not found]   ` <09497926-db8a-4475-b361-7e8338597326@linaro.org>
2025-07-13 16:27     ` Richard Henderson
2025-07-14  5:43       ` Pierrick Bouvier
2025-07-11 14:08 ` [PATCH v7 4/6] target/arm: Add FEAT_TCR2 Gustavo Romero
2025-07-13 21:59   ` Richard Henderson
2025-07-14  6:21     ` Pierrick Bouvier
2025-07-14 12:58       ` Richard Henderson
2025-07-14 13:36         ` Gustavo Romero
2025-07-14 15:46         ` Pierrick Bouvier
2025-07-11 14:08 ` [PATCH v7 5/6] target/arm: Implement FEAT_MEC cache instructions Gustavo Romero
2025-07-11 14:08 ` [PATCH v7 6/6] target/arm: Advertise FEAT_MEC in cpu max Gustavo Romero

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).