[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 13/24] target/arm: Add ptw_idx to S1Translate
From: |
Richard Henderson |
Subject: |
[PATCH v4 13/24] target/arm: Add ptw_idx to S1Translate |
Date: |
Mon, 10 Oct 2022 20:19:00 -0700 |
Hoist the computation of the mmu_idx for the ptw up to
get_phys_addr_with_struct and get_phys_addr_twostage.
This removes the duplicate check for stage2 disabled
from the middle of the walk, performing it only once.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/ptw.c | 53 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 11 deletions(-)
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 6c5ed56a10..b2bfcfde9a 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -17,6 +17,7 @@
typedef struct S1Translate {
ARMMMUIdx in_mmu_idx;
+ ARMMMUIdx in_ptw_idx;
bool in_secure;
bool in_debug;
bool out_secure;
@@ -233,17 +234,12 @@ static bool S1_ptw_translate(CPUARMState *env,
S1Translate *ptw,
{
bool is_secure = ptw->in_secure;
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
- ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
- bool s2_phys = false;
+ ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
+ bool s2_phys = s2_mmu_idx == ARMMMUIdx_Phys_S ||
+ s2_mmu_idx == ARMMMUIdx_Phys_NS;
uint8_t pte_attrs;
bool pte_secure;
- if (!arm_mmu_idx_is_stage1_of_2(mmu_idx)
- || regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
- s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
- s2_phys = true;
- }
-
if (unlikely(ptw->in_debug)) {
/*
* From gdbstub, do not use softmmu so that we don't modify the
@@ -256,10 +252,12 @@ static bool S1_ptw_translate(CPUARMState *env,
S1Translate *ptw,
} else {
S1Translate s2ptw = {
.in_mmu_idx = s2_mmu_idx,
+ .in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS,
.in_secure = is_secure,
.in_debug = true,
};
GetPhysAddrResult s2 = { };
+
if (!get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
false, &s2, fi)) {
goto fail;
@@ -1283,7 +1281,11 @@ static bool get_phys_addr_lpae(CPUARMState *env,
S1Translate *ptw,
descaddr |= (address >> (stride * (4 - level))) & indexmask;
descaddr &= ~7ULL;
nstable = extract32(tableattrs, 4, 1);
- ptw->in_secure = !nstable;
+ if (!nstable) {
+ /* Stage2_S -> Stage2 or Phys_S -> Phys_NS */
+ ptw->in_ptw_idx &= ~1;
+ ptw->in_secure = false;
+ }
descriptor = arm_ldq_ptw(env, ptw, descaddr, fi);
if (fi->type != ARMFault_None) {
goto do_fault;
@@ -2470,6 +2472,7 @@ static bool get_phys_addr_twostage(CPUARMState *env,
S1Translate *ptw,
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
+ ptw->in_ptw_idx = s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
ptw->in_secure = s2walk_secure;
/*
@@ -2529,10 +2532,32 @@ static bool get_phys_addr_with_struct(CPUARMState *env,
S1Translate *ptw,
ARMMMUFaultInfo *fi)
{
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
- ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
bool is_secure = ptw->in_secure;
+ ARMMMUIdx s1_mmu_idx;
- if (mmu_idx != s1_mmu_idx) {
+ switch (mmu_idx) {
+ case ARMMMUIdx_Phys_S:
+ case ARMMMUIdx_Phys_NS:
+ /* Checking Phys early avoids special casing later vs regime_el. */
+ return get_phys_addr_disabled(env, address, access_type, mmu_idx,
+ is_secure, result, fi);
+
+ case ARMMMUIdx_Stage1_E0:
+ case ARMMMUIdx_Stage1_E1:
+ case ARMMMUIdx_Stage1_E1_PAN:
+ /* First stage lookup uses second stage for ptw. */
+ ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
+ break;
+
+ case ARMMMUIdx_E10_0:
+ s1_mmu_idx = ARMMMUIdx_Stage1_E0;
+ goto do_twostage;
+ case ARMMMUIdx_E10_1:
+ s1_mmu_idx = ARMMMUIdx_Stage1_E1;
+ goto do_twostage;
+ case ARMMMUIdx_E10_1_PAN:
+ s1_mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
+ do_twostage:
/*
* Call ourselves recursively to do the stage 1 and then stage 2
* translations if mmu_idx is a two-stage regime, and EL2 present.
@@ -2543,6 +2568,12 @@ static bool get_phys_addr_with_struct(CPUARMState *env,
S1Translate *ptw,
return get_phys_addr_twostage(env, ptw, address, access_type,
result, fi);
}
+ /* fall through */
+
+ default:
+ /* Single stage and second stage uses physical for ptw. */
+ ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
+ break;
}
/*
--
2.34.1
- [PATCH v4 08/24] target/arm: Plumb debug into S1Translate, (continued)
- [PATCH v4 08/24] target/arm: Plumb debug into S1Translate, Richard Henderson, 2022/10/10
- [PATCH v4 03/24] target/arm: Use probe_access_full for BTI, Richard Henderson, 2022/10/10
- [PATCH v4 05/24] target/arm: Move ARMMMUIdx_Stage2 to a real tlb mmu_idx, Richard Henderson, 2022/10/10
- [PATCH v4 06/24] target/arm: Restrict tlb flush from vttbr_write to vmid change, Richard Henderson, 2022/10/10
- [PATCH v4 04/24] target/arm: Add ARMMMUIdx_Phys_{S,NS}, Richard Henderson, 2022/10/10
- [PATCH v4 07/24] target/arm: Split out S1Translate type, Richard Henderson, 2022/10/10
- [PATCH v4 11/24] target/arm: Split out get_phys_addr_twostage, Richard Henderson, 2022/10/10
- [PATCH v4 13/24] target/arm: Add ptw_idx to S1Translate,
Richard Henderson <=
- [PATCH v4 12/24] target/arm: Use bool consistently for get_phys_addr subroutines, Richard Henderson, 2022/10/10
- [PATCH v4 14/24] target/arm: Add isar predicates for FEAT_HAFDBS, Richard Henderson, 2022/10/10
- [PATCH v4 15/24] target/arm: Extract HA and HD in aa64_va_parameters, Richard Henderson, 2022/10/10
- [PATCH v4 09/24] target/arm: Move be test for regime into S1TranslateResult, Richard Henderson, 2022/10/10
- [PATCH v4 19/24] target/arm: Fix fault reporting in get_phys_addr_lpae, Richard Henderson, 2022/10/10
- [PATCH v4 16/24] target/arm: Move S1_ptw_translate outside arm_ld[lq]_ptw, Richard Henderson, 2022/10/10
- [PATCH v4 17/24] target/arm: Add ARMFault_UnsuppAtomicUpdate, Richard Henderson, 2022/10/10
- [PATCH v4 18/24] target/arm: Remove loop from get_phys_addr_lpae, Richard Henderson, 2022/10/10