[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 34/48] target/ppc: Add a function to check for page protection
|
From: |
BALATON Zoltan |
|
Subject: |
[PATCH v6 34/48] target/ppc: Add a function to check for page protection bit |
|
Date: |
Sat, 11 May 2024 03:46:14 +0200 (CEST) |
Checking if a page protection bit is set for a given access type is a
common operation. Add a function to avoid repeating the same check at
multiple places. As this relies on access type and page protection bit
values having certain relation also add an assert to ensure that this
assumption holds.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/cpu_init.c | 5 +++++
target/ppc/internal.h | 23 +++++------------------
target/ppc/mmu-hash32.c | 6 +++---
target/ppc/mmu-hash64.c | 2 +-
target/ppc/mmu-radix64.c | 2 +-
target/ppc/mmu_common.c | 26 +++++++++++++-------------
6 files changed, 28 insertions(+), 36 deletions(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 92c71b2a09..d3b92d9f0e 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7388,6 +7388,11 @@ static void ppc_cpu_class_init(ObjectClass *oc, void
*data)
#ifndef CONFIG_USER_ONLY
cc->sysemu_ops = &ppc_sysemu_ops;
INTERRUPT_STATS_PROVIDER_CLASS(oc)->get_statistics = ppc_get_irq_stats;
+
+ /* check_prot_access_type relies on MMU access and PAGE bits relations */
+ qemu_build_assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 &&
+ MMU_INST_FETCH == 2 && PAGE_READ == 1 &&
+ PAGE_WRITE == 2 && PAGE_EXEC == 4);
#endif
cc->gdb_num_core_regs = 71;
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 46176c4711..9cdb797dc0 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -234,27 +234,14 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
const gchar *ppc_gdb_arch_name(CPUState *cs);
-/**
- * prot_for_access_type:
- * @access_type: Access type
- *
- * Return the protection bit required for the given access type.
- */
-static inline int prot_for_access_type(MMUAccessType access_type)
+#ifndef CONFIG_USER_ONLY
+
+/* Check if permission bit required for the access_type is set in prot */
+static inline int check_prot_access_type(int prot, MMUAccessType access_type)
{
- switch (access_type) {
- case MMU_INST_FETCH:
- return PAGE_EXEC;
- case MMU_DATA_LOAD:
- return PAGE_READ;
- case MMU_DATA_STORE:
- return PAGE_WRITE;
- }
- g_assert_not_reached();
+ return prot & (1 << access_type);
}
-#ifndef CONFIG_USER_ONLY
-
/* PowerPC MMU emulation */
static inline int ppc_hash32_pp_prot(int key, int pp, int nx)
{
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index bf5ce129d2..d5f2057eb1 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -207,7 +207,7 @@ static bool ppc_hash32_direct_store(PowerPCCPU *cpu,
target_ulong sr,
}
*prot = key ? PAGE_READ | PAGE_WRITE : PAGE_READ;
- if (*prot & prot_for_access_type(access_type)) {
+ if (check_prot_access_type(*prot, access_type)) {
*raddr = eaddr;
return true;
}
@@ -358,7 +358,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
if (env->nb_BATs != 0) {
raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx);
if (raddr != -1) {
- if (prot_for_access_type(access_type) & ~*protp) {
+ if (!check_prot_access_type(*protp, access_type)) {
if (guest_visible) {
if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
@@ -426,7 +426,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
prot = ppc_hash32_pte_prot(mmu_idx, sr, pte);
- if (prot_for_access_type(access_type) & ~prot) {
+ if (!check_prot_access_type(prot, access_type)) {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
if (guest_visible) {
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 0966422a55..d9626f6aab 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1097,7 +1097,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
amr_prot = ppc_hash64_amr_prot(cpu, pte);
prot = exec_prot & pp_prot & amr_prot;
- need_prot = prot_for_access_type(access_type);
+ need_prot = check_prot_access_type(PAGE_RWX, access_type);
if (need_prot & ~prot) {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 395ce3b782..2c5ade5cea 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -209,7 +209,7 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu,
MMUAccessType access_type,
}
/* Check if requested access type is allowed */
- if (prot_for_access_type(access_type) & ~*prot) {
+ if (!check_prot_access_type(*prot, access_type)) {
/* Page Protected for that Access */
*fault_cause |= access_type == MMU_INST_FETCH ? SRR1_NOEXEC_GUARD :
DSISR_PROTFAULT;
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index b14421b8c0..ca914fefea 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -76,11 +76,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
/*****************************************************************************/
/* PowerPC MMU emulation */
-static int check_prot(int prot, MMUAccessType access_type)
-{
- return prot & prot_for_access_type(access_type) ? 0 : -2;
-}
-
int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
int way, int is_code)
{
@@ -125,13 +120,14 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx,
target_ulong pte0,
/* Keep the matching PTE information */
ctx->raddr = pte1;
ctx->prot = ppc_hash32_pp_prot(ctx->key, pp, ctx->nx);
- ret = check_prot(ctx->prot, access_type);
- if (ret == 0) {
+ if (check_prot_access_type(ctx->prot, access_type)) {
/* Access granted */
qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
+ ret = 0;
} else {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
+ ret = -2;
}
}
}
@@ -299,12 +295,14 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t
*ctx,
(virtual & 0x0001F000);
/* Compute access rights */
ctx->prot = prot;
- ret = check_prot(ctx->prot, access_type);
- if (ret == 0) {
+ if (check_prot_access_type(ctx->prot, access_type)) {
qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r "
HWADDR_FMT_plx
" prot=%c%c\n", i, ctx->raddr,
ctx->prot & PAGE_READ ? 'R' : '-',
ctx->prot & PAGE_WRITE ? 'W' : '-');
+ ret = 0;
+ } else {
+ ret = -2;
}
break;
}
@@ -521,9 +519,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env,
hwaddr *raddr,
check_perms:
/* Check from TLB entry */
*prot = tlb->prot;
- ret = check_prot(*prot, access_type);
- if (ret == -2) {
+ if (check_prot_access_type(*prot, access_type)) {
+ ret = 0;
+ } else {
env->spr[SPR_40x_ESR] = 0;
+ ret = -2;
}
break;
}
@@ -581,7 +581,7 @@ static int mmubooke_check_tlb(CPUPPCState *env,
ppcemb_tlb_t *tlb,
} else {
*prot = (tlb->prot >> 4) & 0xF;
}
- if (*prot & prot_for_access_type(access_type)) {
+ if (check_prot_access_type(*prot, access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
return 0;
}
@@ -783,7 +783,7 @@ found_tlb:
*prot |= PAGE_EXEC;
}
}
- if (*prot & prot_for_access_type(access_type)) {
+ if (check_prot_access_type(*prot, access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
return 0;
}
--
2.30.9
- [PATCH v6 16/48] target/ppc/mmu_common.c: Replace hard coded constants in ppc_jumbo_xlate(), (continued)
- [PATCH v6 16/48] target/ppc/mmu_common.c: Replace hard coded constants in ppc_jumbo_xlate(), BALATON Zoltan, 2024/05/10
- [PATCH v6 07/48] target/ppc/mmu_common.c: Introduce mmu6xx_get_physical_address(), BALATON Zoltan, 2024/05/10
- [PATCH v6 26/48] target/ppc/mmu_common.c: Split off 40x cases from ppc_jumbo_xlate(), BALATON Zoltan, 2024/05/10
- [PATCH v6 17/48] target/ppc/mmu_common.c: Don't use mmu_ctx_t for mmu40x_get_physical_address(), BALATON Zoltan, 2024/05/10
- [PATCH v6 09/48] target/ppc/mmu_common.c: Move some debug logging, BALATON Zoltan, 2024/05/10
- [PATCH v6 08/48] target/ppc/mmu_common.c: Move else branch to avoid large if block, BALATON Zoltan, 2024/05/10
- [PATCH v6 30/48] target/ppc: Remove id_tlbs flag from CPU env, BALATON Zoltan, 2024/05/10
- [PATCH v6 43/48] target/ppc/mmu_common.c: Remove unused field from mmu_ctx_t, BALATON Zoltan, 2024/05/10
- [PATCH v6 41/48] target/ppc/mmu_common.c: Return directly in ppc6xx_tlb_pte_check(), BALATON Zoltan, 2024/05/10
- [PATCH v6 24/48] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2, BALATON Zoltan, 2024/05/10
- [PATCH v6 34/48] target/ppc: Add a function to check for page protection bit,
BALATON Zoltan <=
- [PATCH v6 25/48] target/ppc/mmu_common.c: Split off real mode handling from get_physical_address_wtlb(), BALATON Zoltan, 2024/05/10
- [PATCH v6 36/48] target/ppc/mmu_common.c: Remove local name for a constant, BALATON Zoltan, 2024/05/10
- [PATCH v6 42/48] target/ppc/mmu_common.c: Simplify ppc6xx_tlb_pte_check(), BALATON Zoltan, 2024/05/10
- [PATCH v6 33/48] target/ppc/mmu-radix64.c: Drop a local variable, BALATON Zoltan, 2024/05/10
- [PATCH v6 31/48] target/ppc: Split off common embedded TLB init, BALATON Zoltan, 2024/05/10
- [PATCH v6 28/48] target/ppc/mmu_common.c: Move mmu_ctx_t type to mmu_common.c, BALATON Zoltan, 2024/05/10
- [PATCH v6 23/48] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1, BALATON Zoltan, 2024/05/10
- [PATCH v6 19/48] target/ppc/mmu_common.c: Don't use mmu_ctx_t in mmubooke206_get_physical_address(), BALATON Zoltan, 2024/05/10
- [PATCH v6 20/48] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot(), BALATON Zoltan, 2024/05/10
- [PATCH v6 47/48] target/ppc/mmu_common.c: Remove single use local variable, BALATON Zoltan, 2024/05/10