[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 70/72] target/ppc: Add a function to check for page protection bit
From: |
Nicholas Piggin |
Subject: |
[PULL 70/72] target/ppc: Add a function to check for page protection bit |
Date: |
Fri, 24 May 2024 09:07:43 +1000 |
From: BALATON Zoltan <balaton@eik.bme.hu>
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.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
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 b1ea301e22..01e358a4a5 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7521,6 +7521,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 4a90dd2584..20fb2ec593 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 */
bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index 3abaf16e78..1e8f1df0f0 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -252,7 +252,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;
}
@@ -403,7 +403,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;
@@ -471,7 +471,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 accbf0b2d8..cbc8efa0c3 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1089,7 +1089,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 c1e4f00335..5a02e4963b 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 78bdbd506c..5414a14aad 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -114,11 +114,6 @@ static int pp_check(int key, int pp, int nx)
return access;
}
-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)
{
@@ -165,13 +160,14 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx,
target_ulong pte0,
/* Keep the matching PTE information */
ctx->raddr = pte1;
ctx->prot = access;
- 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;
}
}
}
@@ -354,12 +350,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;
}
@@ -576,9 +574,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;
}
@@ -636,7 +636,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;
}
@@ -838,7 +838,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.43.0
- [PULL 58/72] target/ppc/mmu_common.c: Remove BookE from direct store handling, (continued)
- [PULL 58/72] target/ppc/mmu_common.c: Remove BookE from direct store handling, Nicholas Piggin, 2024/05/23
- [PULL 64/72] target/ppc/mmu_common.c: Transform ppc_jumbo_xlate() into ppc_6xx_xlate(), Nicholas Piggin, 2024/05/23
- [PULL 60/72] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1, Nicholas Piggin, 2024/05/23
- [PULL 61/72] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2, Nicholas Piggin, 2024/05/23
- [PULL 63/72] target/ppc/mmu_common.c: Split off 40x cases from ppc_jumbo_xlate(), Nicholas Piggin, 2024/05/23
- [PULL 62/72] target/ppc/mmu_common.c: Split off real mode handling from get_physical_address_wtlb(), Nicholas Piggin, 2024/05/23
- [PULL 66/72] target/ppc: Remove id_tlbs flag from CPU env, Nicholas Piggin, 2024/05/23
- [PULL 65/72] target/ppc/mmu_common.c: Move mmu_ctx_t type to mmu_common.c, Nicholas Piggin, 2024/05/23
- [PULL 68/72] target/ppc/mmu-hash32.c: Drop a local variable, Nicholas Piggin, 2024/05/23
- [PULL 67/72] target/ppc: Split off common embedded TLB init, Nicholas Piggin, 2024/05/23
- [PULL 70/72] target/ppc: Add a function to check for page protection bit,
Nicholas Piggin <=
- [PULL 69/72] target/ppc/mmu-radix64.c: Drop a local variable, Nicholas Piggin, 2024/05/23
- [PULL 72/72] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot(), Nicholas Piggin, 2024/05/23
- [PULL 71/72] target/ppc: Move out BookE and related MMU functions from mmu_common.c, Nicholas Piggin, 2024/05/23
- Re: [PULL 00/72] ppc-for-9.1-1 queue, Nicholas Piggin, 2024/05/23
- [PULL 00/72] ppc-for-9.1-1 queue, Nicholas Piggin, 2024/05/23