diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2025-10-07 08:45:52 -0700 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2025-10-07 08:45:52 -0700 |
| commit | 40e62b903ab847eca9ec1f266d4a60c5a3279344 (patch) | |
| tree | b0e879f8f1e4ff5eecfeb03565a8542fbe43e243 /target/arm/ptw.c | |
| parent | eb7abb4a719f93ddd56571bf91681044b4159399 (diff) | |
| parent | 932cac41ca633f24f192a69770bf91b55c4d27bb (diff) | |
| download | focaccia-qemu-40e62b903ab847eca9ec1f266d4a60c5a3279344.tar.gz focaccia-qemu-40e62b903ab847eca9ec1f266d4a60c5a3279344.zip | |
Merge tag 'pull-target-arm-20251007' of https://gitlab.com/pm215/qemu into staging
target-arm queue: * target/arm: Don't set HCR.RW for AArch32 only CPUs * new board model: amd-versal2-virt * xlnx-zynqmp: model the GIC for the Cortex-R5 RPU cluster * hw/arm: Remove sl_bootparam_write() and 'hw/arm/sharpsl.h' header * Emulate FEAT_RME_GPC2 # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmjlH0AZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3gvaD/92LoDOIPQYCw72nwr/hiC8 # DAJddqKL1VvirtcrTuwytB1+w/tM2FdNx4ADzryHiNEDay2gXl0g4X4Pq6QFwu8B # u2gxQhZZc1XWJgvX06CDJZPIUoazQgri21359c+9mJrI94igq1Gisj+KJ2gaMJ/J # hrtsbovKuuKwMyCwCSK0hqvrUFyechfvJ0MzwVXyHn80lvSeYVbHf8ahdM72Lqdt # PFJuM6hM/bBbclMRrcgRZJ3gi6HGHdKQ+LyYeQkvpHtaO3FWBgyJE7dtzs3mj4c9 # zw7kFJi56/19G6Fx3CESCIjoUQxLPZ1wDljqcQ9+mIwhQ4Dm7cy/D5z018TotIws # mNLpMyEYiyC6dl1TxaJkha9jB6MB+nlglpbOGyRDYD1xwV8o5lidAahKxtmZUrGp # sErUqCL5f+e/inwkFLxKrA2Hk1mjFDzf9/aEF/CyA30JYzRrhCfMoffiqtpPpU5D # +OD1OAnj+W7HSBzO6N2I+4bfsaILw61YvckaBbO9+Br9yx8QseXHwXGh+RgsMhY4 # yJdde//tRusT32SAVoQKCMTJM5Rkrt4wu1D0F4LFL/4rJaqkAhqirNP4v5JEjrlk # UDNa19E1TfmLbCG0TfQBWd3kwLYizqjTO0006jpTMX+KIu5aInEIHzzVrKEKK4t5 # fCw9fUM8T4fSTV71wJ/28Q== # =jFB3 # -----END PGP SIGNATURE----- # gpg: Signature made Tue 07 Oct 2025 07:10:08 AM PDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [unknown] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [unknown] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [unknown] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20251007' of https://gitlab.com/pm215/qemu: (62 commits) target/arm: Enable FEAT_RME_GPC2 for -cpu max with x-rme target/arm: Implement APPSAA target/arm: Fix GPT fault type for address outside PPS target/arm: Implement SPAD, NSPAD, RLPAD target/arm: Implement GPT_NonSecureOnly target/arm: GPT_Secure is reserved without FEAT_SEL2 target/arm: Add cur_space to S1Translate target/arm: Enable FEAT_RME_GPC2 bits in gpccr_write target/arm: Add GPCCR fields from ARM revision L.b target/arm: Add isar feature test for FEAT_RME_GPC2 hw/arm: Remove sl_bootparam_write() and 'hw/arm/sharpsl.h' header hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 hw/arm/xlnx-zynqmp: introduce helper to compute RPU number hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header tests/functional/test_aarch64_xlnx_versal: test the versal2 machine hw/arm/xlnx-versal-virt: add the xlnx-versal2-virt machine docs/system/arm/xlnx-versal-virt: add a note about dumpdtb docs/system/arm/xlnx-versal-virt: update supported devices hw/arm/xlnx-versal-virt: tidy up hw/arm/xlnx-versal-virt: split into base/concrete classes ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/arm/ptw.c')
| -rw-r--r-- | target/arm/ptw.c | 87 |
1 files changed, 60 insertions, 27 deletions
diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 6344971fa6..e03657f309 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -36,8 +36,6 @@ typedef struct S1Translate { /* * in_space: the security space for this walk. This plus * the in_mmu_idx specify the architectural translation regime. - * If a Secure ptw is "downgraded" to NonSecure by an NSTable bit, - * this field is updated accordingly. * * Note that the security space for the in_ptw_idx may be different * from that for the in_mmu_idx. We do not need to explicitly track @@ -53,6 +51,11 @@ typedef struct S1Translate { */ ARMSecuritySpace in_space; /* + * Like in_space, except this may be "downgraded" to NonSecure + * by an NSTable bit. + */ + ARMSecuritySpace cur_space; + /* * in_debug: is this a QEMU debug access (gdbstub, etc)? Debug * accesses will not update the guest page table access flags * and will not change the state of the softmmu TLBs. @@ -315,6 +318,7 @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx, static bool granule_protection_check(CPUARMState *env, uint64_t paddress, ARMSecuritySpace pspace, + ARMSecuritySpace ss, ARMMMUFaultInfo *fi) { MemTxAttrs attrs = { @@ -383,18 +387,37 @@ static bool granule_protection_check(CPUARMState *env, uint64_t paddress, l0gptsz = 30 + FIELD_EX64(gpccr, GPCCR, L0GPTSZ); /* - * GPC Priority 2: Secure, Realm or Root address exceeds PPS. + * GPC Priority 2: Access to Secure, NonSecure or Realm is prevented + * by one of the GPCCR_EL3 address space disable bits (R_TCWMD). + * All of these bits are checked vs aa64_rme_gpc2 in gpccr_write. + */ + { + static const uint8_t disable_masks[4] = { + [ARMSS_Secure] = R_GPCCR_SPAD_MASK, + [ARMSS_NonSecure] = R_GPCCR_NSPAD_MASK, + [ARMSS_Root] = 0, + [ARMSS_Realm] = R_GPCCR_RLPAD_MASK, + }; + + if (gpccr & disable_masks[pspace]) { + goto fault_fail; + } + } + + /* + * GPC Priority 3: Secure, Realm or Root address exceeds PPS. * R_CPDSB: A NonSecure physical address input exceeding PPS * does not experience any fault. + * R_PBPSH: Other address spaces have fault suppressed by APPSAA. */ if (paddress & ~pps_mask) { - if (pspace == ARMSS_NonSecure) { + if (pspace == ARMSS_NonSecure || FIELD_EX64(gpccr, GPCCR, APPSAA)) { return true; } - goto fault_size; + goto fault_fail; } - /* GPC Priority 3: the base address of GPTBR_EL3 exceeds PPS. */ + /* GPC Priority 4: the base address of GPTBR_EL3 exceeds PPS. */ tableaddr = env->cp15.gptbr_el3 << 12; if (tableaddr & ~pps_mask) { goto fault_size; @@ -475,18 +498,30 @@ static bool granule_protection_check(CPUARMState *env, uint64_t paddress, break; case 0b1111: /* all access */ return true; - case 0b1000: - case 0b1001: - case 0b1010: - case 0b1011: + case 0b1000: /* secure */ + if (!cpu_isar_feature(aa64_sel2, cpu)) { + goto fault_walk; + } + /* fall through */ + case 0b1001: /* non-secure */ + case 0b1010: /* root */ + case 0b1011: /* realm */ if (pspace == (gpi & 3)) { return true; } break; + case 0b1101: /* non-secure only */ + /* aa64_rme_gpc2 was checked in gpccr_write */ + if (FIELD_EX64(gpccr, GPCCR, NSO)) { + return (pspace == ARMSS_NonSecure && + (ss == ARMSS_NonSecure || ss == ARMSS_Root)); + } + goto fault_walk; default: goto fault_walk; /* reserved */ } + fault_fail: fi->gpcf = GPCF_Fail; goto fault_common; fault_eabt: @@ -587,7 +622,8 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, * From gdbstub, do not use softmmu so that we don't modify the * state of the cpu at all, including softmmu tlb contents. */ - ARMSecuritySpace s2_space = S2_security_space(ptw->in_space, s2_mmu_idx); + ARMSecuritySpace s2_space + = S2_security_space(ptw->cur_space, s2_mmu_idx); S1Translate s2ptw = { .in_mmu_idx = s2_mmu_idx, .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx), @@ -630,7 +666,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, } if (regime_is_stage2(s2_mmu_idx)) { - uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space); + uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->cur_space); if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) { /* @@ -641,7 +677,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, fi->s2addr = addr; fi->stage2 = true; fi->s1ptw = true; - fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx); + fi->s1ns = fault_s1ns(ptw->cur_space, s2_mmu_idx); return false; } } @@ -657,7 +693,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, fi->s2addr = addr; fi->stage2 = regime_is_stage2(s2_mmu_idx); fi->s1ptw = fi->stage2; - fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx); + fi->s1ns = fault_s1ns(ptw->cur_space, s2_mmu_idx); return false; } @@ -844,7 +880,7 @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val, fi->s2addr = ptw->out_virt; fi->stage2 = true; fi->s1ptw = true; - fi->s1ns = fault_s1ns(ptw->in_space, ptw->in_ptw_idx); + fi->s1ns = fault_s1ns(ptw->cur_space, ptw->in_ptw_idx); return 0; } @@ -1224,7 +1260,7 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, g_assert_not_reached(); } } - out_space = ptw->in_space; + out_space = ptw->cur_space; if (ns) { /* * The NS bit will (as required by the architecture) have no effect if @@ -1254,7 +1290,7 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, } result->f.prot = get_S1prot(env, mmu_idx, false, user_rw, prot_rw, - xn, pxn, result->f.attrs.space, out_space); + xn, pxn, ptw->in_space, out_space); if (ptw->in_prot_check & ~result->f.prot) { /* Access permission fault. */ fi->type = ARMFault_Permission; @@ -1857,7 +1893,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * NonSecure. With RME, the EL3 translation regime does not change * from Root to NonSecure. */ - if (ptw->in_space == ARMSS_Secure + if (ptw->cur_space == ARMSS_Secure && !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1)) { /* @@ -1867,7 +1903,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS); QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2); ptw->in_ptw_idx += 1; - ptw->in_space = ARMSS_NonSecure; + ptw->cur_space = ARMSS_NonSecure; } if (!S1_ptw_translate(env, ptw, descaddr, fi)) { @@ -1991,7 +2027,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, } ap = extract32(attrs, 6, 2); - out_space = ptw->in_space; + out_space = ptw->cur_space; if (regime_is_stage2(mmu_idx)) { /* * R_GYNXY: For stage2 in Realm security state, bit 55 is NS. @@ -2089,12 +2125,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, user_rw = simple_ap_to_rw_prot_is_user(ap, true); prot_rw = simple_ap_to_rw_prot_is_user(ap, false); - /* - * Note that we modified ptw->in_space earlier for NSTable, but - * result->f.attrs retains a copy of the original security space. - */ result->f.prot = get_S1prot(env, mmu_idx, aarch64, user_rw, prot_rw, - xn, pxn, result->f.attrs.space, out_space); + xn, pxn, ptw->in_space, out_space); /* Index into MAIR registers for cache attributes */ attrindx = extract32(attrs, 2, 3); @@ -2192,7 +2224,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, fi->level = level; fi->stage2 = regime_is_stage2(mmu_idx); } - fi->s1ns = fault_s1ns(ptw->in_space, mmu_idx); + fi->s1ns = fault_s1ns(ptw->cur_space, mmu_idx); return true; } @@ -3413,6 +3445,7 @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw, * cannot upgrade a NonSecure translation regime's attributes * to Secure or Realm. */ + ptw->cur_space = ptw->in_space; result->f.attrs.space = ptw->in_space; result->f.attrs.secure = arm_space_is_secure(ptw->in_space); @@ -3548,7 +3581,7 @@ static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw, return true; } if (!granule_protection_check(env, result->f.phys_addr, - result->f.attrs.space, fi)) { + result->f.attrs.space, ptw->in_space, fi)) { fi->type = ARMFault_GPCFOnOutput; return true; } |