Revision | ebd0e151149a6280ea9f4cd9638aea517bb3238b (tree) |
---|---|
Time | 2018-03-26 23:56:57 |
Author | Richard Henderson <richard.henderson@lina...> |
Commiter | Richard Henderson |
target/hppa: Include priv level in user-only iaoq
A recent glibc change relies on the fact that 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>
@@ -305,8 +305,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, target_ulong *pc, | ||
305 | 305 | incomplete virtual address. This also means that we must separate |
306 | 306 | out current cpu priviledge from the low bits of IAOQ_F. */ |
307 | 307 | #ifdef CONFIG_USER_ONLY |
308 | - *pc = env->iaoq_f; | |
309 | - *cs_base = env->iaoq_b; | |
308 | + *pc = env->iaoq_f & -4; | |
309 | + *cs_base = env->iaoq_b & -4; | |
310 | 310 | #else |
311 | 311 | /* ??? E, T, H, L, B, P bits need to be here, when implemented. */ |
312 | 312 | flags |= env->psw & (PSW_W | PSW_C | PSW_D); |
@@ -1909,9 +1909,6 @@ static DisasJumpType do_ibranch(DisasContext *ctx, TCGv_reg dest, | ||
1909 | 1909 | */ |
1910 | 1910 | static TCGv_reg do_ibranch_priv(DisasContext *ctx, TCGv_reg offset) |
1911 | 1911 | { |
1912 | -#ifdef CONFIG_USER_ONLY | |
1913 | - return offset; | |
1914 | -#else | |
1915 | 1912 | TCGv_reg dest; |
1916 | 1913 | switch (ctx->privilege) { |
1917 | 1914 | case 0: |
@@ -1931,7 +1928,6 @@ static TCGv_reg do_ibranch_priv(DisasContext *ctx, TCGv_reg offset) | ||
1931 | 1928 | break; |
1932 | 1929 | } |
1933 | 1930 | return dest; |
1934 | -#endif | |
1935 | 1931 | } |
1936 | 1932 | |
1937 | 1933 | #ifdef CONFIG_USER_ONLY |
@@ -1967,7 +1963,7 @@ static DisasJumpType do_page_zero(DisasContext *ctx) | ||
1967 | 1963 | goto do_sigill; |
1968 | 1964 | } |
1969 | 1965 | |
1970 | - switch (ctx->iaoq_f) { | |
1966 | + switch (ctx->iaoq_f & -4) { | |
1971 | 1967 | case 0x00: /* Null pointer call */ |
1972 | 1968 | gen_excp_1(EXCP_IMP); |
1973 | 1969 | return DISAS_NORETURN; |
@@ -1978,7 +1974,7 @@ static DisasJumpType do_page_zero(DisasContext *ctx) | ||
1978 | 1974 | |
1979 | 1975 | case 0xe0: /* SET_THREAD_POINTER */ |
1980 | 1976 | tcg_gen_st_reg(cpu_gr[26], cpu_env, offsetof(CPUHPPAState, cr[27])); |
1981 | - tcg_gen_mov_reg(cpu_iaoq_f, cpu_gr[31]); | |
1977 | + tcg_gen_ori_reg(cpu_iaoq_f, cpu_gr[31], 3); | |
1982 | 1978 | tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4); |
1983 | 1979 | return DISAS_IAQ_N_UPDATED; |
1984 | 1980 |
@@ -4697,8 +4693,8 @@ static int hppa_tr_init_disas_context(DisasContextBase *dcbase, | ||
4697 | 4693 | #ifdef CONFIG_USER_ONLY |
4698 | 4694 | ctx->privilege = MMU_USER_IDX; |
4699 | 4695 | ctx->mmu_idx = MMU_USER_IDX; |
4700 | - ctx->iaoq_f = ctx->base.pc_first; | |
4701 | - ctx->iaoq_b = ctx->base.tb->cs_base; | |
4696 | + ctx->iaoq_f = ctx->base.pc_first | MMU_USER_IDX; | |
4697 | + ctx->iaoq_b = ctx->base.tb->cs_base | MMU_USER_IDX; | |
4702 | 4698 | #else |
4703 | 4699 | ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3; |
4704 | 4700 | ctx->mmu_idx = (ctx->tb_flags & PSW_D ? ctx->privilege : MMU_PHYS_IDX); |