Update CPUState::interrupt_request once in cpu_interrupt().
Pass the old and new masks along.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/tcg-accel-ops-icount.h | 2 +-
accel/tcg/tcg-accel-ops.h | 2 +-
include/system/accel-ops.h | 2 +-
accel/tcg/tcg-accel-ops-icount.c | 8 +++-----
accel/tcg/tcg-accel-ops.c | 4 +---
system/cpus.c | 12 +++++++-----
6 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/accel/tcg/tcg-accel-ops-icount.h b/accel/tcg/tcg-accel-ops-icount.h
index 16a301b6dc0..1d9d66f0707 100644
--- a/accel/tcg/tcg-accel-ops-icount.h
+++ b/accel/tcg/tcg-accel-ops-icount.h
@@ -15,6 +15,6 @@ void icount_prepare_for_run(CPUState *cpu, int64_t cpu_budget);
int64_t icount_percpu_budget(int cpu_count);
void icount_process_data(CPUState *cpu);
-void icount_handle_interrupt(CPUState *cpu, int mask);
+void icount_handle_interrupt(CPUState *cpu, int old_mask, int new_mask);
#endif /* TCG_ACCEL_OPS_ICOUNT_H */
diff --git a/accel/tcg/tcg-accel-ops.h b/accel/tcg/tcg-accel-ops.h
index 129af89c3e7..3f8eccb7a7f 100644
--- a/accel/tcg/tcg-accel-ops.h
+++ b/accel/tcg/tcg-accel-ops.h
@@ -17,7 +17,7 @@
void tcg_vcpu_thread_precreate(CPUState *cpu);
void tcg_cpu_destroy(CPUState *cpu);
int tcg_cpu_exec(CPUState *cpu);
-void tcg_handle_interrupt(CPUState *cpu, int mask);
+void tcg_handle_interrupt(CPUState *cpu, int old_mask, int new_mask);
void tcg_cpu_init_cflags(CPUState *cpu, bool parallel);
#endif /* TCG_ACCEL_OPS_H */
diff --git a/include/system/accel-ops.h b/include/system/accel-ops.h
index d4bd9c02d14..6d0791d73a4 100644
--- a/include/system/accel-ops.h
+++ b/include/system/accel-ops.h
@@ -67,7 +67,7 @@ struct AccelOpsClass {
void (*synchronize_state)(CPUState *cpu);
void (*synchronize_pre_loadvm)(CPUState *cpu);
- void (*handle_interrupt)(CPUState *cpu, int mask);
+ void (*handle_interrupt)(CPUState *cpu, int old_mask, int new_mask);
/* get_vcpu_stats: Append statistics of this @cpu to @buf */
void (*get_vcpu_stats)(CPUState *cpu, GString *buf);
diff --git a/accel/tcg/tcg-accel-ops-icount.c b/accel/tcg/tcg-accel-ops-icount.c
index d0f7b410fab..500b5dd4942 100644
--- a/accel/tcg/tcg-accel-ops-icount.c
+++ b/accel/tcg/tcg-accel-ops-icount.c
@@ -147,14 +147,12 @@ void icount_process_data(CPUState *cpu)
replay_mutex_unlock();
}
-void icount_handle_interrupt(CPUState *cpu, int mask)
+void icount_handle_interrupt(CPUState *cpu, int old_mask, int new_mask)
{
- int old_mask = cpu->interrupt_request;
-
- tcg_handle_interrupt(cpu, mask);
+ tcg_handle_interrupt(cpu, old_mask, new_mask);
if (qemu_cpu_is_self(cpu) &&
!cpu->neg.can_do_io
- && (mask & ~old_mask) != 0) {
+ && (new_mask & ~old_mask) != 0) {
cpu_abort(cpu, "Raised interrupt while not in I/O function");
}
}
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
index 4931e536beb..a8c24cf8a4c 100644
--- a/accel/tcg/tcg-accel-ops.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -99,10 +99,8 @@ static void tcg_cpu_reset_hold(CPUState *cpu)
}
/* mask must never be zero, except for A20 change call */
-void tcg_handle_interrupt(CPUState *cpu, int mask)
+void tcg_handle_interrupt(CPUState *cpu, int old_mask, int new_mask)
{
- cpu->interrupt_request |= mask;
-
/*
* If called from iothread context, wake the target cpu in
* case its halted.
diff --git a/system/cpus.c b/system/cpus.c
index c2ad640980c..8c2647f5f19 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -246,10 +246,8 @@ int64_t cpus_get_elapsed_ticks(void)
return cpu_get_ticks();
}
-static void generic_handle_interrupt(CPUState *cpu, int mask)
+static void generic_handle_interrupt(CPUState *cpu, int old_mask, int new_mask)
{
- cpu->interrupt_request |= mask;
-
if (!qemu_cpu_is_self(cpu)) {
qemu_cpu_kick(cpu);
}
@@ -257,12 +255,16 @@ static void generic_handle_interrupt(CPUState *cpu, int mask)
void cpu_interrupt(CPUState *cpu, int mask)
{
+ int old_mask = cpu->interrupt_request;
+
g_assert(bql_locked());
+ cpu->interrupt_request |= mask;
+
if (cpus_accel->handle_interrupt) {
- cpus_accel->handle_interrupt(cpu, mask);
+ cpus_accel->handle_interrupt(cpu, old_mask, cpu->interrupt_request);
} else {
- generic_handle_interrupt(cpu, mask);
+ generic_handle_interrupt(cpu, old_mask, cpu->interrupt_request);
}
}
--
2.49.0