Patchwork [09/10] PPC: booke206: Check for TLB overrun

login
register
mail settings
Submitter Alexander Graf
Date Jan. 25, 2012, 5:27 p.m.
Message ID <1327512458-28550-10-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/137801/
State New
Headers show

Comments

Alexander Graf - Jan. 25, 2012, 5:27 p.m.
Our internal helpers to fetch TLB entries were not able to tell us
that an entry doesn't even exist. Pass an error out if we hit such
a case to not accidently pass beyond the TLB array.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h       |    4 ++++
 target-ppc/helper.c    |    3 +++
 target-ppc/op_helper.c |   22 +++++++++++++++++++++-
 target-ppc/translate.c |    1 +
 4 files changed, 29 insertions(+), 1 deletions(-)

Patch

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1026254..668ddf3 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2112,6 +2112,10 @@  static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn,
     ea &= (1 << (tlb_bits - ways_bits)) - 1;
     r = (ea << ways_bits) | way;
 
+    if (r >= booke206_tlb_size(env, tlbn)) {
+        return NULL;
+    }
+
     /* bump up to tlbn index */
     for (i = 0; i < tlbn; i++) {
         r += booke206_tlb_size(env, i);
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 2ce2d92..672494c 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1448,6 +1448,9 @@  static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
 
         for (j = 0; j < ways; j++) {
             tlb = booke206_get_tlbm(env, i, address, j);
+            if (!tlb) {
+                continue;
+            }
             ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
                                         rw, access_type);
             if (ret != -1) {
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 1f1fa09..be4e539 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -4260,6 +4260,12 @@  void helper_booke206_tlbwe(void)
 
     tlb = booke206_cur_tlb(env);
 
+    if (!tlb) {
+        helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+                                   POWERPC_EXCP_INVAL |
+                                   POWERPC_EXCP_INVAL_INVAL);
+    }
+
     /* check that we support the targeted size */
     size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
     size_ps = booke206_tlbnps(env, tlbn);
@@ -4311,7 +4317,11 @@  void helper_booke206_tlbre(void)
     ppcmas_tlb_t *tlb = NULL;
 
     tlb = booke206_cur_tlb(env);
-    booke206_tlb_to_mas(env, tlb);
+    if (!tlb) {
+        env->spr[SPR_BOOKE_MAS1] = 0;
+    } else {
+        booke206_tlb_to_mas(env, tlb);
+    }
 }
 
 void helper_booke206_tlbsx(target_ulong address)
@@ -4330,6 +4340,10 @@  void helper_booke206_tlbsx(target_ulong address)
         for (j = 0; j < ways; j++) {
             tlb = booke206_get_tlbm(env, i, address, j);
 
+            if (!tlb) {
+                continue;
+            }
+
             if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) {
                 continue;
             }
@@ -4373,6 +4387,9 @@  static inline void booke206_invalidate_ea_tlb(CPUState *env, int tlbn,
 
     for (i = 0; i < ways; i++) {
         ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i);
+        if (!tlb) {
+            continue;
+        }
         mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
         if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) &&
             !(tlb->mas1 & MAS1_IPROT)) {
@@ -4453,6 +4470,9 @@  void helper_booke206_tlbilx3(target_ulong address)
 
         for (j = 0; j < ways; j++) {
             tlb = booke206_get_tlbm(env, i, address, j);
+            if (!tlb) {
+                continue;
+            }
             if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) ||
                 (tlb->mas1 & MAS1_IPROT) ||
                 ((tlb->mas1 & MAS1_IND) != ind) ||
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index d8ef719..58a4853 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6088,6 +6088,7 @@  static void gen_tlbwe_booke206(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
         return;
     }
+    gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_booke206_tlbwe();
 #endif
 }