qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 24/45] mmu-hash*: Cleanup segment-level NX check


From: David Gibson
Subject: [Qemu-devel] [PATCH 24/45] mmu-hash*: Cleanup segment-level NX check
Date: Wed, 6 Mar 2013 14:44:12 +1100

On the ppc hash mmus, no-execute can be set at the segment level (on more
recent 64-bit hash mmus it can also be set at the page level).  This patch
separates out this check to make it clearer what is going on, and avoiding
excessive indentation of the remaining translation code.

Signed-off-by: David Gibson <address@hidden>
---
 target-ppc/mmu-hash32.c |   98 +++++++++++++++++++++++------------------------
 target-ppc/mmu-hash64.c |   68 ++++++++++++++++----------------
 2 files changed, 83 insertions(+), 83 deletions(-)

diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index dbde264..d812adb 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -466,10 +466,16 @@ static int ppc_hash32_translate(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
                                        &ctx->raddr, &ctx->prot);
     }
 
+    /* 5. Check for segment level no-execute violation */
+    ctx->nx = !!(sr & SR32_NX);
+    if ((rwx == 2) && ctx->nx) {
+        return -3;
+    }
+
     pr = msr_pr;
     ctx->key = (((sr & SR32_KP) && (pr != 0)) ||
                 ((sr & SR32_KS) && (pr == 0))) ? 1 : 0;
-    ctx->nx = !!(sr & SR32_NX);
+
     vsid = sr & SR32_VSID;
     target_page_bits = TARGET_PAGE_BITS;
     LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
@@ -485,59 +491,53 @@ static int ppc_hash32_translate(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
             ctx->key, ctx->nx, vsid);
     ret = -1;
 
-    /* Check if instruction fetch is allowed, if needed */
-    if (rwx != 2 || ctx->nx == 0) {
-        /* Page address translation */
-        LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
-                " hash " TARGET_FMT_plx "\n",
-                env->htab_base, env->htab_mask, hash);
-        ctx->hash[0] = hash;
-        ctx->hash[1] = ~hash;
-
-        /* Initialize real address with an invalid value */
-        ctx->raddr = (hwaddr)-1ULL;
-        LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
-                " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
-                " hash=" TARGET_FMT_plx "\n",
-                env->htab_base, env->htab_mask, vsid, ctx->ptem,
-                ctx->hash[0]);
-        /* Primary table lookup */
-        ret = find_pte32(env, ctx, eaddr, 0, rwx, target_page_bits);
-        if (ret < 0) {
-            /* Secondary table lookup */
-            LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
-                    " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
-                    " hash=" TARGET_FMT_plx "\n", env->htab_base,
-                    env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
-            ret2 = find_pte32(env, ctx, eaddr, 1, rwx, target_page_bits);
-            if (ret2 != -1) {
-                ret = ret2;
-            }
+    /* Page address translation */
+    LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+            " hash " TARGET_FMT_plx "\n",
+            env->htab_base, env->htab_mask, hash);
+    ctx->hash[0] = hash;
+    ctx->hash[1] = ~hash;
+
+    /* Initialize real address with an invalid value */
+    ctx->raddr = (hwaddr)-1ULL;
+    LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+            " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
+            " hash=" TARGET_FMT_plx "\n",
+            env->htab_base, env->htab_mask, vsid, ctx->ptem,
+            ctx->hash[0]);
+    /* Primary table lookup */
+    ret = find_pte32(env, ctx, eaddr, 0, rwx, target_page_bits);
+    if (ret < 0) {
+        /* Secondary table lookup */
+        LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+                " hash=" TARGET_FMT_plx "\n", env->htab_base,
+                env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
+        ret2 = find_pte32(env, ctx, eaddr, 1, rwx, target_page_bits);
+        if (ret2 != -1) {
+            ret = ret2;
         }
+    }
 #if defined(DUMP_PAGE_TABLES)
-        if (qemu_log_enabled()) {
-            hwaddr curaddr;
-            uint32_t a0, a1, a2, a3;
-
-            qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
-                     "\n", sdr, mask + 0x80);
-            for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
-                 curaddr += 16) {
-                a0 = ldl_phys(curaddr);
-                a1 = ldl_phys(curaddr + 4);
-                a2 = ldl_phys(curaddr + 8);
-                a3 = ldl_phys(curaddr + 12);
-                if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
-                    qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
-                             curaddr, a0, a1, a2, a3);
-                }
+    if (qemu_log_enabled()) {
+        hwaddr curaddr;
+        uint32_t a0, a1, a2, a3;
+
+        qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
+                 "\n", sdr, mask + 0x80);
+        for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
+             curaddr += 16) {
+            a0 = ldl_phys(curaddr);
+            a1 = ldl_phys(curaddr + 4);
+            a2 = ldl_phys(curaddr + 8);
+            a3 = ldl_phys(curaddr + 12);
+            if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
+                qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
+                         curaddr, a0, a1, a2, a3);
             }
         }
-#endif
-    } else {
-        LOG_MMU("No access allowed\n");
-        ret = -3;
     }
+#endif
 
     return ret;
 }
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 9afc418..4fb7ecd 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -454,14 +454,20 @@ static int ppc_hash64_translate(CPUPPCState *env, struct 
mmu_ctx_hash64 *ctx,
         return 0;
     }
 
-    pr = msr_pr;
-
-    LOG_MMU("Check SLBs\n");
+    /* 2. Translation is on, so look up the SLB */
     slb = slb_lookup(env, eaddr);
+
     if (!slb) {
         return -5;
     }
 
+    /* 3. Check for segment level no-execute violation */
+    if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
+        return -3;
+    }
+
+    pr = msr_pr;
+
     if (slb->vsid & SLB_VSID_B) {
         vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
         segment_bits = 40;
@@ -490,38 +496,32 @@ static int ppc_hash64_translate(CPUPPCState *env, struct 
mmu_ctx_hash64 *ctx,
             ctx->key, !!(slb->vsid & SLB_VSID_N), vsid);
     ret = -1;
 
-    /* Check if instruction fetch is allowed, if needed */
-    if (rwx != 2 || !(slb->vsid & SLB_VSID_N)) {
-        /* Page address translation */
-        LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
-                " hash " TARGET_FMT_plx "\n",
-                env->htab_base, env->htab_mask, hash);
-        ctx->hash[0] = hash;
-        ctx->hash[1] = ~hash;
-
-        /* Initialize real address with an invalid value */
-        ctx->raddr = (hwaddr)-1ULL;
-        LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
-                " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
-                " hash=" TARGET_FMT_plx "\n",
-                env->htab_base, env->htab_mask, vsid, ctx->ptem,
-                ctx->hash[0]);
-        /* Primary table lookup */
-        ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits);
-        if (ret < 0) {
-            /* Secondary table lookup */
-            LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
-                    " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
-                    " hash=" TARGET_FMT_plx "\n", env->htab_base,
-                    env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
-            ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits);
-            if (ret2 != -1) {
-                ret = ret2;
-            }
+    /* Page address translation */
+    LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+            " hash " TARGET_FMT_plx "\n",
+            env->htab_base, env->htab_mask, hash);
+    ctx->hash[0] = hash;
+    ctx->hash[1] = ~hash;
+
+    /* Initialize real address with an invalid value */
+    ctx->raddr = (hwaddr)-1ULL;
+    LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+            " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
+            " hash=" TARGET_FMT_plx "\n",
+            env->htab_base, env->htab_mask, vsid, ctx->ptem,
+            ctx->hash[0]);
+    /* Primary table lookup */
+    ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits);
+    if (ret < 0) {
+        /* Secondary table lookup */
+        LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+                " hash=" TARGET_FMT_plx "\n", env->htab_base,
+                env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
+        ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits);
+        if (ret2 != -1) {
+            ret = ret2;
         }
-    } else {
-        LOG_MMU("No access allowed\n");
-        ret = -3;
     }
 
     return ret;
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]