[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
- [Qemu-devel] [PATCH 17/45] mmu-hash*: Add hash pte load/store helpers, (continued)
- [Qemu-devel] [PATCH 17/45] mmu-hash*: Add hash pte load/store helpers, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 06/45] target-ppc: Disentangle find_pte(), David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 20/45] mmu-hash*: Remove eaddr field from mmu_ctx_hash{32, 64}, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 16/45] mmu-hash*: Add header file for definitions, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 14/45] target-ppc: Disentangle BAT code for 32-bit hash MMUs, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 22/45] mmu-hash32: Split out handling of direct store segments, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 07/45] target-ppc: Disentangle get_segment(), David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 21/45] mmu-hash*: Combine ppc_hash{32, 64}_get_physical_address and get_segment{32, 64}(), David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 18/45] mmu-hash*: Reduce use of access_type, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 23/45] mmu-hash32: Split direct store segment handling into a helper, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 24/45] mmu-hash*: Cleanup segment-level NX check,
David Gibson <=
- [Qemu-devel] [PATCH 29/45] mmu-hash64: Clean up ppc_hash64_htab_lookup(), David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 25/45] mmu-hash*: Don't keep looking for PTEs after we find a match, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 27/45] mmu-hash*: Make find_pte{32, 64} do more of the job of finding ptes, David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 28/45] mmu-hash*: Remove permission checking from find_pte{32, 64}(), David Gibson, 2013/03/05
- [Qemu-devel] [PATCH 32/45] mmu-hash32: Split BAT size logic from permissions logic, David Gibson, 2013/03/05
- [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