diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-04-16 20:50:30 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-05-15 10:03:44 +0200 |
commit | 5ae8adbb01cdb0bd2f3c1c444b3e543b38737102 (patch) | |
tree | d53a28db99ee474fd3cc0c1aa703ea0113a455a3 | |
parent | d27fe7c3af30a9b6281e7aafb5d603efe64ff939 (diff) | |
download | qemu-5ae8adbb01cdb0bd2f3c1c444b3e543b38737102.zip qemu-5ae8adbb01cdb0bd2f3c1c444b3e543b38737102.tar.gz qemu-5ae8adbb01cdb0bd2f3c1c444b3e543b38737102.tar.bz2 |
target/hppa: Implement PSW_B
PSW_B causes B,GATE to trap as an illegal instruction, removing our
previous sequential execution test that was merely an approximation.
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | target/hppa/translate.c | 25 |
1 files changed, 6 insertions, 19 deletions
diff --git a/target/hppa/translate.c b/target/hppa/translate.c index f7d54f4..f40ac92 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -2062,11 +2062,8 @@ static void do_page_zero(DisasContext *ctx) g_assert_not_reached(); } - /* Check that we didn't arrive here via some means that allowed - non-sequential instruction execution. Normally the PSW[B] bit - detects this by disallowing the B,GATE instruction to execute - under such conditions. */ - if (iaqe_variable(&ctx->iaq_b) || ctx->iaq_b.disp != 4) { + /* If PSW[B] is set, the B,GATE insn would trap. */ + if (ctx->psw_xb & PSW_B) { goto do_sigill; } @@ -3965,23 +3962,13 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a) { int64_t disp = a->disp; - nullify_over(ctx); - - /* Make sure the caller hasn't done something weird with the queue. - * ??? This is not quite the same as the PSW[B] bit, which would be - * expensive to track. Real hardware will trap for - * b gateway - * b gateway+4 (in delay slot of first branch) - * However, checking for a non-sequential instruction queue *will* - * diagnose the security hole - * b gateway - * b evil - * in which instructions at evil would run with increased privs. - */ - if (iaqe_variable(&ctx->iaq_b) || ctx->iaq_b.disp != ctx->iaq_f.disp + 4) { + /* Trap if PSW[B] is set. */ + if (ctx->psw_xb & PSW_B) { return gen_illegal(ctx); } + nullify_over(ctx); + #ifndef CONFIG_USER_ONLY if (ctx->tb_flags & PSW_C) { int type = hppa_artype_for_page(cpu_env(ctx->cs), ctx->base.pc_next); |