[PULL 9/9] rx: cpu: fix interrupts check in rx_cpu_do_interrupt()

Philippe Mathieu-Daudé posted 9 patches 1 week, 6 days ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Yanan Wang <wangyanan55@huawei.com>, Zhao Liu <zhao1.liu@intel.com>, Alexander Graf <agraf@csgraf.de>, Mads Ynddal <mads@ynddal.dk>, Peter Maydell <peter.maydell@linaro.org>, Cameron Esfahani <dirty@apple.com>, Roman Bolshakov <rbolshakov@ddn.com>, Phil Dennis-Jordan <phil@philjordan.eu>, Yoshinori Sato <yoshinori.sato@nifty.com>
[PULL 9/9] rx: cpu: fix interrupts check in rx_cpu_do_interrupt()
Posted by Philippe Mathieu-Daudé 1 week, 6 days ago
From: Igor Mammedov <imammedo@redhat.com>

Commit 87511341c30 broke interrupt handling, replacing interrupts
fetch with a bool and then the remaining code attempting to check
individual bits on that bool value, which effectively masked those
interrupts.

Fix it by checking individual interrupt bits directly instead of
old 'fetch then check' approach.

Fixes: 87511341c30d ("add cpu_test_interrupt()/cpu_set_interrupt() helpers and use them tree wide")
Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20251030165932.138512-1-imammedo@redhat.com>
[PMD: Rebased on commit dde21df2393 "call plugin trap callbacks"]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/rx/helper.c | 45 ++++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/target/rx/helper.c b/target/rx/helper.c
index ef47e32add8..e9a7aaf610d 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -41,11 +41,9 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
     env->psw_c = FIELD_EX32(psw, PSW, C);
 }
 
-#define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
 void rx_cpu_do_interrupt(CPUState *cs)
 {
     CPURXState *env = cpu_env(cs);
-    int do_irq = cpu_test_interrupt(cs, INT_FLAGS);
     uint32_t save_psw;
     uint64_t last_pc = env->pc;
 
@@ -59,29 +57,26 @@ void rx_cpu_do_interrupt(CPUState *cs)
     save_psw = rx_cpu_pack_psw(env);
     env->psw_pm = env->psw_i = env->psw_u = 0;
 
-    if (do_irq) {
-        if (do_irq & CPU_INTERRUPT_FIR) {
-            env->bpc = env->pc;
-            env->bpsw = save_psw;
-            env->pc = env->fintv;
-            env->psw_ipl = 15;
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_FIR);
-            qemu_set_irq(env->ack, env->ack_irq);
-            qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
-            qemu_log_mask(CPU_LOG_INT, "fast interrupt raised\n");
-        } else if (do_irq & CPU_INTERRUPT_HARD) {
-            env->isp -= 4;
-            cpu_stl_data(env, env->isp, save_psw);
-            env->isp -= 4;
-            cpu_stl_data(env, env->isp, env->pc);
-            env->pc = cpu_ldl_data(env, env->intb + env->ack_irq * 4);
-            env->psw_ipl = env->ack_ipl;
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
-            qemu_set_irq(env->ack, env->ack_irq);
-            qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
-            qemu_log_mask(CPU_LOG_INT,
-                          "interrupt 0x%02x raised\n", env->ack_irq);
-        }
+    if (cpu_test_interrupt(cs, CPU_INTERRUPT_FIR)) {
+        env->bpc = env->pc;
+        env->bpsw = save_psw;
+        env->pc = env->fintv;
+        env->psw_ipl = 15;
+        cpu_reset_interrupt(cs, CPU_INTERRUPT_FIR);
+        qemu_set_irq(env->ack, env->ack_irq);
+        qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+        qemu_log_mask(CPU_LOG_INT, "fast interrupt raised\n");
+    } else if (cpu_test_interrupt(cs, CPU_INTERRUPT_HARD)) {
+        env->isp -= 4;
+        cpu_stl_data(env, env->isp, save_psw);
+        env->isp -= 4;
+        cpu_stl_data(env, env->isp, env->pc);
+        env->pc = cpu_ldl_data(env, env->intb + env->ack_irq * 4);
+        env->psw_ipl = env->ack_ipl;
+        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+        qemu_set_irq(env->ack, env->ack_irq);
+        qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+        qemu_log_mask(CPU_LOG_INT, "interrupt 0x%02x raised\n", env->ack_irq);
     } else {
         uint32_t vec = cs->exception_index;
         const char *expname = "unknown exception";
-- 
2.51.0