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

Richard Henderson posted 1 patch 6 years ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20180324092614.6176-1-richard.henderson@linaro.org
Test checkpatch passed
Test docker-build@min-glib failed
Test docker-mingw@fedora failed
Test docker-quick@centos6 failed
Test s390x passed
target/hppa/cpu.h       |  4 ++--
target/hppa/translate.c | 12 ++++--------
2 files changed, 6 insertions(+), 10 deletions(-)
[Qemu-devel] [PATCH for-2.12] target/hppa: Include priv level in user-only iaoq
Posted by Richard Henderson 6 years ago
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 <dave.anglin@bell.net>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---

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