qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH for-2.12] target/hppa: Include priv level in user-on


From: Richard Henderson
Subject: [Qemu-devel] [PATCH for-2.12] target/hppa: Include priv level in user-only iaoq
Date: Sat, 24 Mar 2018 17:26:14 +0800

A recent glibc change relies on the fact that the priv level in the iaoq
must be 3, and computes an address based on that.  QEMU had been ignoring
the priv level for user-only, which produced an incorrect address.

Reported-by: John David Anglin <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---

I have not set up everything in order to test this vs current glibc,
but since I'm forcing the value upon starting translation, I expect
it to work.  It does at least work with my current sysroot.


r~
---
 target/hppa/cpu.h       |  4 ++--
 target/hppa/translate.c | 12 ++++--------
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 19dd12a93e..861bbb1f16 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -305,8 +305,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, 
target_ulong *pc,
        incomplete virtual address.  This also means that we must separate
        out current cpu priviledge from the low bits of IAOQ_F.  */
 #ifdef CONFIG_USER_ONLY
-    *pc = env->iaoq_f;
-    *cs_base = env->iaoq_b;
+    *pc = env->iaoq_f & -4;
+    *cs_base = env->iaoq_b & -4;
 #else
     /* ??? E, T, H, L, B, P bits need to be here, when implemented.  */
     flags |= env->psw & (PSW_W | PSW_C | PSW_D);
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 6499b392f9..c532889b1f 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1909,9 +1909,6 @@ static DisasJumpType do_ibranch(DisasContext *ctx, 
TCGv_reg dest,
  */
 static TCGv_reg do_ibranch_priv(DisasContext *ctx, TCGv_reg offset)
 {
-#ifdef CONFIG_USER_ONLY
-    return offset;
-#else
     TCGv_reg dest;
     switch (ctx->privilege) {
     case 0:
@@ -1931,7 +1928,6 @@ static TCGv_reg do_ibranch_priv(DisasContext *ctx, 
TCGv_reg offset)
         break;
     }
     return dest;
-#endif
 }
 
 #ifdef CONFIG_USER_ONLY
@@ -1967,7 +1963,7 @@ static DisasJumpType do_page_zero(DisasContext *ctx)
         goto do_sigill;
     }
 
-    switch (ctx->iaoq_f) {
+    switch (ctx->iaoq_f & -4) {
     case 0x00: /* Null pointer call */
         gen_excp_1(EXCP_IMP);
         return DISAS_NORETURN;
@@ -1978,7 +1974,7 @@ static DisasJumpType do_page_zero(DisasContext *ctx)
 
     case 0xe0: /* SET_THREAD_POINTER */
         tcg_gen_st_reg(cpu_gr[26], cpu_env, offsetof(CPUHPPAState, cr[27]));
-        tcg_gen_mov_reg(cpu_iaoq_f, cpu_gr[31]);
+        tcg_gen_ori_reg(cpu_iaoq_f, cpu_gr[31], 3);
         tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
         return DISAS_IAQ_N_UPDATED;
 
@@ -4697,8 +4693,8 @@ static int hppa_tr_init_disas_context(DisasContextBase 
*dcbase,
 #ifdef CONFIG_USER_ONLY
     ctx->privilege = MMU_USER_IDX;
     ctx->mmu_idx = MMU_USER_IDX;
-    ctx->iaoq_f = ctx->base.pc_first;
-    ctx->iaoq_b = ctx->base.tb->cs_base;
+    ctx->iaoq_f = ctx->base.pc_first | MMU_USER_IDX;
+    ctx->iaoq_b = ctx->base.tb->cs_base | MMU_USER_IDX;
 #else
     ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
     ctx->mmu_idx = (ctx->tb_flags & PSW_D ? ctx->privilege : MMU_PHYS_IDX);
-- 
2.14.3




reply via email to

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