@@ -2061,11 +2061,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;
}
@@ -3964,23 +3961,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);
PSW_B causes B,GATE to trap as an illegal instruction, removing the sequential execution test that was merely an approximation. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/hppa/translate.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-)