qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org, Pierrick Bouvier <pierrick.bouvier@linaro.org>
Subject: [PATCH v4 52/84] target/arm: Implement EXLOCKException for ELR_ELx and SPSR_ELx
Date: Sat, 30 Aug 2025 15:40:56 +1000	[thread overview]
Message-ID: <20250830054128.448363-53-richard.henderson@linaro.org> (raw)
In-Reply-To: <20250830054128.448363-1-richard.henderson@linaro.org>

If PSTATE.EXLOCK is set, and the GCS EXLOCK enable bit is set,
and nested virt is in the appropriate state, then we need to
raise an EXLOCK exception.

Since PSTATE.EXLOCK cannot be set without GCS being present
and enabled, no explicit check for GCS is required.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpregs.h        |  3 ++
 target/arm/cpu.h           |  1 +
 target/arm/helper.c        | 83 +++++++++++++++++++++++++++++++++++---
 target/arm/tcg/op_helper.c |  4 ++
 4 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
index bc6adf5956..15894332b2 100644
--- a/target/arm/cpregs.h
+++ b/target/arm/cpregs.h
@@ -346,6 +346,9 @@ typedef enum CPAccessResult {
      * specified target EL.
      */
     CP_ACCESS_UNDEFINED = (2 << 2),
+
+    /* Access fails with EXLOCK, a GCS exception syndrome. */
+    CP_ACCESS_EXLOCK = (3 << 2),
 } CPAccessResult;
 
 /* Indexes into fgt_read[] */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d5a5152a9c..17902eb40d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1511,6 +1511,7 @@ void pmu_init(ARMCPU *cpu);
 #define PSTATE_C (1U << 29)
 #define PSTATE_Z (1U << 30)
 #define PSTATE_N (1U << 31)
+#define PSTATE_EXLOCK (1ULL << 34)
 #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V)
 #define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F)
 #define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF | PSTATE_BTYPE)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 83a7d6ae36..2f19695d82 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3432,6 +3432,77 @@ static CPAccessResult access_nv1(CPUARMState *env, const ARMCPRegInfo *ri,
     return CP_ACCESS_OK;
 }
 
+static CPAccessResult access_exlock_el1(CPUARMState *env,
+                                        const ARMCPRegInfo *ri, bool isread)
+{
+    int el = arm_current_el(env);
+
+    if (el == 1) {
+        uint64_t hcr = arm_hcr_el2_eff(env);
+
+        /*
+         * EXLOCK check is disabled for NVx in 'x11'.
+         * Since we have to diagnose that, dispatch NV1 trap too.
+         */
+        if ((hcr & HCR_NV) && (hcr & HCR_NV1)) {
+            if (hcr & HCR_NV2) {
+                return CP_ACCESS_OK;
+            }
+            return CP_ACCESS_TRAP_EL2;
+        }
+    }
+
+    if (!isread &&
+        (env->pstate & PSTATE_EXLOCK) &&
+        (el_is_in_host(env, el) ? el == 2 : el == 1) &&
+        (env->cp15.gcscr_el[el] & GCSCR_EXLOCKEN)) {
+        return CP_ACCESS_EXLOCK;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult access_exlock_el2(CPUARMState *env,
+                                        const ARMCPRegInfo *ri, bool isread)
+{
+    int el = arm_current_el(env);
+
+    if (el == 3) {
+        return CP_ACCESS_OK;
+    }
+    if (el == 1) {
+        uint64_t hcr = arm_hcr_el2_eff(env);
+
+        /*
+         * EXLOCK check is disabled for NVx in 'xx1'.
+         * Since we have to diagnose that, dispatch NV1 trap too.
+         */
+        if (hcr & HCR_NV) {
+            if (hcr & HCR_NV2) {
+                return CP_ACCESS_OK;
+            }
+            return CP_ACCESS_TRAP_EL2;
+        }
+    }
+
+    if (!isread &&
+        (env->pstate & PSTATE_EXLOCK) &&
+        (env->cp15.gcscr_el[el] & GCSCR_EXLOCKEN)) {
+        return CP_ACCESS_EXLOCK;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult access_exlock_el3(CPUARMState *env,
+                                        const ARMCPRegInfo *ri, bool isread)
+{
+    if (!isread &&
+        (env->pstate & PSTATE_EXLOCK) &&
+        (env->cp15.gcscr_el[3] & GCSCR_EXLOCKEN)) {
+        return CP_ACCESS_EXLOCK;
+    }
+    return CP_ACCESS_OK;
+}
+
 #ifdef CONFIG_USER_ONLY
 /*
  * `IC IVAU` is handled to improve compatibility with JITs that dual-map their
@@ -3603,13 +3674,13 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
-      .access = PL1_RW, .accessfn = access_nv1,
+      .access = PL1_RW, .accessfn = access_exlock_el1,
       .nv2_redirect_offset = 0x230 | NV2_REDIR_NV1,
       .fieldoffset = offsetof(CPUARMState, elr_el[1]) },
     { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
-      .access = PL1_RW, .accessfn = access_nv1,
+      .access = PL1_RW, .accessfn = access_exlock_el1,
       .nv2_redirect_offset = 0x160 | NV2_REDIR_NV1,
       .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
     /*
@@ -4080,7 +4151,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
     { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
-      .access = PL2_RW,
+      .access = PL2_RW, .accessfn = access_exlock_el2,
       .fieldoffset = offsetof(CPUARMState, elr_el[2]) },
     { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
       .type = ARM_CP_NV2_REDIRECT,
@@ -4098,7 +4169,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
     { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
-      .access = PL2_RW,
+      .access = PL2_RW, .accessfn = access_exlock_el2,
       .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
     { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
@@ -4380,7 +4451,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
-      .access = PL3_RW,
+      .access = PL3_RW, .accessfn = access_exlock_el3,
       .fieldoffset = offsetof(CPUARMState, elr_el[3]) },
     { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
@@ -4391,7 +4462,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
     { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
-      .access = PL3_RW,
+      .access = PL3_RW, .accessfn = access_exlock_el3,
       .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
     { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index 46a3b911ec..56e117c01e 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -887,6 +887,10 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
         }
         syndrome = syn_uncategorized();
         break;
+    case CP_ACCESS_EXLOCK:
+        /* CP_ACCESS_EXLOCK is always directed to the current EL */
+        syndrome = syn_gcs_exlock();
+        break;
     default:
         g_assert_not_reached();
     }
-- 
2.43.0



  parent reply	other threads:[~2025-08-30 16:18 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-30  5:40 [PATCH v4 00/84] target/arm: Implement FEAT_GCS Richard Henderson
2025-08-30  5:40 ` [PATCH v4 01/84] linux-user/aarch64: Split out signal_for_exception Richard Henderson
2025-08-30  5:40 ` [PATCH v4 02/84] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
2025-08-30  5:40 ` [PATCH v4 03/84] linux-user/aarch64: Generate ESR signal records Richard Henderson
2025-08-30  5:40 ` [PATCH v4 04/84] target/arm: Add prot_check parameter to pmsav8_mpu_lookup Richard Henderson
2025-08-30  5:40 ` [PATCH v4 05/84] target/arm: Add in_prot_check to S1Translate Richard Henderson
2025-08-30  5:40 ` [PATCH v4 06/84] target/arm: Skip permission check from arm_cpu_get_phys_page_attrs_debug Richard Henderson
2025-08-30  5:40 ` [PATCH v4 07/84] target/arm: Introduce get_phys_addr_for_at Richard Henderson
2025-08-30  5:40 ` [PATCH v4 08/84] target/arm: Skip AF and DB updates for AccessType_AT Richard Henderson
2025-08-30  5:40 ` [PATCH v4 09/84] target/arm: Add prot_check parameter to do_ats_write Richard Henderson
2025-08-30  5:40 ` [PATCH v4 10/84] target/arm: Fill in HFG[RWI]TR_EL2 bits for Arm v9.5 Richard Henderson
2025-08-30  5:40 ` [PATCH v4 11/84] target/arm: Remove outdated comment for ZCR_EL12 Richard Henderson
2025-08-30  5:40 ` [PATCH v4 12/84] target/arm: Implement FEAT_ATS1A Richard Henderson
2025-08-30  5:40 ` [PATCH v4 13/84] target/arm: Add isar feature test for FEAT_S1PIE, FEAT_S2PIE Richard Henderson
2025-08-30  5:40 ` [PATCH v4 14/84] target/arm: Enable TCR2_ELx.PIE Richard Henderson
2025-08-30  5:40 ` [PATCH v4 15/84] target/arm: Implement PIR_ELx, PIRE0_ELx, S2PIR_EL2 registers Richard Henderson
2025-08-30  5:40 ` [PATCH v4 16/84] target/arm: Force HPD for stage2 translations Richard Henderson
2025-08-30  5:40 ` [PATCH v4 17/84] target/arm: Cache NV1 early in get_phys_addr_lpae Richard Henderson
2025-08-30  5:40 ` [PATCH v4 18/84] target/arm: Populate PIE in aa64_va_parameters Richard Henderson
2025-08-30  5:40 ` [PATCH v4 19/84] target/arm: Implement get_S1prot_indirect Richard Henderson
2025-08-30  5:40 ` [PATCH v4 20/84] target/arm: Implement get_S2prot_indirect Richard Henderson
2025-08-30  5:40 ` [PATCH v4 21/84] target/arm: Do not migrate env->exception Richard Henderson
2025-09-08 14:40   ` Peter Maydell
2025-09-15 17:42     ` Richard Henderson
2025-08-30  5:40 ` [PATCH v4 22/84] target/arm: Expand CPUARMState.exception.syndrome to 64 bits Richard Henderson
2025-08-30  5:40 ` [PATCH v4 23/84] target/arm: Expand syndrome parameter to raise_exception* Richard Henderson
2025-08-30  5:40 ` [PATCH v4 24/84] target/arm: Implement dirtybit check for PIE Richard Henderson
2025-08-30  5:40 ` [PATCH v4 25/84] target/arm: Enable FEAT_S1PIE and FEAT_S2PIE on -cpu max Richard Henderson
2025-08-30  5:40 ` [PATCH v4 26/84] include/hw/core/cpu: Introduce MMUIdxMap Richard Henderson
2025-09-08 14:42   ` Peter Maydell
2025-08-30  5:40 ` [PATCH v4 27/84] include/hw/core/cpu: Introduce cpu_tlb_fast Richard Henderson
2025-08-30  5:40 ` [PATCH v4 28/84] include/hw/core/cpu: Invert the indexing into CPUTLBDescFast Richard Henderson
2025-08-30  5:40 ` [PATCH v4 29/84] target/hppa: Adjust mmu indexes to begin with 0 Richard Henderson
2025-08-30  5:40 ` [PATCH v4 30/84] include/exec/memopidx: Adjust for 32 mmu indexes Richard Henderson
2025-08-30  5:40 ` [PATCH v4 31/84] include/hw/core/cpu: Widen MMUIdxMap Richard Henderson
2025-08-30  5:40 ` [PATCH v4 32/84] target/arm: Split out mmuidx.h from cpu.h Richard Henderson
2025-08-30  5:40 ` [PATCH v4 33/84] target/arm: Convert arm_mmu_idx_to_el from switch to table Richard Henderson
2025-08-30  5:40 ` [PATCH v4 34/84] target/arm: Remove unused env argument from regime_el Richard Henderson
2025-08-30  5:40 ` [PATCH v4 35/84] target/arm: Convert regime_el from switch to table Richard Henderson
2025-08-30  5:40 ` [PATCH v4 36/84] target/arm: Convert regime_has_2_ranges " Richard Henderson
2025-08-30  5:40 ` [PATCH v4 37/84] target/arm: Remove unused env argument from regime_is_pan Richard Henderson
2025-08-30  5:40 ` [PATCH v4 38/84] target/arm: Convert regime_is_pan from switch to table Richard Henderson
2025-08-30  5:40 ` [PATCH v4 39/84] target/arm: Remove unused env argument from regime_is_user Richard Henderson
2025-08-30  5:40 ` [PATCH v4 40/84] target/arm: Convert regime_is_user from switch to table Richard Henderson
2025-08-30  5:40 ` [PATCH v4 41/84] target/arm: Convert arm_mmu_idx_is_stage1_of_2 " Richard Henderson
2025-08-30  5:40 ` [PATCH v4 42/84] target/arm: Convert regime_is_stage2 " Richard Henderson
2025-08-30  5:40 ` [PATCH v4 43/84] target/arm: Introduce mmu indexes for GCS Richard Henderson
2025-08-30  5:40 ` [PATCH v4 44/84] target/arm: Introduce regime_to_gcs Richard Henderson
2025-08-30  5:40 ` [PATCH v4 45/84] target/arm: Support page protections for GCS mmu indexes Richard Henderson
2025-08-30  5:40 ` [PATCH v4 46/84] target/arm: Implement gcs bit for data abort Richard Henderson
2025-08-30  5:40 ` [PATCH v4 47/84] target/arm: Add GCS cpregs Richard Henderson
2025-08-30  5:40 ` [PATCH v4 48/84] target/arm: Add GCS enable and trap levels to DisasContext Richard Henderson
2025-08-30  5:40 ` [PATCH v4 49/84] target/arm: Implement FEAT_CHK Richard Henderson
2025-08-30  5:40 ` [PATCH v4 50/84] target/arm: Expand pstate to 64 bits Richard Henderson
2025-09-08 15:57   ` Peter Maydell
2025-09-15 19:45     ` Richard Henderson
2025-08-30  5:40 ` [PATCH v4 51/84] target/arm: Add syndrome data for EC_GCS Richard Henderson
2025-08-30  5:40 ` Richard Henderson [this message]
2025-09-09 13:14   ` [PATCH v4 52/84] target/arm: Implement EXLOCKException for ELR_ELx and SPSR_ELx Peter Maydell
2025-08-30  5:40 ` [PATCH v4 53/84] target/arm: Split {arm,core}_user_mem_index Richard Henderson
2025-09-09 13:21   ` Peter Maydell
2025-08-30  5:40 ` [PATCH v4 54/84] target/arm: Introduce delay_exception{_el} Richard Henderson
2025-08-30  5:40 ` [PATCH v4 55/84] target/arm: Emit HSTR trap exception out of line Richard Henderson
2025-09-09 13:33   ` Peter Maydell
2025-09-16  1:00     ` Richard Henderson
2025-08-30  5:41 ` [PATCH v4 56/84] target/arm: Emit v7m LTPSIZE " Richard Henderson
2025-08-30  5:41 ` [PATCH v4 57/84] target/arm: Implement GCSSTR, GCSSTTR Richard Henderson
2025-08-30  5:41 ` [PATCH v4 58/84] target/arm: Implement GCSB Richard Henderson
2025-08-30  5:41 ` [PATCH v4 59/84] target/arm: Implement GCSPUSHM Richard Henderson
2025-08-30  5:41 ` [PATCH v4 60/84] target/arm: Implement GCSPOPM Richard Henderson
2025-08-30  5:41 ` [PATCH v4 61/84] target/arm: Implement GCSPUSHX Richard Henderson
2025-08-30  5:41 ` [PATCH v4 62/84] target/arm: Implement GCSPOPX Richard Henderson
2025-08-30  5:41 ` [PATCH v4 63/84] target/arm: Implement GCSPOPCX Richard Henderson
2025-08-30  5:41 ` [PATCH v4 64/84] target/arm: Implement GCSSS1 Richard Henderson
2025-08-30  5:41 ` [PATCH v4 65/84] target/arm: Implement GCSSS2 Richard Henderson
2025-08-30  5:41 ` [PATCH v4 66/84] target/arm: Add gcs record for BL Richard Henderson
2025-08-30  5:41 ` [PATCH v4 67/84] target/arm: Add gcs record for BLR Richard Henderson
2025-08-30  5:41 ` [PATCH v4 68/84] target/arm: Add gcs record for BLR with PAuth Richard Henderson
2025-09-09 17:17   ` Peter Maydell
2025-08-30  5:41 ` [PATCH v4 69/84] target/arm: Load gcs record for RET Richard Henderson
2025-08-30  5:41 ` [PATCH v4 70/84] target/arm: Load gcs record for RET with PAuth Richard Henderson
2025-08-30  5:41 ` [PATCH v4 71/84] target/arm: Copy EXLOCKEn to EXLOCK on exception to the same EL Richard Henderson
2025-08-30  5:41 ` [PATCH v4 72/84] target/arm: Implement EXLOCK check during exception return Richard Henderson
2025-08-30  5:41 ` [PATCH v4 73/84] target/arm: Enable FEAT_GCS with -cpu max Richard Henderson
2025-08-30  5:41 ` [PATCH v4 74/84] linux-user/aarch64: Implement prctls for GCS Richard Henderson
2025-08-30  5:41 ` [PATCH v4 75/84] linux-user/aarch64: Allocate new gcs stack on clone Richard Henderson
2025-08-30  5:41 ` [PATCH v4 76/84] linux-user/aarch64: Release gcs stack on thread exit Richard Henderson
2025-08-30  5:41 ` [PATCH v4 77/84] linux-user/aarch64: Implement map_shadow_stack syscall Richard Henderson
2025-08-30  5:41 ` [PATCH v4 78/84] target/arm: Enable GCSPR_EL0 for read in user-mode Richard Henderson
2025-08-30  5:41 ` [PATCH v4 79/84] linux-user/aarch64: Inject SIGSEGV for GCS faults Richard Henderson
2025-08-30  5:41 ` [PATCH v4 80/84] linux-user/aarch64: Generate GCS signal records Richard Henderson
2025-08-30  5:41 ` [PATCH v4 81/84] linux-user/aarch64: Enable GCS in HWCAP Richard Henderson
2025-08-30  5:41 ` [PATCH v4 82/84] tests/tcg/aarch64: Add gcsstr Richard Henderson
2025-08-30  5:41 ` [PATCH v4 83/84] tests/tcg/aarch64: Add gcspushm Richard Henderson
2025-08-30  5:41 ` [PATCH v4 84/84] tests/tcg/aarch64: Add gcsss Richard Henderson
2025-09-11 12:18 ` [PATCH v4 00/84] target/arm: Implement FEAT_GCS 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=20250830054128.448363-53-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=pierrick.bouvier@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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 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).