[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 80/89] target/riscv: Reorg access check in get_physical_address
|
From: |
Alistair Francis |
|
Subject: |
[PULL 80/89] target/riscv: Reorg access check in get_physical_address |
|
Date: |
Fri, 5 May 2023 11:02:32 +1000 |
From: Richard Henderson <richard.henderson@linaro.org>
We were effectively computing the protection bits twice,
once while performing access checks and once while returning
the valid bits to the caller. Reorg so we do this once.
Move the computation of mxr close to its single use.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-25-richard.henderson@linaro.org>
Message-Id: <20230412114333.118895-25-richard.henderson@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_helper.c | 69 ++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 33 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c7c384bae3..7849e18554 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -747,7 +747,7 @@ static int get_physical_address_pmp(CPURISCVState *env, int
*prot,
* @is_debug: Is this access from a debugger or the monitor?
*/
static int get_physical_address(CPURISCVState *env, hwaddr *physical,
- int *prot, vaddr addr,
+ int *ret_prot, vaddr addr,
target_ulong *fault_pte_addr,
int access_type, int mmu_idx,
bool first_stage, bool two_stage,
@@ -779,20 +779,14 @@ static int get_physical_address(CPURISCVState *env,
hwaddr *physical,
if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
*physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ *ret_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
}
- *prot = 0;
+ *ret_prot = 0;
hwaddr base;
- int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
-
- if (first_stage == true) {
- mxr = get_field(env->mstatus, MSTATUS_MXR);
- } else {
- mxr = get_field(env->vsstatus, MSTATUS_MXR);
- }
+ int levels, ptidxbits, ptesize, vm, sum, widened;
if (first_stage == true) {
if (use_background) {
@@ -835,7 +829,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr
*physical,
levels = 5; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_MBARE:
*physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ *ret_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
default:
g_assert_not_reached();
@@ -970,6 +964,27 @@ restart:
return TRANSLATE_FAIL;
}
+ int prot = 0;
+ if (pte & PTE_R) {
+ prot |= PAGE_READ;
+ }
+ if (pte & PTE_W) {
+ prot |= PAGE_WRITE;
+ }
+ if (pte & PTE_X) {
+ bool mxr;
+
+ if (first_stage == true) {
+ mxr = get_field(env->mstatus, MSTATUS_MXR);
+ } else {
+ mxr = get_field(env->vsstatus, MSTATUS_MXR);
+ }
+ if (mxr) {
+ prot |= PAGE_READ;
+ }
+ prot |= PAGE_EXEC;
+ }
+
if ((pte & PTE_U) &&
((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
/*
@@ -982,17 +997,9 @@ restart:
/* Supervisor PTE flags when not S mode */
return TRANSLATE_FAIL;
}
- if (access_type == MMU_DATA_LOAD &&
- !((pte & PTE_R) || ((pte & PTE_X) && mxr))) {
- /* Read access check failed */
- return TRANSLATE_FAIL;
- }
- if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
- /* Write access check failed */
- return TRANSLATE_FAIL;
- }
- if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
- /* Fetch access check failed */
+
+ if (!((prot >> access_type) & 1)) {
+ /* Access check failed */
return TRANSLATE_FAIL;
}
@@ -1057,20 +1064,16 @@ restart:
(vpn & (((target_ulong)1 << ptshift) - 1))
) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK);
- /* set permissions on the TLB entry */
- if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) {
- *prot |= PAGE_READ;
- }
- if (pte & PTE_X) {
- *prot |= PAGE_EXEC;
- }
/*
- * Add write permission on stores or if the page is already dirty,
- * so that we TLB miss on later writes to update the dirty bit.
+ * Remove write permission unless this is a store, or the page is
+ * already dirty, so that we TLB miss on later writes to update
+ * the dirty bit.
*/
- if ((pte & PTE_W) && (access_type == MMU_DATA_STORE || (pte & PTE_D))) {
- *prot |= PAGE_WRITE;
+ if (access_type != MMU_DATA_STORE && !(pte & PTE_D)) {
+ prot &= ~PAGE_WRITE;
}
+ *ret_prot = prot;
+
return TRANSLATE_SUCCESS;
}
--
2.40.0
- [PULL 71/89] target/riscv: Move hstatus.spvp check to check_access_hlsv, (continued)
- [PULL 71/89] target/riscv: Move hstatus.spvp check to check_access_hlsv, Alistair Francis, 2023/05/04
- [PULL 72/89] target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index, Alistair Francis, 2023/05/04
- [PULL 74/89] target/riscv: Hoist second stage mode change to callers, Alistair Francis, 2023/05/04
- [PULL 73/89] target/riscv: Check SUM in the correct register, Alistair Francis, 2023/05/04
- [PULL 75/89] target/riscv: Hoist pbmte and hade out of the level loop, Alistair Francis, 2023/05/04
- [PULL 77/89] target/riscv: Suppress pte update with is_debug, Alistair Francis, 2023/05/04
- [PULL 76/89] target/riscv: Move leaf pte processing out of level loop, Alistair Francis, 2023/05/04
- [PULL 78/89] target/riscv: Don't modify SUM with is_debug, Alistair Francis, 2023/05/04
- [PULL 81/89] target/riscv: Reorg sum check in get_physical_address, Alistair Francis, 2023/05/04
- [PULL 79/89] target/riscv: Merge checks for reserved pte flags, Alistair Francis, 2023/05/04
- [PULL 80/89] target/riscv: Reorg access check in get_physical_address,
Alistair Francis <=
- [PULL 83/89] target/riscv: add CPU QOM header, Alistair Francis, 2023/05/04
- [PULL 86/89] target/riscv: Restore the predicate() NULL check behavior, Alistair Francis, 2023/05/04
- [PULL 84/89] target/riscv: add query-cpy-definitions support, Alistair Francis, 2023/05/04
- [PULL 85/89] target/riscv: add TYPE_RISCV_DYNAMIC_CPU, Alistair Francis, 2023/05/04
- [PULL 87/89] target/riscv: Fix Guest Physical Address Translation, Alistair Francis, 2023/05/04
- [PULL 89/89] target/riscv: add Ventana's Veyron V1 CPU, Alistair Francis, 2023/05/04
- [PULL 82/89] hw/intc/riscv_aplic: Zero init APLIC internal state, Alistair Francis, 2023/05/04
- [PULL 88/89] riscv: Make sure an exception is raised if a pte is malformed, Alistair Francis, 2023/05/04