[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 41/45] mmu-hash*: Clean up real address calculation
From: |
David Gibson |
Subject: |
[Qemu-devel] [PATCH 41/45] mmu-hash*: Clean up real address calculation |
Date: |
Wed, 6 Mar 2013 14:44:29 +1100 |
More recent 64-bit hash MMUs support multiple page sizes, and PTEs for
large pages only include the offset of the whole large page. But the qemu
tlb only handles pages of the base size (4k) so we need to break up the
large pages into 4k pieces for the qemu tlb. To do that we have a somewhat
awkward piece of code that adds the folds address bits 4k and the page size
from the virtual address into the real address from the pte.
This patch simplifies this redefining the raddr output of
ppc_hash64_translate() to be the full real address of the faulting address,
rather than just the (4k) page offset. Computing that turns out to be
simpler, and is fine for the caller, since it already masks with
TARGET_PAGE_MASK before inserting into the qemu tlb.
The multiple page size complication doesn't exist for 32-bit hash mmus, but
we make an analogous cleanup there for consistency.
Signed-off-by: David Gibson <address@hidden>
---
target-ppc/mmu-hash32.c | 14 ++++++++++++--
target-ppc/mmu-hash64.c | 26 +++++++++++++++-----------
2 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 314b7d1..e5ee29b 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -343,6 +343,15 @@ static hwaddr ppc_hash32_htab_lookup(CPUPPCState *env,
return pte_offset;
}
+static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
+ target_ulong eaddr)
+{
+ hwaddr rpn = pte.pte1;
+ hwaddr mask = ~TARGET_PAGE_MASK;
+
+ return (rpn & ~mask) | (eaddr & mask);
+}
+
static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
target_ulong eaddr, int rwx)
{
@@ -421,8 +430,9 @@ static int ppc_hash32_translate(CPUPPCState *env, struct
mmu_ctx_hash32 *ctx,
ppc_hash32_store_hpte1(env, pte_offset, new_pte1);
}
- /* Keep the matching PTE informations */
- ctx->raddr = pte.pte1;
+ /* 9. Determine the real address from the PTE */
+
+ ctx->raddr = ppc_hash32_pte_raddr(sr, pte, eaddr);
return 0;
}
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index c76abb7..5e168d5 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -362,6 +362,18 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
return pte_offset;
}
+static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
+ target_ulong eaddr)
+{
+ hwaddr rpn = pte.pte1;
+ /* FIXME: Add support for SLLP extended page sizes */
+ int target_page_bits = (slb->vsid & SLB_VSID_L)
+ ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
+ hwaddr mask = (1ULL << target_page_bits) - 1;
+
+ return (rpn & ~mask) | (eaddr & mask);
+}
+
static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
target_ulong eaddr, int rwx)
{
@@ -369,7 +381,6 @@ static int ppc_hash64_translate(CPUPPCState *env, struct
mmu_ctx_hash64 *ctx,
hwaddr pte_offset;
ppc_hash_pte64_t pte;
uint64_t new_pte1;
- int target_page_bits;
const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
assert((rwx == 0) || (rwx == 1) || (rwx == 2));
@@ -429,17 +440,10 @@ static int ppc_hash64_translate(CPUPPCState *env, struct
mmu_ctx_hash64 *ctx,
ppc_hash64_store_hpte1(env, pte_offset, new_pte1);
}
- /* Keep the matching PTE informations */
- ctx->raddr = pte.pte1;
+ /* 7. Determine the real address from the PTE */
+
+ ctx->raddr = ppc_hash64_pte_raddr(slb, pte, eaddr);
- /* We have a TLB that saves 4K pages, so let's
- * split a huge page to 4k chunks */
- target_page_bits = (slb->vsid & SLB_VSID_L)
- ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
- if (target_page_bits != TARGET_PAGE_BITS) {
- ctx->raddr |= (eaddr & ((1 << target_page_bits) - 1))
- & TARGET_PAGE_MASK;
- }
return 0;
}
--
1.7.10.4
- [Qemu-devel] [PATCH 26/45] mmu-hash*: Separate PTEG searching from permissions checking, (continued)
- [Qemu-devel] [PATCH 26/45] mmu-hash*: Separate PTEG searching from permissions checking, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 30/45] mmu-hash*: Fold pte_check*() logic into caller, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 35/45] mmu-hash32: Don't look up page tables on BAT permission error, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 31/45] mmu-hash32: Remove odd pointer usage from BAT code, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 37/45] mmu-hash32: Remove nx from context structure, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 33/45] mmu-hash32: Clean up BAT matching logic, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 36/45] mmu-hash*: Don't update PTE flags when permission is denied, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 34/45] mmu-hash32: Cleanup BAT lookup, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 39/45] mmu-hash64: Factor SLB N bit into permissions bits, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 42/45] mmu-hash*: Correctly mask RPN from hash PTE, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 41/45] mmu-hash*: Clean up real address calculation,
David Gibson <=
- [Qemu-devel] [PATCH 40/45] mmu-hash*: Clean up PTE flags update, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 38/45] mmu-hash*: Clean up permission checking, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 43/45] mmu-hash*: Don't use full ppc_hash{32, 64}_translate() path for get_phys_page_debug(), David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 44/45] mmu-hash*: Merge translate and fault handling functions, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 45/45] mmu-hash64: Implement Virtual Page Class Key Protection, David Gibson, 2013/03/05