Patchwork [4/9] unicore32-softmmu: make sure that kernel can access user space

login
register
mail settings
Submitter Guan Xuetao
Date May 25, 2012, 11:29 a.m.
Message ID <09b1a3e9bb99749459febae17f7e92b201ca7b1d.1337944756.git.gxt@mprc.pku.edu.cn>
Download mbox | patch
Permalink /patch/161297/
State New
Headers show

Comments

Guan Xuetao - May 25, 2012, 11:29 a.m.
Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
---
 target-unicore32/translate.c |   33 ++++++++++++++++++++++++---------
 1 files changed, 24 insertions(+), 9 deletions(-)

Patch

diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index d76fff0..1f0ba4f 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -33,9 +33,16 @@  typedef struct DisasContext {
     int condlabel;
     struct TranslationBlock *tb;
     int singlestep_enabled;
+#ifndef CONFIG_USER_ONLY
+    int user;
+#endif
 } DisasContext;
 
+#ifndef CONFIG_USER_ONLY
+#define IS_USER(s) (s->user)
+#else
 #define IS_USER(s) 1
+#endif
 
 /* These instructions trap after executing, so defer them until after the
    conditional executions state has been updated.  */
@@ -1551,12 +1558,12 @@  static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
 /* load/store I_offset and R_offset */
 static void do_ldst_ir(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
 {
-    unsigned int i;
+    unsigned int mmuindex;
     TCGv tmp;
     TCGv tmp2;
 
     tmp2 = load_reg(s, UCOP_REG_N);
-    i = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
+    mmuindex = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
 
     /* immediate */
     if (UCOP_SET_P) {
@@ -1566,17 +1573,17 @@  static void do_ldst_ir(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
     if (UCOP_SET_L) {
         /* load */
         if (UCOP_SET_B) {
-            tmp = gen_ld8u(tmp2, i);
+            tmp = gen_ld8u(tmp2, mmuindex);
         } else {
-            tmp = gen_ld32(tmp2, i);
+            tmp = gen_ld32(tmp2, mmuindex);
         }
     } else {
         /* store */
         tmp = load_reg(s, UCOP_REG_D);
         if (UCOP_SET_B) {
-            gen_st8(tmp, tmp2, i);
+            gen_st8(tmp, tmp2, mmuindex);
         } else {
-            gen_st32(tmp, tmp2, i);
+            gen_st32(tmp, tmp2, mmuindex);
         }
     }
     if (!UCOP_SET_P) {
@@ -1679,7 +1686,7 @@  static void do_ldst_hwsb(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
 /* load/store multiple words */
 static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
 {
-    unsigned int val, i;
+    unsigned int val, i, mmuindex;
     int j, n, reg, user, loaded_base;
     TCGv tmp;
     TCGv tmp2;
@@ -1700,6 +1707,7 @@  static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
         }
     }
 
+    mmuindex = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
     addr = load_reg(s, UCOP_REG_N);
 
     /* compute total size */
@@ -1744,7 +1752,7 @@  static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
         }
         if (UCOP_SET(i)) {
             if (UCOP_SET_L) { /* load */
-                tmp = gen_ld32(addr, IS_USER(s));
+                tmp = gen_ld32(addr, mmuindex);
                 if (reg == 31) {
                     gen_bx(s, tmp);
                 } else if (user) {
@@ -1772,7 +1780,7 @@  static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
                 } else {
                     tmp = load_reg(s, reg);
                 }
-                gen_st32(tmp, addr, IS_USER(s));
+                gen_st32(tmp, addr, mmuindex);
             }
             j++;
             /* no need to add after the last transfer */
@@ -1953,6 +1961,13 @@  static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
     cpu_F1s = tcg_temp_new_i32();
     cpu_F0d = tcg_temp_new_i64();
     cpu_F1d = tcg_temp_new_i64();
+#ifndef CONFIG_USER_ONLY
+    if ((env->uncached_asr & 0x1f) == 0x10) {
+        dc->user = 1;
+    } else {
+        dc->user = 0;
+    }
+#endif
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
     lj = -1;
     num_insns = 0;