[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 26/48] mmu-hash*: Separate PTEG searching from permiss
From: |
David Gibson |
Subject: |
[Qemu-ppc] [PATCH 26/48] mmu-hash*: Separate PTEG searching from permissions checking |
Date: |
Tue, 12 Mar 2013 21:31:28 +1100 |
find_pte{32,64{() do several things. First they search through a PTEG
ooking for a PTE matching our virtual address. Then they do permissions
checking and other processing on that PTE.
This patch separates the search by VA out from the rest. The search is
combined with the pte{32,64}_match() functions into new
ppc_has{32,64}_pteg_search() functions.
Signed-off-by: David Gibson <address@hidden>
---
target-ppc/mmu-hash32.c | 69 ++++++++++++++++++++++++-----------------------
target-ppc/mmu-hash32.h | 4 +++
target-ppc/mmu-hash64.c | 67 ++++++++++++++++++++++-----------------------
target-ppc/mmu-hash64.h | 4 +++
4 files changed, 77 insertions(+), 67 deletions(-)
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 3be1002..7c13a49 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -297,14 +297,6 @@ static int ppc_hash32_direct_store(CPUPPCState *env,
target_ulong sr,
}
}
-static bool pte32_match(target_ulong pte0, target_ulong pte1,
- bool secondary, target_ulong ptem)
-{
- return (pte0 & HPTE32_V_VALID)
- && (secondary == !!(pte0 & HPTE32_V_SECONDARY))
- && HPTE32_V_COMPARE(pte0, ptem);
-}
-
static int pte_check_hash32(struct mmu_ctx_hash32 *ctx, target_ulong pte0,
target_ulong pte1, int rwx)
{
@@ -328,8 +320,8 @@ static int pte_check_hash32(struct mmu_ctx_hash32 *ctx,
target_ulong pte0,
return ret;
}
-static int ppc_hash32_pte_update_flags(struct mmu_ctx_hash32 *ctx,
target_ulong *pte1p,
- int ret, int rwx)
+static int ppc_hash32_pte_update_flags(struct mmu_ctx_hash32 *ctx,
+ uint32_t *pte1p, int ret, int rwx)
{
int store = 0;
@@ -358,40 +350,49 @@ hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash)
return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
}
-/* PTE table lookup */
+static hwaddr ppc_hash32_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+ bool secondary, target_ulong ptem,
+ ppc_hash_pte32_t *pte)
+{
+ hwaddr pte_offset = pteg_off;
+ target_ulong pte0, pte1;
+ int i;
+
+ for (i = 0; i < HPTES_PER_GROUP; i++) {
+ pte0 = ppc_hash32_load_hpte0(env, pte_offset);
+ pte1 = ppc_hash32_load_hpte1(env, pte_offset);
+
+ if ((pte0 & HPTE32_V_VALID)
+ && (secondary == !!(pte0 & HPTE32_V_SECONDARY))
+ && HPTE32_V_COMPARE(pte0, ptem)) {
+ pte->pte0 = pte0;
+ pte->pte1 = pte1;
+ return pte_offset;
+ }
+
+ pte_offset += HASH_PTE_SIZE_32;
+ }
+
+ return -1;
+}
+
static int find_pte32(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
target_ulong eaddr, int h, int rwx, int target_page_bits)
{
- hwaddr pteg_off;
- target_ulong pte0, pte1;
- int i, good = -1;
+ hwaddr pteg_off, pte_offset;
+ ppc_hash_pte32_t pte;
int ret;
ret = -1; /* No entry found */
pteg_off = get_pteg_offset32(env, ctx->hash[h]);
- for (i = 0; i < HPTES_PER_GROUP; i++) {
- pte0 = ppc_hash32_load_hpte0(env, pteg_off + i*HASH_PTE_SIZE_32);
- pte1 = ppc_hash32_load_hpte1(env, pteg_off + i*HASH_PTE_SIZE_32);
-
- LOG_MMU("Load pte from %08" HWADDR_PRIx " => " TARGET_FMT_lx " "
- TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
- pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
- (int)((pte0 >> 6) & 1), ctx->ptem);
-
- if (pte32_match(pte0, pte1, h, ctx->ptem)) {
- good = i;
- break;
- }
- }
- if (good != -1) {
- ret = pte_check_hash32(ctx, pte0, pte1, rwx);
+ pte_offset = ppc_hash32_pteg_search(env, pteg_off, h, ctx->ptem, &pte);
+ if (pte_offset != -1) {
+ ret = pte_check_hash32(ctx, pte.pte0, pte.pte1, rwx);
LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n",
ctx->raddr, ctx->prot, ret);
/* Update page flags */
- pte1 = ctx->raddr;
- if (ppc_hash32_pte_update_flags(ctx, &pte1, ret, rwx) == 1) {
- ppc_hash32_store_hpte1(env, pteg_off + good * HASH_PTE_SIZE_32,
- pte1);
+ if (ppc_hash32_pte_update_flags(ctx, &pte.pte1, ret, rwx) == 1) {
+ ppc_hash32_store_hpte1(env, pte_offset, pte.pte1);
}
}
diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h
index 2344184..f990edc 100644
--- a/target-ppc/mmu-hash32.h
+++ b/target-ppc/mmu-hash32.h
@@ -97,6 +97,10 @@ static inline void ppc_hash32_store_hpte1(CPUPPCState *env,
stl_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_32/2, pte1);
}
+typedef struct {
+ uint32_t pte0, pte1;
+} ppc_hash_pte32_t;
+
#endif /* CONFIG_USER_ONLY */
#endif /* __MMU_HASH32_H__ */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 8664116..66b2d24 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -299,14 +299,6 @@ static int ppc_hash64_check_prot(int prot, int rwx)
return ret;
}
-static bool pte64_match(target_ulong pte0, target_ulong pte1,
- bool secondary, target_ulong ptem)
-{
- return (pte0 & HPTE64_V_VALID)
- && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
- && HPTE64_V_COMPARE(pte0, ptem);
-}
-
static int pte64_check(struct mmu_ctx_hash64 *ctx, target_ulong pte0,
target_ulong pte1, int rwx)
{
@@ -334,8 +326,7 @@ static int pte64_check(struct mmu_ctx_hash64 *ctx,
target_ulong pte0,
}
static int ppc_hash64_pte_update_flags(struct mmu_ctx_hash64 *ctx,
- target_ulong *pte1p,
- int ret, int rw)
+ uint64_t *pte1p, int ret, int rw)
{
int store = 0;
@@ -359,39 +350,49 @@ static int ppc_hash64_pte_update_flags(struct
mmu_ctx_hash64 *ctx,
return store;
}
-/* PTE table lookup */
+static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+ bool secondary, target_ulong ptem,
+ ppc_hash_pte64_t *pte)
+{
+ hwaddr pte_offset = pteg_off;
+ target_ulong pte0, pte1;
+ int i;
+
+ for (i = 0; i < HPTES_PER_GROUP; i++) {
+ pte0 = ppc_hash64_load_hpte0(env, pte_offset);
+ pte1 = ppc_hash64_load_hpte1(env, pte_offset);
+
+ if ((pte0 & HPTE64_V_VALID)
+ && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
+ && HPTE64_V_COMPARE(pte0, ptem)) {
+ pte->pte0 = pte0;
+ pte->pte1 = pte1;
+ return pte_offset;
+ }
+
+ pte_offset += HASH_PTE_SIZE_64;
+ }
+
+ return -1;
+}
+
static int find_pte64(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
target_ulong eaddr, int h, int rwx, int target_page_bits)
{
- hwaddr pteg_off;
- target_ulong pte0, pte1;
- int i, good = -1;
+ hwaddr pteg_off, pte_offset;
+ ppc_hash_pte64_t pte;
int ret;
ret = -1; /* No entry found */
pteg_off = (ctx->hash[h] * HASH_PTEG_SIZE_64) & env->htab_mask;
- for (i = 0; i < HPTES_PER_GROUP; i++) {
- pte0 = ppc_hash64_load_hpte0(env, pteg_off + i*HASH_PTE_SIZE_64);
- pte1 = ppc_hash64_load_hpte1(env, pteg_off + i*HASH_PTE_SIZE_64);
-
- LOG_MMU("Load pte from %016" HWADDR_PRIx " => " TARGET_FMT_lx " "
- TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
- pteg_off + (i * 16), pte0, pte1, !!(pte0 & HPTE64_V_VALID),
- h, !!(pte0 & HPTE64_V_SECONDARY), ctx->ptem);
-
- if (pte64_match(pte0, pte1, h, ctx->ptem)) {
- good = i;
- break;
- }
- }
- if (good != -1) {
- ret = pte64_check(ctx, pte0, pte1, rwx);
+ pte_offset = ppc_hash64_pteg_search(env, pteg_off, h, ctx->ptem, &pte);
+ if (pte_offset != -1) {
+ ret = pte64_check(ctx, pte.pte0, pte.pte1, rwx);
LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n",
ctx->raddr, ctx->prot, ret);
/* Update page flags */
- pte1 = ctx->raddr;
- if (ppc_hash64_pte_update_flags(ctx, &pte1, ret, rwx) == 1) {
- ppc_hash64_store_hpte1(env, pteg_off + good * HASH_PTE_SIZE_64,
pte1);
+ if (ppc_hash64_pte_update_flags(ctx, &pte.pte1, ret, rwx) == 1) {
+ ppc_hash64_store_hpte1(env, pte_offset, pte.pte1);
}
}
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index a9c73d4..1ce6e5b 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -113,6 +113,10 @@ static inline void ppc_hash64_store_hpte1(CPUPPCState *env,
}
}
+typedef struct {
+ uint64_t pte0, pte1;
+} ppc_hash_pte64_t;
+
#endif /* CONFIG_USER_ONLY */
#endif /* !defined (__MMU_HASH64_H__) */
--
1.7.10.4
- [Qemu-ppc] [PATCH 43/48] mmu-hash*: Don't use full ppc_hash{32, 64}_translate() path for get_phys_page_debug(), (continued)
- [Qemu-ppc] [PATCH 43/48] mmu-hash*: Don't use full ppc_hash{32, 64}_translate() path for get_phys_page_debug(), David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 27/48] mmu-hash*: Make find_pte{32, 64} do more of the job of finding ptes, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 10/48] target-ppc: Disentangle hash mmu paths for cpu_ppc_handle_mmu_fault, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 12/48] target-ppc: Disentangle hash mmu helper functions, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 31/48] mmu-hash32: Remove odd pointer usage from BAT code, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 21/48] mmu-hash*: Combine ppc_hash{32, 64}_get_physical_address and get_segment{32, 64}(), David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 13/48] target-ppc: Don't share get_pteg_offset() between 32 and 64-bit, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 06/48] target-ppc: Disentangle find_pte(), David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 45/48] mmu-hash64: Implement Virtual Page Class Key Protection, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 09/48] target-ppc: Disentangle get_physical_address() paths, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 26/48] mmu-hash*: Separate PTEG searching from permissions checking,
David Gibson <=
- [Qemu-ppc] [PATCH 41/48] mmu-hash*: Clean up real address calculation, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 04/48] target-ppc: Move SLB handling into a mmu-hash64.c, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 36/48] mmu-hash*: Don't update PTE flags when permission is denied, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 47/48] target-ppc: Move ppc tlb_fill implementation into mmu_helper.c, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 44/48] mmu-hash*: Merge translate and fault handling functions, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 48/48] target-ppc: Use QOM method dispatch for MMU fault handling, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 15/48] target-ppc: mmu_ctx_t should not be a global type, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 17/48] mmu-hash*: Add hash pte load/store helpers, David Gibson, 2013/03/12
- [Qemu-ppc] [PATCH 03/48] target-ppc: Remove address check for logging, David Gibson, 2013/03/12