diff mbox series

[PULL,37/43] target/hppa: Implement PSW_B

Message ID 20240515094043.82850-38-richard.henderson@linaro.org (mailing list archive)
State New, archived
Headers show
Series [PULL,01/43] target/hppa: Move cpu_get_tb_cpu_state out of line | expand

Commit Message

Richard Henderson May 15, 2024, 9:40 a.m. UTC
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>
---
 target/hppa/translate.c | 25 ++++++-------------------
 1 file changed, 6 insertions(+), 19 deletions(-)
diff mbox series

Patch

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f7d54f4009..f40ac92e98 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);