Patchwork [40/45] mmu-hash*: Clean up PTE flags update

login
register
mail settings
Submitter David Gibson
Date March 6, 2013, 3:44 a.m.
Message ID <1362541473-4365-41-git-send-email-david@gibson.dropbear.id.au>
Download mbox | patch
Permalink /patch/225286/
State New
Headers show

Comments

David Gibson - March 6, 2013, 3:44 a.m.
Currently the ppc_hash{32,64}_pte_update_flags() helper functions update a
PTE's referenced and changed bits as necessary to reflect the access.  It
is somewhat long winded, though.  This patch open codes them in their
(single) callers, in a simpler way.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/mmu-hash32.c |   39 ++++++++++++---------------------------
 target-ppc/mmu-hash64.c |   39 ++++++++++++---------------------------
 2 files changed, 24 insertions(+), 54 deletions(-)

Patch

diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 6581d0f..314b7d1 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -274,31 +274,6 @@  static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
     }
 }
 
-static int ppc_hash32_pte_update_flags(struct mmu_ctx_hash32 *ctx, uint32_t *pte1p,
-                                       int ret, int rwx)
-{
-    int store = 0;
-
-    /* Update page flags */
-    if (!(*pte1p & HPTE32_R_R)) {
-        /* Update accessed flag */
-        *pte1p |= HPTE32_R_R;
-        store = 1;
-    }
-    if (!(*pte1p & HPTE32_R_C)) {
-        if (rwx == 1 && ret == 0) {
-            /* Update changed flag */
-            *pte1p |= HPTE32_R_C;
-            store = 1;
-        } else {
-            /* Force page fault for first write access */
-            ctx->prot &= ~PAGE_WRITE;
-        }
-    }
-
-    return store;
-}
-
 hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash)
 {
     return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
@@ -374,6 +349,7 @@  static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
     target_ulong sr;
     hwaddr pte_offset;
     ppc_hash_pte32_t pte;
+    uint32_t new_pte1;
     const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
 
     assert((rwx == 0) || (rwx == 1) || (rwx == 2));
@@ -432,8 +408,17 @@  static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
 
     /* 8. Update PTE referenced and changed bits if necessary */
 
-    if (ppc_hash32_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) {
-        ppc_hash32_store_hpte1(env, pte_offset, pte.pte1);
+    new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */
+    if (rwx == 1) {
+        new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */
+    } else {
+        /* Treat the page as read-only for now, so that a later write
+         * will pass through this function again to set the C bit */
+        ctx->prot &= ~PAGE_WRITE;
+    }
+
+    if (new_pte1 != pte.pte1) {
+        ppc_hash32_store_hpte1(env, pte_offset, new_pte1);
     }
 
     /* Keep the matching PTE informations */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 5607ce8..c76abb7 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -280,31 +280,6 @@  static int ppc_hash64_pte_prot(CPUPPCState *env,
     return prot;
 }
 
-static int ppc_hash64_pte_update_flags(struct mmu_ctx_hash64 *ctx,
-                                       uint64_t *pte1p, int ret, int rw)
-{
-    int store = 0;
-
-    /* Update page flags */
-    if (!(*pte1p & HPTE64_R_R)) {
-        /* Update accessed flag */
-        *pte1p |= HPTE64_R_R;
-        store = 1;
-    }
-    if (!(*pte1p & HPTE64_R_C)) {
-        if (rw == 1 && ret == 0) {
-            /* Update changed flag */
-            *pte1p |= HPTE64_R_C;
-            store = 1;
-        } else {
-            /* Force page fault for first write access */
-            ctx->prot &= ~PAGE_WRITE;
-        }
-    }
-
-    return store;
-}
-
 static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
                                      bool secondary, target_ulong ptem,
                                      ppc_hash_pte64_t *pte)
@@ -393,6 +368,7 @@  static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
     ppc_slb_t *slb;
     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};
 
@@ -440,8 +416,17 @@  static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
 
     /* 6. Update PTE referenced and changed bits if necessary */
 
-    if (ppc_hash64_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) {
-        ppc_hash64_store_hpte1(env, pte_offset, pte.pte1);
+    new_pte1 = pte.pte1 | HPTE64_R_R; /* set referenced bit */
+    if (rwx == 1) {
+        new_pte1 |= HPTE64_R_C; /* set changed (dirty) bit */
+    } else {
+        /* Treat the page as read-only for now, so that a later write
+         * will pass through this function again to set the C bit */
+        ctx->prot &= ~PAGE_WRITE;
+    }
+
+    if (new_pte1 != pte.pte1) {
+        ppc_hash64_store_hpte1(env, pte_offset, new_pte1);
     }
 
     /* Keep the matching PTE informations */