All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path
@ 2020-08-19 18:28 Robert Foley
  2020-08-19 18:28   ` Robert Foley
                   ` (7 more replies)
  0 siblings, 8 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Anthony Green, Mark Cave-Ayland, Thomas Huth,
	Jiaxun Yang, Max Filippov, Alistair Francis, Edgar E. Iglesias,
	Guan Xuetao, Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, Richard Henderson, Artyom Tarasenko,
	Aleksandar Rikalo, robert.foley, Michael Rolnik, pbonzini,
	Stafford Horne, alex.bennee, David Gibson, Bastian Koppelmann,
	Chris Wulff, Laurent Vivier, Michael Walle, Palmer Dabbelt,
	peter.puhov, Aurelien Jarno

The purpose of this change is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

The BQL is a bottleneck in scaling to more cores.
And this cpu_handle_interrupt/exception path is one of
the key BQL users as measured by the QEMU sync profiling (qsp).

As the first step in removing the BQL from this path, we will make
changes to the core/common functions of cpu_handle_interrupt/exception
to drop the holding of the BQL. The holding of the BQL is pushed down
to the per-arch implementation code.

This patch goes through several transitions of the code in order to
maintain correctness (bisectability).  In order to maintain
bisectability across these steps some patches need to touch many
files across different arches, however most of the changes are trivial.

The general order of the changes is below where each step
represents one patch.

1) rename all *_do_interrupt functions to *_do_interrupt_locked

2) add a new function *_do_interrupt that takes the BQL and calls
*_do_interrupt_locked, point ->do_interrupt to it, and remove 
the BQL from cpu-exec.c's cpu_handle_exception.

3) modify the BQL critical sections around
->cpu_exec_interrupt, so that the BQL critical section covers just the
call to ->cpu_exec_interrupt. 

4/5) same as 1/2 for ->cpu_exec_interrupt.  This removes the BQL
from cpu_handle_exception.

This approach of pushing the BQL down to the per arch functions was
suggested by Paolo Bonzini.
For reference, here are several key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

This patch series is based on the per-CPU locks patch:
https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg05314.html

Our most recent WIP tree is here: 
https://github.com/rf972/qemu/tree/interrupts_v2.7

Robert Foley (7):
  target: rename all *_do_interupt functions to _do_interrupt_locked
  target/arm: add ARMCPUClass->do_interrupt_locked
  target/cris: add CRISCPUClass->do_interrupt_locked
  target: Push BQL on ->do_interrupt down into per-arch implementation
  accel/tcg: Change BQL critical section in cpu_handle_interrupt
  target: rename all *_cpu_exec_interrupt functions to
    *_cpu_exec_interrupt_locked
  target: Push BQL on ->cpu_exec_interrupt down into per-arch
    implementation

 accel/tcg/cpu-exec.c        |  8 +-------
 hw/ppc/spapr_events.c       |  2 +-
 target/alpha/helper.c       | 22 +++++++++++++++++++---
 target/arm/cpu-qom.h        |  3 +++
 target/arm/cpu.c            | 16 +++++++++++++---
 target/arm/cpu.h            |  2 ++
 target/arm/cpu_tcg.c        | 19 +++++++++++++++----
 target/arm/helper.c         | 10 +++++++++-
 target/arm/m_helper.c       |  2 +-
 target/avr/helper.c         | 27 ++++++++++++++++++++++-----
 target/cris/cpu-qom.h       |  3 +++
 target/cris/cpu.c           | 11 ++++++-----
 target/cris/cpu.h           |  3 ++-
 target/cris/helper.c        | 35 ++++++++++++++++++++++++++---------
 target/hppa/int_helper.c    | 22 +++++++++++++++++++---
 target/i386/seg_helper.c    | 20 ++++++++++++++++++--
 target/lm32/helper.c        | 22 +++++++++++++++++++---
 target/m68k/op_helper.c     | 22 +++++++++++++++++++---
 target/microblaze/helper.c  | 24 ++++++++++++++++++++----
 target/mips/helper.c        | 22 +++++++++++++++++++---
 target/moxie/cpu.c          |  2 +-
 target/moxie/cpu.h          |  2 +-
 target/moxie/helper.c       |  2 +-
 target/nios2/cpu.c          | 13 +++++++++++--
 target/nios2/cpu.h          |  1 +
 target/nios2/helper.c       | 13 +++++++++++--
 target/openrisc/interrupt.c | 23 ++++++++++++++++++++---
 target/ppc/cpu.h            |  1 +
 target/ppc/excp_helper.c    | 22 +++++++++++++++++++---
 target/ppc/kvm.c            |  2 +-
 target/riscv/cpu_helper.c   | 24 +++++++++++++++++++++---
 target/rx/cpu.h             |  1 +
 target/rx/helper.c          | 22 +++++++++++++++++++---
 target/s390x/excp_helper.c  | 24 ++++++++++++++++++++----
 target/s390x/internal.h     |  1 +
 target/sh4/helper.c         | 25 +++++++++++++++++++++----
 target/sparc/cpu.c          | 13 +++++++++++--
 target/sparc/cpu.h          |  1 +
 target/sparc/int32_helper.c |  9 ++++++++-
 target/sparc/int64_helper.c |  9 ++++++++-
 target/tilegx/cpu.c         | 23 ++++++++++++++++++++---
 target/unicore32/cpu.h      |  1 +
 target/unicore32/helper.c   | 13 +++++++++++--
 target/unicore32/softmmu.c  |  9 ++++++++-
 target/xtensa/exc_helper.c  | 25 +++++++++++++++++++++----
 45 files changed, 476 insertions(+), 100 deletions(-)

-- 
2.17.1



^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v2 1/7] target: rename all *_do_interupt functions to _do_interrupt_locked
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
@ 2020-08-19 18:28   ` Robert Foley
  2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, pbonzini, peter.puhov, robert.foley, David Gibson,
	Richard Henderson, Peter Maydell, Michael Rolnik, Sarah Harris,
	Edgar E. Iglesias, Eduardo Habkost, Michael Walle,
	Laurent Vivier, Aleksandar Markovic, Aurelien Jarno, Jiaxun Yang,
	Aleksandar Rikalo, Anthony Green, Chris Wulff, Marek Vasut,
	Stafford Horne, Palmer Dabbelt, Alistair Francis,
	Sagar Karandikar, Bastian Koppelmann, Yoshinori Sato,
	Cornelia Huck, Thomas Huth, David Hildenbrand, Mark Cave-Ayland,
	Artyom Tarasenko, Guan Xuetao, Max Filippov, open list:sPAPR,
	open list:ARM TCG CPUs, open list:Overall KVM CPUs,
	open list:RISC-V TCG CPUs, open list:S390 general arch...

The rename of all *_do_interrupt functions to *_do_interrupt_locked
is preparation for pushing the BQL lock around these functions
down into the per-arch implementation of *_do_interrupt.
In a later patch which pushes down the lock, we will add
a new *_do_interrupt function which grabs the BQL and calls to
*_do_interrupt_locked.

This is the first patch in a series of transitions to move the
BQL down into the do_interrupt per arch function.  This set of
transitions is needed to maintain bisectability.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.

https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 hw/ppc/spapr_events.c           |  2 +-
 target/alpha/cpu.c              |  2 +-
 target/alpha/cpu.h              |  2 +-
 target/alpha/helper.c           |  4 ++--
 target/arm/cpu.c                |  2 +-
 target/arm/cpu.h                |  4 ++--
 target/arm/cpu_tcg.c            |  2 +-
 target/arm/helper.c             |  2 +-
 target/arm/m_helper.c           |  2 +-
 target/avr/cpu.c                |  2 +-
 target/avr/cpu.h                |  2 +-
 target/avr/helper.c             |  2 +-
 target/cris/cpu.c               | 12 ++++++------
 target/cris/cpu.h               |  4 ++--
 target/cris/helper.c            | 10 +++++-----
 target/hppa/cpu.c               |  2 +-
 target/hppa/cpu.h               |  2 +-
 target/hppa/int_helper.c        |  4 ++--
 target/i386/cpu.c               |  2 +-
 target/i386/cpu.h               |  2 +-
 target/i386/seg_helper.c        |  2 +-
 target/lm32/cpu.c               |  2 +-
 target/lm32/cpu.h               |  2 +-
 target/lm32/helper.c            |  4 ++--
 target/m68k/cpu.c               |  2 +-
 target/m68k/cpu.h               |  2 +-
 target/m68k/op_helper.c         |  4 ++--
 target/microblaze/cpu.c         |  2 +-
 target/microblaze/cpu.h         |  2 +-
 target/microblaze/helper.c      |  6 +++---
 target/mips/cpu.c               |  2 +-
 target/mips/helper.c            |  4 ++--
 target/mips/internal.h          |  2 +-
 target/moxie/cpu.c              |  2 +-
 target/moxie/cpu.h              |  2 +-
 target/moxie/helper.c           |  2 +-
 target/nios2/cpu.c              |  4 ++--
 target/nios2/cpu.h              |  2 +-
 target/nios2/helper.c           |  4 ++--
 target/openrisc/cpu.c           |  2 +-
 target/openrisc/cpu.h           |  2 +-
 target/openrisc/interrupt.c     |  4 ++--
 target/ppc/cpu.h                |  2 +-
 target/ppc/excp_helper.c        |  4 ++--
 target/ppc/kvm.c                |  2 +-
 target/ppc/translate_init.inc.c |  2 +-
 target/riscv/cpu.c              |  2 +-
 target/riscv/cpu.h              |  2 +-
 target/riscv/cpu_helper.c       |  4 ++--
 target/rx/cpu.c                 |  2 +-
 target/rx/cpu.h                 |  2 +-
 target/rx/helper.c              |  4 ++--
 target/s390x/cpu.c              |  2 +-
 target/s390x/excp_helper.c      |  6 +++---
 target/s390x/internal.h         |  2 +-
 target/sh4/cpu.c                |  2 +-
 target/sh4/cpu.h                |  2 +-
 target/sh4/helper.c             |  6 +++---
 target/sparc/cpu.c              |  4 ++--
 target/sparc/cpu.h              |  2 +-
 target/sparc/int32_helper.c     |  2 +-
 target/sparc/int64_helper.c     |  2 +-
 target/tilegx/cpu.c             |  6 +++---
 target/unicore32/cpu.c          |  2 +-
 target/unicore32/cpu.h          |  2 +-
 target/unicore32/helper.c       |  2 +-
 target/unicore32/softmmu.c      |  2 +-
 target/xtensa/cpu.c             |  2 +-
 target/xtensa/cpu.h             |  2 +-
 target/xtensa/exc_helper.c      |  6 +++---
 70 files changed, 103 insertions(+), 103 deletions(-)

diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 1069d0197b..b281022e20 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -879,7 +879,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
     if (spapr->fwnmi_machine_check_addr == -1) {
         /* Non-FWNMI case, deliver it like an architected CPU interrupt. */
         cs->exception_index = POWERPC_EXCP_MCHECK;
-        ppc_cpu_do_interrupt(cs);
+        ppc_cpu_do_interrupt_locked(cs);
         return;
     }
 
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 09677c6c44..cb1074e0f9 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -217,7 +217,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
-    cc->do_interrupt = alpha_cpu_do_interrupt;
+    cc->do_interrupt = alpha_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index be29bdd530..4c6753df34 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -276,7 +276,7 @@ struct AlphaCPU {
 extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
-void alpha_cpu_do_interrupt(CPUState *cpu);
+void alpha_cpu_do_interrupt_locked(CPUState *cpu);
 bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 55d7274d94..ff9a2a7765 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 }
 #endif /* USER_ONLY */
 
-void alpha_cpu_do_interrupt(CPUState *cs)
+void alpha_cpu_do_interrupt_locked(CPUState *cs)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -445,7 +445,7 @@ bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if (idx >= 0) {
         cs->exception_index = idx;
         env->error_code = 0;
-        alpha_cpu_do_interrupt(cs);
+        alpha_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 401832ea95..46c1d92080 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2224,7 +2224,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_read_register = arm_cpu_gdb_read_register;
     cc->gdb_write_register = arm_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_cpu_do_interrupt;
+    cc->do_interrupt = arm_cpu_do_interrupt_locked;
     cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
     cc->asidx_from_attrs = arm_asidx_from_attrs;
     cc->vmsd = &vmstate_arm_cpu;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9e8ed423ea..1f522964b5 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -991,8 +991,8 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz);
 extern const VMStateDescription vmstate_arm_cpu;
 #endif
 
-void arm_cpu_do_interrupt(CPUState *cpu);
-void arm_v7m_cpu_do_interrupt(CPUState *cpu);
+void arm_cpu_do_interrupt_locked(CPUState *cpu);
+void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
 bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 00b0e08f33..2fc7a29340 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -601,7 +601,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
 
     acc->info = data;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_v7m_cpu_do_interrupt;
+    cc->do_interrupt = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
     cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0ef0ef65dd..e07924daf5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9845,7 +9845,7 @@ static void handle_semihosting(CPUState *cs)
  * to the AArch64-entry or AArch32-entry function depending on the
  * target exception level's register width.
  */
-void arm_cpu_do_interrupt(CPUState *cs)
+void arm_cpu_do_interrupt_locked(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 036454234c..ca65b89fae 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -2039,7 +2039,7 @@ gen_invep:
     return false;
 }
 
-void arm_v7m_cpu_do_interrupt(CPUState *cs)
+void arm_v7m_cpu_do_interrupt_locked(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5d9c4ad5bf..d856069230 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -197,7 +197,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = avr_cpu_class_by_name;
 
     cc->has_work = avr_cpu_has_work;
-    cc->do_interrupt = avr_cpu_do_interrupt;
+    cc->do_interrupt = avr_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index d148e8c75a..66a26f08ef 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -156,7 +156,7 @@ typedef struct AVRCPU {
 
 extern const struct VMStateDescription vms_avr_cpu;
 
-void avr_cpu_do_interrupt(CPUState *cpu);
+void avr_cpu_do_interrupt_locked(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index d96d14372b..096bc35945 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -56,7 +56,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     return ret;
 }
 
-void avr_cpu_do_interrupt(CPUState *cs)
+void avr_cpu_do_interrupt_locked(CPUState *cs)
 {
     AVRCPU *cpu = AVR_CPU(cs);
     CPUAVRState *env = &cpu->env;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 6d7e266042..40b110f161 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -199,7 +199,7 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 8;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -210,7 +210,7 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 9;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -221,7 +221,7 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 10;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -232,7 +232,7 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 11;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -243,7 +243,7 @@ static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 17;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -268,7 +268,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = cris_cpu_class_by_name;
     cc->has_work = cris_cpu_has_work;
-    cc->do_interrupt = cris_cpu_do_interrupt;
+    cc->do_interrupt = cris_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 8f08d7628b..597ccd6451 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -187,8 +187,8 @@ struct CRISCPU {
 extern const VMStateDescription vmstate_cris_cpu;
 #endif
 
-void cris_cpu_do_interrupt(CPUState *cpu);
-void crisv10_cpu_do_interrupt(CPUState *cpu);
+void cris_cpu_do_interrupt_locked(CPUState *cpu);
+void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 67946d9246..e0ee6b4e05 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -40,7 +40,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void cris_cpu_do_interrupt(CPUState *cs)
+void cris_cpu_do_interrupt_locked(CPUState *cs)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
@@ -49,9 +49,9 @@ void cris_cpu_do_interrupt(CPUState *cs)
     env->pregs[PR_ERP] = env->pc;
 }
 
-void crisv10_cpu_do_interrupt(CPUState *cs)
+void crisv10_cpu_do_interrupt_locked(CPUState *cs)
 {
-    cris_cpu_do_interrupt(cs);
+    cris_cpu_do_interrupt_locked(cs);
 }
 
 bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -123,7 +123,7 @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit(cs);
 }
 
-void crisv10_cpu_do_interrupt(CPUState *cs)
+void crisv10_cpu_do_interrupt_locked(CPUState *cs)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
@@ -185,7 +185,7 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
                   env->pregs[PR_ERP]);
 }
 
-void cris_cpu_do_interrupt(CPUState *cs)
+void cris_cpu_do_interrupt_locked(CPUState *cs)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 287055f96e..7241ffbd7f 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -139,7 +139,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
-    cc->do_interrupt = hppa_cpu_do_interrupt;
+    cc->do_interrupt = hppa_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 801a4fb1ba..7fc7682ca8 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,7 +323,7 @@ int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc);
 hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void hppa_cpu_do_interrupt(CPUState *cpu);
+void hppa_cpu_do_interrupt_locked(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 462747baf8..31fce959d6 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -90,7 +90,7 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg val)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-void hppa_cpu_do_interrupt(CPUState *cs)
+void hppa_cpu_do_interrupt_locked(CPUState *cs)
 {
     HPPACPU *cpu = HPPA_CPU(cs);
     CPUHPPAState *env = &cpu->env;
@@ -255,7 +255,7 @@ bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     /* If interrupts are requested and enabled, raise them.  */
     if ((env->psw & PSW_I) && (interrupt_request & CPU_INTERRUPT_HARD)) {
         cs->exception_index = EXCP_EXT_INTERRUPT;
-        hppa_cpu_do_interrupt(cs);
+        hppa_cpu_do_interrupt_locked(cs);
         return true;
     }
 #endif
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 592aa0baf7..fdb8ae11b6 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7297,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->parse_features = x86_cpu_parse_featurestr;
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = x86_cpu_do_interrupt;
+    cc->do_interrupt = x86_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
 #endif
     cc->dump_state = x86_cpu_dump_state;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d784eeaf29..8d4dac129b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1770,7 +1770,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * x86_cpu_do_interrupt:
  * @cpu: vCPU the interrupt is to be handled by.
  */
-void x86_cpu_do_interrupt(CPUState *cpu);
+void x86_cpu_do_interrupt_locked(CPUState *cpu);
 bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 818f65f35f..0d8464abec 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1280,7 +1280,7 @@ static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
 #endif
 }
 
-void x86_cpu_do_interrupt(CPUState *cs)
+void x86_cpu_do_interrupt_locked(CPUState *cs)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 9e7d8ca929..93da742520 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -222,7 +222,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
-    cc->do_interrupt = lm32_cpu_do_interrupt;
+    cc->do_interrupt = lm32_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index 01d408eb55..cd96a2905e 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -198,7 +198,7 @@ struct LM32CPU {
 extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
-void lm32_cpu_do_interrupt(CPUState *cpu);
+void lm32_cpu_do_interrupt_locked(CPUState *cpu);
 bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 1130fc8884..8599a59df2 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -148,7 +148,7 @@ void lm32_debug_excp_handler(CPUState *cs)
     }
 }
 
-void lm32_cpu_do_interrupt(CPUState *cs)
+void lm32_cpu_do_interrupt_locked(CPUState *cs)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
@@ -205,7 +205,7 @@ bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
     if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) {
         cs->exception_index = EXCP_IRQ;
-        lm32_cpu_do_interrupt(cs);
+        lm32_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index f2585154f5..6ac0dd87a6 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -277,7 +277,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
-    cc->do_interrupt = m68k_cpu_do_interrupt;
+    cc->do_interrupt = m68k_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 521ac67cdd..1afbe94570 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -164,7 +164,7 @@ struct M68kCPU {
 };
 
 
-void m68k_cpu_do_interrupt(CPUState *cpu);
+void m68k_cpu_do_interrupt_locked(CPUState *cpu);
 bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 4a032a150e..8fd6481883 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -25,7 +25,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void m68k_cpu_do_interrupt(CPUState *cs)
+void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -443,7 +443,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
     cf_interrupt_all(env, is_hw);
 }
 
-void m68k_cpu_do_interrupt(CPUState *cs)
+void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index ce70f7d281..b19e386bcf 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -316,7 +316,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
-    cc->do_interrupt = mb_cpu_do_interrupt;
+    cc->do_interrupt = mb_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a31134b65c..7617565a0c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -315,7 +315,7 @@ struct MicroBlazeCPU {
 };
 
 
-void mb_cpu_do_interrupt(CPUState *cs);
+void mb_cpu_do_interrupt_locked(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index ab2ceeb055..263cdf59be 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -28,7 +28,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void mb_cpu_do_interrupt(CPUState *cs)
+void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -108,7 +108,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-void mb_cpu_do_interrupt(CPUState *cs)
+void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -297,7 +297,7 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
         cs->exception_index = EXCP_IRQ;
-        mb_cpu_do_interrupt(cs);
+        mb_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index ec9dde5100..c616a0ef5a 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -196,7 +196,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
-    cc->do_interrupt = mips_cpu_do_interrupt;
+    cc->do_interrupt = mips_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index afd78b1990..a85c4057d0 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1083,7 +1083,7 @@ static inline void set_badinstr_registers(CPUMIPSState *env)
 }
 #endif
 
-void mips_cpu_do_interrupt(CPUState *cs)
+void mips_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
     MIPSCPU *cpu = MIPS_CPU(cs);
@@ -1409,7 +1409,7 @@ bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
             /* Raise it */
             cs->exception_index = EXCP_EXT_INTERRUPT;
             env->error_code = 0;
-            mips_cpu_do_interrupt(cs);
+            mips_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 7f159a9230..fb0181c095 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -80,7 +80,7 @@ enum CPUMIPSMSADataFormat {
     DF_DOUBLE
 };
 
-void mips_cpu_do_interrupt(CPUState *cpu);
+void mips_cpu_do_interrupt_locked(CPUState *cpu);
 bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index f823eb234d..bba886cfe1 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -107,7 +107,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = moxie_cpu_class_by_name;
 
     cc->has_work = moxie_cpu_has_work;
-    cc->do_interrupt = moxie_cpu_do_interrupt;
+    cc->do_interrupt = moxie_cpu_do_interrupt_locked;
     cc->dump_state = moxie_cpu_dump_state;
     cc->set_pc = moxie_cpu_set_pc;
     cc->tlb_fill = moxie_cpu_tlb_fill;
diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
index 455553b794..1a47ce4d8c 100644
--- a/target/moxie/cpu.h
+++ b/target/moxie/cpu.h
@@ -88,7 +88,7 @@ typedef struct MoxieCPU {
 } MoxieCPU;
 
 
-void moxie_cpu_do_interrupt(CPUState *cs);
+void moxie_cpu_do_interrupt_locked(CPUState *cs);
 void moxie_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 void moxie_translate_init(void);
diff --git a/target/moxie/helper.c b/target/moxie/helper.c
index b1919f62b3..c222895ca5 100644
--- a/target/moxie/helper.c
+++ b/target/moxie/helper.c
@@ -95,7 +95,7 @@ bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-void moxie_cpu_do_interrupt(CPUState *cs)
+void moxie_cpu_do_interrupt_locked(CPUState *cs)
 {
     switch (cs->exception_index) {
     case MOXIE_EX_BREAK:
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index fe5fd9adfd..cc813181a4 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -106,7 +106,7 @@ static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
         (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
         cs->exception_index = EXCP_IRQ;
-        nios2_cpu_do_interrupt(cs);
+        nios2_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
@@ -192,7 +192,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
-    cc->do_interrupt = nios2_cpu_do_interrupt;
+    cc->do_interrupt = nios2_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 4dddf9c3a1..dcf1715092 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -195,7 +195,7 @@ typedef struct Nios2CPU {
 
 
 void nios2_tcg_init(void);
-void nios2_cpu_do_interrupt(CPUState *cs);
+void nios2_cpu_do_interrupt_locked(CPUState *cs);
 int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc);
 void dump_mmu(CPUNios2State *env);
 void nios2_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 57c97bde3c..25c6c6d4d8 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -30,7 +30,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void nios2_cpu_do_interrupt(CPUState *cs)
+void nios2_cpu_do_interrupt_locked(CPUState *cs)
 {
     Nios2CPU *cpu = NIOS2_CPU(cs);
     CPUNios2State *env = &cpu->env;
@@ -48,7 +48,7 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 
 #else /* !CONFIG_USER_ONLY */
 
-void nios2_cpu_do_interrupt(CPUState *cs)
+void nios2_cpu_do_interrupt_locked(CPUState *cs)
 {
     Nios2CPU *cpu = NIOS2_CPU(cs);
     CPUNios2State *env = &cpu->env;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index fd2da39124..e428946dc2 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -154,7 +154,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
-    cc->do_interrupt = openrisc_cpu_do_interrupt;
+    cc->do_interrupt = openrisc_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index f37a52e153..e77f075cd9 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -316,7 +316,7 @@ typedef struct OpenRISCCPU {
 
 
 void cpu_openrisc_list(void);
-void openrisc_cpu_do_interrupt(CPUState *cpu);
+void openrisc_cpu_do_interrupt_locked(CPUState *cpu);
 bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 3eab771dcd..f95289444f 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -26,7 +26,7 @@
 #include "hw/loader.h"
 #endif
 
-void openrisc_cpu_do_interrupt(CPUState *cs)
+void openrisc_cpu_do_interrupt_locked(CPUState *cs)
 {
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -115,7 +115,7 @@ bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     }
     if (idx >= 0) {
         cs->exception_index = idx;
-        openrisc_cpu_do_interrupt(cs);
+        openrisc_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e7d382ac10..ed297acdb4 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1231,7 +1231,7 @@ struct PPCVirtualHypervisorClass {
                      TYPE_PPC_VIRTUAL_HYPERVISOR)
 #endif /* CONFIG_USER_ONLY */
 
-void ppc_cpu_do_interrupt(CPUState *cpu);
+void ppc_cpu_do_interrupt_locked(CPUState *cpu);
 bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index bf9e1e27e9..fe9b122fd0 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -38,7 +38,7 @@
 /*****************************************************************************/
 /* Exception processing */
 #if defined(CONFIG_USER_ONLY)
-void ppc_cpu_do_interrupt(CPUState *cs)
+void ppc_cpu_do_interrupt_locked(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
@@ -865,7 +865,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     powerpc_set_excp_state(cpu, vector, new_msr);
 }
 
-void ppc_cpu_do_interrupt(CPUState *cs)
+void ppc_cpu_do_interrupt_locked(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index f94c45a508..5f0ab06daa 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1650,7 +1650,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
     env->nip += 4;
     cs->exception_index = POWERPC_EXCP_PROGRAM;
     env->error_code = POWERPC_EXCP_INVAL;
-    ppc_cpu_do_interrupt(cs);
+    ppc_cpu_do_interrupt_locked(cs);
 
     return DEBUG_RETURN_GUEST;
 }
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 27ae7fa195..653b04aef6 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10885,7 +10885,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     pcc->parent_parse_features = cc->parse_features;
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
-    cc->do_interrupt = ppc_cpu_do_interrupt;
+    cc->do_interrupt = ppc_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 832171c360..833e6d4f1e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -537,7 +537,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
-    cc->do_interrupt = riscv_cpu_do_interrupt;
+    cc->do_interrupt = riscv_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a804a5d0ba..372005b79c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -312,7 +312,7 @@ extern const char * const riscv_fpr_regnames[];
 extern const char * const riscv_excp_names[];
 extern const char * const riscv_intr_names[];
 
-void riscv_cpu_do_interrupt(CPUState *cpu);
+void riscv_cpu_do_interrupt_locked(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 75d2ae3434..477cf66b66 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -85,7 +85,7 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         int interruptno = riscv_cpu_local_irq_pending(env);
         if (interruptno >= 0) {
             cs->exception_index = RISCV_EXCP_INT_FLAG | interruptno;
-            riscv_cpu_do_interrupt(cs);
+            riscv_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
@@ -820,7 +820,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  * Adapted from Spike's processor_t::take_trap.
  *
  */
-void riscv_cpu_do_interrupt(CPUState *cs)
+void riscv_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
 
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 219e05397b..51e10da7cc 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -185,7 +185,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
 
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
-    cc->do_interrupt = rx_cpu_do_interrupt;
+    cc->do_interrupt = rx_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index d1fb1ef3ca..d188e7d43f 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -125,7 +125,7 @@ typedef RXCPU ArchCPU;
 #define CPU_RESOLVING_TYPE TYPE_RX_CPU
 
 const char *rx_crname(uint8_t cr);
-void rx_cpu_do_interrupt(CPUState *cpu);
+void rx_cpu_do_interrupt_locked(CPUState *cpu);
 bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index a6a337a311..332f89435a 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -42,7 +42,7 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
 }
 
 #define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
-void rx_cpu_do_interrupt(CPUState *cs)
+void rx_cpu_do_interrupt_locked(CPUState *cs)
 {
     RXCPU *cpu = RXCPU(cs);
     CPURXState *env = &cpu->env;
@@ -137,7 +137,7 @@ bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         accept = 1;
     }
     if (accept) {
-        rx_cpu_do_interrupt(cs);
+        rx_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 4d0d323cf9..eb23d64f36 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -493,7 +493,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = s390_cpu_class_by_name,
     cc->has_work_with_iothread_lock = s390_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = s390_cpu_do_interrupt;
+    cc->do_interrupt = s390_cpu_do_interrupt_locked;
 #endif
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index dde7afc2f0..a663127f17 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -85,7 +85,7 @@ void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
 
 #if defined(CONFIG_USER_ONLY)
 
-void s390_cpu_do_interrupt(CPUState *cs)
+void s390_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -464,7 +464,7 @@ static void do_mchk_interrupt(CPUS390XState *env)
     load_psw(env, mask, addr);
 }
 
-void s390_cpu_do_interrupt(CPUState *cs)
+void s390_cpu_do_interrupt_locked(CPUState *cs)
 {
     QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
     S390CPU *cpu = S390_CPU(cs);
@@ -555,7 +555,7 @@ bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
             return false;
         }
         if (s390_cpu_has_int(cpu)) {
-            s390_cpu_do_interrupt(cs);
+            s390_cpu_do_interrupt_locked(cs);
             return true;
         }
         if (env->psw.mask & PSW_MASK_WAIT) {
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index b1e0ebf67f..6ab0fb481a 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -268,7 +268,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 
 /* excp_helper.c */
 void s390x_cpu_debug_excp_handler(CPUState *cs);
-void s390_cpu_do_interrupt(CPUState *cpu);
+void s390_cpu_do_interrupt_locked(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 18f3448183..5e5921a220 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -218,7 +218,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
-    cc->do_interrupt = superh_cpu_do_interrupt;
+    cc->do_interrupt = superh_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index dbe58c7888..2ae3dd132b 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -204,7 +204,7 @@ struct SuperHCPU {
 };
 
 
-void superh_cpu_do_interrupt(CPUState *cpu);
+void superh_cpu_do_interrupt_locked(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 1e32365c75..2d61f65d50 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -45,7 +45,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void superh_cpu_do_interrupt(CPUState *cs)
+void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -58,7 +58,7 @@ int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
 
 #else /* !CONFIG_USER_ONLY */
 
-void superh_cpu_do_interrupt(CPUState *cs)
+void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     SuperHCPU *cpu = SUPERH_CPU(cs);
     CPUSH4State *env = &cpu->env;
@@ -792,7 +792,7 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         if (env->flags & DELAY_SLOT_MASK) {
             return false;
         } else {
-            superh_cpu_do_interrupt(cs);
+            superh_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 20c7c0c434..4c8842adcf 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -89,7 +89,7 @@ static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
             if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) {
                 cs->exception_index = env->interrupt_index;
-                sparc_cpu_do_interrupt(cs);
+                sparc_cpu_do_interrupt_locked(cs);
                 return true;
             }
         }
@@ -863,7 +863,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = sparc_cpu_class_by_name;
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
-    cc->do_interrupt = sparc_cpu_do_interrupt;
+    cc->do_interrupt = sparc_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index b9369398f2..3563e65d73 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -568,7 +568,7 @@ struct SPARCCPU {
 extern const VMStateDescription vmstate_sparc_cpu;
 #endif
 
-void sparc_cpu_do_interrupt(CPUState *cpu);
+void sparc_cpu_do_interrupt_locked(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int sparc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
index 9a71e1abd8..90f4aa4a78 100644
--- a/target/sparc/int32_helper.c
+++ b/target/sparc/int32_helper.c
@@ -65,7 +65,7 @@ static const char *excp_name_str(int32_t exception_index)
     return excp_names[exception_index];
 }
 
-void sparc_cpu_do_interrupt(CPUState *cs)
+void sparc_cpu_do_interrupt_locked(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index f3e7f32de6..b81b4abaa8 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -62,7 +62,7 @@ static const char * const excp_names[0x80] = {
 };
 #endif
 
-void sparc_cpu_do_interrupt(CPUState *cs)
+void sparc_cpu_do_interrupt_locked(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 1fee87c094..a2ff335977 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -105,7 +105,7 @@ static void tilegx_cpu_initfn(Object *obj)
     cpu_set_cpustate_pointers(cpu);
 }
 
-static void tilegx_cpu_do_interrupt(CPUState *cs)
+static void tilegx_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -128,7 +128,7 @@ static bool tilegx_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
-        tilegx_cpu_do_interrupt(cs);
+        tilegx_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
@@ -147,7 +147,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
-    cc->do_interrupt = tilegx_cpu_do_interrupt;
+    cc->do_interrupt = tilegx_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 06bf4b4b63..a96077d666 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -131,7 +131,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
-    cc->do_interrupt = uc32_cpu_do_interrupt;
+    cc->do_interrupt = uc32_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 7a32e086ed..d948392ff3 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -75,7 +75,7 @@ struct UniCore32CPU {
 };
 
 
-void uc32_cpu_do_interrupt(CPUState *cpu);
+void uc32_cpu_do_interrupt_locked(CPUState *cpu);
 bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index 54c26871fe..f024b83bc8 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -175,7 +175,7 @@ bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
         if (!(env->uncached_asr & ASR_I)) {
             cs->exception_index = UC32_EXCP_INTR;
-            uc32_cpu_do_interrupt(cs);
+            uc32_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
index 9660bd2a27..a12526a8ca 100644
--- a/target/unicore32/softmmu.c
+++ b/target/unicore32/softmmu.c
@@ -75,7 +75,7 @@ void switch_mode(CPUUniCore32State *env, int mode)
 }
 
 /* Handle a CPU exception.  */
-void uc32_cpu_do_interrupt(CPUState *cs)
+void uc32_cpu_do_interrupt_locked(CPUState *cs)
 {
     UniCore32CPU *cpu = UNICORE32_CPU(cs);
     CPUUniCore32State *env = &cpu->env;
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 0f96483563..7962bc66a8 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -190,7 +190,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
-    cc->do_interrupt = xtensa_cpu_do_interrupt;
+    cc->do_interrupt = xtensa_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 32749378bf..c02f531b64 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,7 +563,7 @@ struct XtensaCPU {
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
-void xtensa_cpu_do_interrupt(CPUState *cpu);
+void xtensa_cpu_do_interrupt_locked(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 01d1e56feb..10d4762f36 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -195,7 +195,7 @@ static void handle_interrupt(CPUXtensaState *env)
 }
 
 /* Called from cpu_handle_interrupt with BQL held */
-void xtensa_cpu_do_interrupt(CPUState *cs)
+void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
@@ -254,7 +254,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
     check_interrupts(env);
 }
 #else
-void xtensa_cpu_do_interrupt(CPUState *cs)
+void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
 }
 #endif
@@ -263,7 +263,7 @@ bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         cs->exception_index = EXC_IRQ;
-        xtensa_cpu_do_interrupt(cs);
+        xtensa_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 1/7] target: rename all *_do_interupt functions to _do_interrupt_locked
@ 2020-08-19 18:28   ` Robert Foley
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Anthony Green, Mark Cave-Ayland, Thomas Huth,
	Jiaxun Yang, Max Filippov, Alistair Francis, Edgar E. Iglesias,
	Guan Xuetao, Eduardo Habkost, Marek Vasut,
	open list:Overall KVM CPUs, Yoshinori Sato, Aleksandar Markovic,
	open list:sPAPR, Richard Henderson, Artyom Tarasenko,
	Aleksandar Rikalo, robert.foley, open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, open list:RISC-V TCG CPUs,
	Bastian Koppelmann, Chris Wulff, Laurent Vivier, Michael Walle,
	Palmer Dabbelt, peter.puhov, Aurelien Jarno

The rename of all *_do_interrupt functions to *_do_interrupt_locked
is preparation for pushing the BQL lock around these functions
down into the per-arch implementation of *_do_interrupt.
In a later patch which pushes down the lock, we will add
a new *_do_interrupt function which grabs the BQL and calls to
*_do_interrupt_locked.

This is the first patch in a series of transitions to move the
BQL down into the do_interrupt per arch function.  This set of
transitions is needed to maintain bisectability.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.

https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 hw/ppc/spapr_events.c           |  2 +-
 target/alpha/cpu.c              |  2 +-
 target/alpha/cpu.h              |  2 +-
 target/alpha/helper.c           |  4 ++--
 target/arm/cpu.c                |  2 +-
 target/arm/cpu.h                |  4 ++--
 target/arm/cpu_tcg.c            |  2 +-
 target/arm/helper.c             |  2 +-
 target/arm/m_helper.c           |  2 +-
 target/avr/cpu.c                |  2 +-
 target/avr/cpu.h                |  2 +-
 target/avr/helper.c             |  2 +-
 target/cris/cpu.c               | 12 ++++++------
 target/cris/cpu.h               |  4 ++--
 target/cris/helper.c            | 10 +++++-----
 target/hppa/cpu.c               |  2 +-
 target/hppa/cpu.h               |  2 +-
 target/hppa/int_helper.c        |  4 ++--
 target/i386/cpu.c               |  2 +-
 target/i386/cpu.h               |  2 +-
 target/i386/seg_helper.c        |  2 +-
 target/lm32/cpu.c               |  2 +-
 target/lm32/cpu.h               |  2 +-
 target/lm32/helper.c            |  4 ++--
 target/m68k/cpu.c               |  2 +-
 target/m68k/cpu.h               |  2 +-
 target/m68k/op_helper.c         |  4 ++--
 target/microblaze/cpu.c         |  2 +-
 target/microblaze/cpu.h         |  2 +-
 target/microblaze/helper.c      |  6 +++---
 target/mips/cpu.c               |  2 +-
 target/mips/helper.c            |  4 ++--
 target/mips/internal.h          |  2 +-
 target/moxie/cpu.c              |  2 +-
 target/moxie/cpu.h              |  2 +-
 target/moxie/helper.c           |  2 +-
 target/nios2/cpu.c              |  4 ++--
 target/nios2/cpu.h              |  2 +-
 target/nios2/helper.c           |  4 ++--
 target/openrisc/cpu.c           |  2 +-
 target/openrisc/cpu.h           |  2 +-
 target/openrisc/interrupt.c     |  4 ++--
 target/ppc/cpu.h                |  2 +-
 target/ppc/excp_helper.c        |  4 ++--
 target/ppc/kvm.c                |  2 +-
 target/ppc/translate_init.inc.c |  2 +-
 target/riscv/cpu.c              |  2 +-
 target/riscv/cpu.h              |  2 +-
 target/riscv/cpu_helper.c       |  4 ++--
 target/rx/cpu.c                 |  2 +-
 target/rx/cpu.h                 |  2 +-
 target/rx/helper.c              |  4 ++--
 target/s390x/cpu.c              |  2 +-
 target/s390x/excp_helper.c      |  6 +++---
 target/s390x/internal.h         |  2 +-
 target/sh4/cpu.c                |  2 +-
 target/sh4/cpu.h                |  2 +-
 target/sh4/helper.c             |  6 +++---
 target/sparc/cpu.c              |  4 ++--
 target/sparc/cpu.h              |  2 +-
 target/sparc/int32_helper.c     |  2 +-
 target/sparc/int64_helper.c     |  2 +-
 target/tilegx/cpu.c             |  6 +++---
 target/unicore32/cpu.c          |  2 +-
 target/unicore32/cpu.h          |  2 +-
 target/unicore32/helper.c       |  2 +-
 target/unicore32/softmmu.c      |  2 +-
 target/xtensa/cpu.c             |  2 +-
 target/xtensa/cpu.h             |  2 +-
 target/xtensa/exc_helper.c      |  6 +++---
 70 files changed, 103 insertions(+), 103 deletions(-)

diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 1069d0197b..b281022e20 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -879,7 +879,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
     if (spapr->fwnmi_machine_check_addr == -1) {
         /* Non-FWNMI case, deliver it like an architected CPU interrupt. */
         cs->exception_index = POWERPC_EXCP_MCHECK;
-        ppc_cpu_do_interrupt(cs);
+        ppc_cpu_do_interrupt_locked(cs);
         return;
     }
 
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 09677c6c44..cb1074e0f9 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -217,7 +217,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
-    cc->do_interrupt = alpha_cpu_do_interrupt;
+    cc->do_interrupt = alpha_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index be29bdd530..4c6753df34 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -276,7 +276,7 @@ struct AlphaCPU {
 extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
-void alpha_cpu_do_interrupt(CPUState *cpu);
+void alpha_cpu_do_interrupt_locked(CPUState *cpu);
 bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 55d7274d94..ff9a2a7765 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 }
 #endif /* USER_ONLY */
 
-void alpha_cpu_do_interrupt(CPUState *cs)
+void alpha_cpu_do_interrupt_locked(CPUState *cs)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -445,7 +445,7 @@ bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if (idx >= 0) {
         cs->exception_index = idx;
         env->error_code = 0;
-        alpha_cpu_do_interrupt(cs);
+        alpha_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 401832ea95..46c1d92080 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2224,7 +2224,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_read_register = arm_cpu_gdb_read_register;
     cc->gdb_write_register = arm_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_cpu_do_interrupt;
+    cc->do_interrupt = arm_cpu_do_interrupt_locked;
     cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
     cc->asidx_from_attrs = arm_asidx_from_attrs;
     cc->vmsd = &vmstate_arm_cpu;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9e8ed423ea..1f522964b5 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -991,8 +991,8 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz);
 extern const VMStateDescription vmstate_arm_cpu;
 #endif
 
-void arm_cpu_do_interrupt(CPUState *cpu);
-void arm_v7m_cpu_do_interrupt(CPUState *cpu);
+void arm_cpu_do_interrupt_locked(CPUState *cpu);
+void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
 bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 00b0e08f33..2fc7a29340 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -601,7 +601,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
 
     acc->info = data;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_v7m_cpu_do_interrupt;
+    cc->do_interrupt = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
     cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0ef0ef65dd..e07924daf5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9845,7 +9845,7 @@ static void handle_semihosting(CPUState *cs)
  * to the AArch64-entry or AArch32-entry function depending on the
  * target exception level's register width.
  */
-void arm_cpu_do_interrupt(CPUState *cs)
+void arm_cpu_do_interrupt_locked(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 036454234c..ca65b89fae 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -2039,7 +2039,7 @@ gen_invep:
     return false;
 }
 
-void arm_v7m_cpu_do_interrupt(CPUState *cs)
+void arm_v7m_cpu_do_interrupt_locked(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5d9c4ad5bf..d856069230 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -197,7 +197,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = avr_cpu_class_by_name;
 
     cc->has_work = avr_cpu_has_work;
-    cc->do_interrupt = avr_cpu_do_interrupt;
+    cc->do_interrupt = avr_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index d148e8c75a..66a26f08ef 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -156,7 +156,7 @@ typedef struct AVRCPU {
 
 extern const struct VMStateDescription vms_avr_cpu;
 
-void avr_cpu_do_interrupt(CPUState *cpu);
+void avr_cpu_do_interrupt_locked(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index d96d14372b..096bc35945 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -56,7 +56,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     return ret;
 }
 
-void avr_cpu_do_interrupt(CPUState *cs)
+void avr_cpu_do_interrupt_locked(CPUState *cs)
 {
     AVRCPU *cpu = AVR_CPU(cs);
     CPUAVRState *env = &cpu->env;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 6d7e266042..40b110f161 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -199,7 +199,7 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 8;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -210,7 +210,7 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 9;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -221,7 +221,7 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 10;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -232,7 +232,7 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 11;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -243,7 +243,7 @@ static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 17;
-    cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -268,7 +268,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = cris_cpu_class_by_name;
     cc->has_work = cris_cpu_has_work;
-    cc->do_interrupt = cris_cpu_do_interrupt;
+    cc->do_interrupt = cris_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 8f08d7628b..597ccd6451 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -187,8 +187,8 @@ struct CRISCPU {
 extern const VMStateDescription vmstate_cris_cpu;
 #endif
 
-void cris_cpu_do_interrupt(CPUState *cpu);
-void crisv10_cpu_do_interrupt(CPUState *cpu);
+void cris_cpu_do_interrupt_locked(CPUState *cpu);
+void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 67946d9246..e0ee6b4e05 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -40,7 +40,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void cris_cpu_do_interrupt(CPUState *cs)
+void cris_cpu_do_interrupt_locked(CPUState *cs)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
@@ -49,9 +49,9 @@ void cris_cpu_do_interrupt(CPUState *cs)
     env->pregs[PR_ERP] = env->pc;
 }
 
-void crisv10_cpu_do_interrupt(CPUState *cs)
+void crisv10_cpu_do_interrupt_locked(CPUState *cs)
 {
-    cris_cpu_do_interrupt(cs);
+    cris_cpu_do_interrupt_locked(cs);
 }
 
 bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -123,7 +123,7 @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit(cs);
 }
 
-void crisv10_cpu_do_interrupt(CPUState *cs)
+void crisv10_cpu_do_interrupt_locked(CPUState *cs)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
@@ -185,7 +185,7 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
                   env->pregs[PR_ERP]);
 }
 
-void cris_cpu_do_interrupt(CPUState *cs)
+void cris_cpu_do_interrupt_locked(CPUState *cs)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 287055f96e..7241ffbd7f 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -139,7 +139,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
-    cc->do_interrupt = hppa_cpu_do_interrupt;
+    cc->do_interrupt = hppa_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 801a4fb1ba..7fc7682ca8 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,7 +323,7 @@ int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc);
 hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void hppa_cpu_do_interrupt(CPUState *cpu);
+void hppa_cpu_do_interrupt_locked(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 462747baf8..31fce959d6 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -90,7 +90,7 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg val)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-void hppa_cpu_do_interrupt(CPUState *cs)
+void hppa_cpu_do_interrupt_locked(CPUState *cs)
 {
     HPPACPU *cpu = HPPA_CPU(cs);
     CPUHPPAState *env = &cpu->env;
@@ -255,7 +255,7 @@ bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     /* If interrupts are requested and enabled, raise them.  */
     if ((env->psw & PSW_I) && (interrupt_request & CPU_INTERRUPT_HARD)) {
         cs->exception_index = EXCP_EXT_INTERRUPT;
-        hppa_cpu_do_interrupt(cs);
+        hppa_cpu_do_interrupt_locked(cs);
         return true;
     }
 #endif
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 592aa0baf7..fdb8ae11b6 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7297,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->parse_features = x86_cpu_parse_featurestr;
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = x86_cpu_do_interrupt;
+    cc->do_interrupt = x86_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
 #endif
     cc->dump_state = x86_cpu_dump_state;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d784eeaf29..8d4dac129b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1770,7 +1770,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * x86_cpu_do_interrupt:
  * @cpu: vCPU the interrupt is to be handled by.
  */
-void x86_cpu_do_interrupt(CPUState *cpu);
+void x86_cpu_do_interrupt_locked(CPUState *cpu);
 bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 818f65f35f..0d8464abec 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1280,7 +1280,7 @@ static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
 #endif
 }
 
-void x86_cpu_do_interrupt(CPUState *cs)
+void x86_cpu_do_interrupt_locked(CPUState *cs)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 9e7d8ca929..93da742520 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -222,7 +222,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
-    cc->do_interrupt = lm32_cpu_do_interrupt;
+    cc->do_interrupt = lm32_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index 01d408eb55..cd96a2905e 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -198,7 +198,7 @@ struct LM32CPU {
 extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
-void lm32_cpu_do_interrupt(CPUState *cpu);
+void lm32_cpu_do_interrupt_locked(CPUState *cpu);
 bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 1130fc8884..8599a59df2 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -148,7 +148,7 @@ void lm32_debug_excp_handler(CPUState *cs)
     }
 }
 
-void lm32_cpu_do_interrupt(CPUState *cs)
+void lm32_cpu_do_interrupt_locked(CPUState *cs)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
@@ -205,7 +205,7 @@ bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
     if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) {
         cs->exception_index = EXCP_IRQ;
-        lm32_cpu_do_interrupt(cs);
+        lm32_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index f2585154f5..6ac0dd87a6 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -277,7 +277,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
-    cc->do_interrupt = m68k_cpu_do_interrupt;
+    cc->do_interrupt = m68k_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 521ac67cdd..1afbe94570 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -164,7 +164,7 @@ struct M68kCPU {
 };
 
 
-void m68k_cpu_do_interrupt(CPUState *cpu);
+void m68k_cpu_do_interrupt_locked(CPUState *cpu);
 bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 4a032a150e..8fd6481883 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -25,7 +25,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void m68k_cpu_do_interrupt(CPUState *cs)
+void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -443,7 +443,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
     cf_interrupt_all(env, is_hw);
 }
 
-void m68k_cpu_do_interrupt(CPUState *cs)
+void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index ce70f7d281..b19e386bcf 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -316,7 +316,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
-    cc->do_interrupt = mb_cpu_do_interrupt;
+    cc->do_interrupt = mb_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a31134b65c..7617565a0c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -315,7 +315,7 @@ struct MicroBlazeCPU {
 };
 
 
-void mb_cpu_do_interrupt(CPUState *cs);
+void mb_cpu_do_interrupt_locked(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index ab2ceeb055..263cdf59be 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -28,7 +28,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void mb_cpu_do_interrupt(CPUState *cs)
+void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -108,7 +108,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-void mb_cpu_do_interrupt(CPUState *cs)
+void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -297,7 +297,7 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
         cs->exception_index = EXCP_IRQ;
-        mb_cpu_do_interrupt(cs);
+        mb_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index ec9dde5100..c616a0ef5a 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -196,7 +196,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
-    cc->do_interrupt = mips_cpu_do_interrupt;
+    cc->do_interrupt = mips_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index afd78b1990..a85c4057d0 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1083,7 +1083,7 @@ static inline void set_badinstr_registers(CPUMIPSState *env)
 }
 #endif
 
-void mips_cpu_do_interrupt(CPUState *cs)
+void mips_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
     MIPSCPU *cpu = MIPS_CPU(cs);
@@ -1409,7 +1409,7 @@ bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
             /* Raise it */
             cs->exception_index = EXCP_EXT_INTERRUPT;
             env->error_code = 0;
-            mips_cpu_do_interrupt(cs);
+            mips_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 7f159a9230..fb0181c095 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -80,7 +80,7 @@ enum CPUMIPSMSADataFormat {
     DF_DOUBLE
 };
 
-void mips_cpu_do_interrupt(CPUState *cpu);
+void mips_cpu_do_interrupt_locked(CPUState *cpu);
 bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index f823eb234d..bba886cfe1 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -107,7 +107,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = moxie_cpu_class_by_name;
 
     cc->has_work = moxie_cpu_has_work;
-    cc->do_interrupt = moxie_cpu_do_interrupt;
+    cc->do_interrupt = moxie_cpu_do_interrupt_locked;
     cc->dump_state = moxie_cpu_dump_state;
     cc->set_pc = moxie_cpu_set_pc;
     cc->tlb_fill = moxie_cpu_tlb_fill;
diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
index 455553b794..1a47ce4d8c 100644
--- a/target/moxie/cpu.h
+++ b/target/moxie/cpu.h
@@ -88,7 +88,7 @@ typedef struct MoxieCPU {
 } MoxieCPU;
 
 
-void moxie_cpu_do_interrupt(CPUState *cs);
+void moxie_cpu_do_interrupt_locked(CPUState *cs);
 void moxie_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 void moxie_translate_init(void);
diff --git a/target/moxie/helper.c b/target/moxie/helper.c
index b1919f62b3..c222895ca5 100644
--- a/target/moxie/helper.c
+++ b/target/moxie/helper.c
@@ -95,7 +95,7 @@ bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-void moxie_cpu_do_interrupt(CPUState *cs)
+void moxie_cpu_do_interrupt_locked(CPUState *cs)
 {
     switch (cs->exception_index) {
     case MOXIE_EX_BREAK:
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index fe5fd9adfd..cc813181a4 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -106,7 +106,7 @@ static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
         (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
         cs->exception_index = EXCP_IRQ;
-        nios2_cpu_do_interrupt(cs);
+        nios2_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
@@ -192,7 +192,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
-    cc->do_interrupt = nios2_cpu_do_interrupt;
+    cc->do_interrupt = nios2_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 4dddf9c3a1..dcf1715092 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -195,7 +195,7 @@ typedef struct Nios2CPU {
 
 
 void nios2_tcg_init(void);
-void nios2_cpu_do_interrupt(CPUState *cs);
+void nios2_cpu_do_interrupt_locked(CPUState *cs);
 int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc);
 void dump_mmu(CPUNios2State *env);
 void nios2_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 57c97bde3c..25c6c6d4d8 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -30,7 +30,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void nios2_cpu_do_interrupt(CPUState *cs)
+void nios2_cpu_do_interrupt_locked(CPUState *cs)
 {
     Nios2CPU *cpu = NIOS2_CPU(cs);
     CPUNios2State *env = &cpu->env;
@@ -48,7 +48,7 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 
 #else /* !CONFIG_USER_ONLY */
 
-void nios2_cpu_do_interrupt(CPUState *cs)
+void nios2_cpu_do_interrupt_locked(CPUState *cs)
 {
     Nios2CPU *cpu = NIOS2_CPU(cs);
     CPUNios2State *env = &cpu->env;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index fd2da39124..e428946dc2 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -154,7 +154,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
-    cc->do_interrupt = openrisc_cpu_do_interrupt;
+    cc->do_interrupt = openrisc_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index f37a52e153..e77f075cd9 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -316,7 +316,7 @@ typedef struct OpenRISCCPU {
 
 
 void cpu_openrisc_list(void);
-void openrisc_cpu_do_interrupt(CPUState *cpu);
+void openrisc_cpu_do_interrupt_locked(CPUState *cpu);
 bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 3eab771dcd..f95289444f 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -26,7 +26,7 @@
 #include "hw/loader.h"
 #endif
 
-void openrisc_cpu_do_interrupt(CPUState *cs)
+void openrisc_cpu_do_interrupt_locked(CPUState *cs)
 {
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -115,7 +115,7 @@ bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     }
     if (idx >= 0) {
         cs->exception_index = idx;
-        openrisc_cpu_do_interrupt(cs);
+        openrisc_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e7d382ac10..ed297acdb4 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1231,7 +1231,7 @@ struct PPCVirtualHypervisorClass {
                      TYPE_PPC_VIRTUAL_HYPERVISOR)
 #endif /* CONFIG_USER_ONLY */
 
-void ppc_cpu_do_interrupt(CPUState *cpu);
+void ppc_cpu_do_interrupt_locked(CPUState *cpu);
 bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index bf9e1e27e9..fe9b122fd0 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -38,7 +38,7 @@
 /*****************************************************************************/
 /* Exception processing */
 #if defined(CONFIG_USER_ONLY)
-void ppc_cpu_do_interrupt(CPUState *cs)
+void ppc_cpu_do_interrupt_locked(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
@@ -865,7 +865,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     powerpc_set_excp_state(cpu, vector, new_msr);
 }
 
-void ppc_cpu_do_interrupt(CPUState *cs)
+void ppc_cpu_do_interrupt_locked(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index f94c45a508..5f0ab06daa 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1650,7 +1650,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
     env->nip += 4;
     cs->exception_index = POWERPC_EXCP_PROGRAM;
     env->error_code = POWERPC_EXCP_INVAL;
-    ppc_cpu_do_interrupt(cs);
+    ppc_cpu_do_interrupt_locked(cs);
 
     return DEBUG_RETURN_GUEST;
 }
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 27ae7fa195..653b04aef6 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10885,7 +10885,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     pcc->parent_parse_features = cc->parse_features;
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
-    cc->do_interrupt = ppc_cpu_do_interrupt;
+    cc->do_interrupt = ppc_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 832171c360..833e6d4f1e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -537,7 +537,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
-    cc->do_interrupt = riscv_cpu_do_interrupt;
+    cc->do_interrupt = riscv_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a804a5d0ba..372005b79c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -312,7 +312,7 @@ extern const char * const riscv_fpr_regnames[];
 extern const char * const riscv_excp_names[];
 extern const char * const riscv_intr_names[];
 
-void riscv_cpu_do_interrupt(CPUState *cpu);
+void riscv_cpu_do_interrupt_locked(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 75d2ae3434..477cf66b66 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -85,7 +85,7 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         int interruptno = riscv_cpu_local_irq_pending(env);
         if (interruptno >= 0) {
             cs->exception_index = RISCV_EXCP_INT_FLAG | interruptno;
-            riscv_cpu_do_interrupt(cs);
+            riscv_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
@@ -820,7 +820,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  * Adapted from Spike's processor_t::take_trap.
  *
  */
-void riscv_cpu_do_interrupt(CPUState *cs)
+void riscv_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
 
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 219e05397b..51e10da7cc 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -185,7 +185,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
 
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
-    cc->do_interrupt = rx_cpu_do_interrupt;
+    cc->do_interrupt = rx_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index d1fb1ef3ca..d188e7d43f 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -125,7 +125,7 @@ typedef RXCPU ArchCPU;
 #define CPU_RESOLVING_TYPE TYPE_RX_CPU
 
 const char *rx_crname(uint8_t cr);
-void rx_cpu_do_interrupt(CPUState *cpu);
+void rx_cpu_do_interrupt_locked(CPUState *cpu);
 bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index a6a337a311..332f89435a 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -42,7 +42,7 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
 }
 
 #define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
-void rx_cpu_do_interrupt(CPUState *cs)
+void rx_cpu_do_interrupt_locked(CPUState *cs)
 {
     RXCPU *cpu = RXCPU(cs);
     CPURXState *env = &cpu->env;
@@ -137,7 +137,7 @@ bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         accept = 1;
     }
     if (accept) {
-        rx_cpu_do_interrupt(cs);
+        rx_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 4d0d323cf9..eb23d64f36 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -493,7 +493,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = s390_cpu_class_by_name,
     cc->has_work_with_iothread_lock = s390_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = s390_cpu_do_interrupt;
+    cc->do_interrupt = s390_cpu_do_interrupt_locked;
 #endif
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index dde7afc2f0..a663127f17 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -85,7 +85,7 @@ void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
 
 #if defined(CONFIG_USER_ONLY)
 
-void s390_cpu_do_interrupt(CPUState *cs)
+void s390_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -464,7 +464,7 @@ static void do_mchk_interrupt(CPUS390XState *env)
     load_psw(env, mask, addr);
 }
 
-void s390_cpu_do_interrupt(CPUState *cs)
+void s390_cpu_do_interrupt_locked(CPUState *cs)
 {
     QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
     S390CPU *cpu = S390_CPU(cs);
@@ -555,7 +555,7 @@ bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
             return false;
         }
         if (s390_cpu_has_int(cpu)) {
-            s390_cpu_do_interrupt(cs);
+            s390_cpu_do_interrupt_locked(cs);
             return true;
         }
         if (env->psw.mask & PSW_MASK_WAIT) {
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index b1e0ebf67f..6ab0fb481a 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -268,7 +268,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 
 /* excp_helper.c */
 void s390x_cpu_debug_excp_handler(CPUState *cs);
-void s390_cpu_do_interrupt(CPUState *cpu);
+void s390_cpu_do_interrupt_locked(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 18f3448183..5e5921a220 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -218,7 +218,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
-    cc->do_interrupt = superh_cpu_do_interrupt;
+    cc->do_interrupt = superh_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index dbe58c7888..2ae3dd132b 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -204,7 +204,7 @@ struct SuperHCPU {
 };
 
 
-void superh_cpu_do_interrupt(CPUState *cpu);
+void superh_cpu_do_interrupt_locked(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 1e32365c75..2d61f65d50 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -45,7 +45,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void superh_cpu_do_interrupt(CPUState *cs)
+void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -58,7 +58,7 @@ int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
 
 #else /* !CONFIG_USER_ONLY */
 
-void superh_cpu_do_interrupt(CPUState *cs)
+void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     SuperHCPU *cpu = SUPERH_CPU(cs);
     CPUSH4State *env = &cpu->env;
@@ -792,7 +792,7 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         if (env->flags & DELAY_SLOT_MASK) {
             return false;
         } else {
-            superh_cpu_do_interrupt(cs);
+            superh_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 20c7c0c434..4c8842adcf 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -89,7 +89,7 @@ static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
             if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) {
                 cs->exception_index = env->interrupt_index;
-                sparc_cpu_do_interrupt(cs);
+                sparc_cpu_do_interrupt_locked(cs);
                 return true;
             }
         }
@@ -863,7 +863,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = sparc_cpu_class_by_name;
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
-    cc->do_interrupt = sparc_cpu_do_interrupt;
+    cc->do_interrupt = sparc_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index b9369398f2..3563e65d73 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -568,7 +568,7 @@ struct SPARCCPU {
 extern const VMStateDescription vmstate_sparc_cpu;
 #endif
 
-void sparc_cpu_do_interrupt(CPUState *cpu);
+void sparc_cpu_do_interrupt_locked(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int sparc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
index 9a71e1abd8..90f4aa4a78 100644
--- a/target/sparc/int32_helper.c
+++ b/target/sparc/int32_helper.c
@@ -65,7 +65,7 @@ static const char *excp_name_str(int32_t exception_index)
     return excp_names[exception_index];
 }
 
-void sparc_cpu_do_interrupt(CPUState *cs)
+void sparc_cpu_do_interrupt_locked(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index f3e7f32de6..b81b4abaa8 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -62,7 +62,7 @@ static const char * const excp_names[0x80] = {
 };
 #endif
 
-void sparc_cpu_do_interrupt(CPUState *cs)
+void sparc_cpu_do_interrupt_locked(CPUState *cs)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 1fee87c094..a2ff335977 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -105,7 +105,7 @@ static void tilegx_cpu_initfn(Object *obj)
     cpu_set_cpustate_pointers(cpu);
 }
 
-static void tilegx_cpu_do_interrupt(CPUState *cs)
+static void tilegx_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -128,7 +128,7 @@ static bool tilegx_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
-        tilegx_cpu_do_interrupt(cs);
+        tilegx_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
@@ -147,7 +147,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
-    cc->do_interrupt = tilegx_cpu_do_interrupt;
+    cc->do_interrupt = tilegx_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 06bf4b4b63..a96077d666 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -131,7 +131,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
-    cc->do_interrupt = uc32_cpu_do_interrupt;
+    cc->do_interrupt = uc32_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 7a32e086ed..d948392ff3 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -75,7 +75,7 @@ struct UniCore32CPU {
 };
 
 
-void uc32_cpu_do_interrupt(CPUState *cpu);
+void uc32_cpu_do_interrupt_locked(CPUState *cpu);
 bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index 54c26871fe..f024b83bc8 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -175,7 +175,7 @@ bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
         if (!(env->uncached_asr & ASR_I)) {
             cs->exception_index = UC32_EXCP_INTR;
-            uc32_cpu_do_interrupt(cs);
+            uc32_cpu_do_interrupt_locked(cs);
             return true;
         }
     }
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
index 9660bd2a27..a12526a8ca 100644
--- a/target/unicore32/softmmu.c
+++ b/target/unicore32/softmmu.c
@@ -75,7 +75,7 @@ void switch_mode(CPUUniCore32State *env, int mode)
 }
 
 /* Handle a CPU exception.  */
-void uc32_cpu_do_interrupt(CPUState *cs)
+void uc32_cpu_do_interrupt_locked(CPUState *cs)
 {
     UniCore32CPU *cpu = UNICORE32_CPU(cs);
     CPUUniCore32State *env = &cpu->env;
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 0f96483563..7962bc66a8 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -190,7 +190,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
-    cc->do_interrupt = xtensa_cpu_do_interrupt;
+    cc->do_interrupt = xtensa_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 32749378bf..c02f531b64 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,7 +563,7 @@ struct XtensaCPU {
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
-void xtensa_cpu_do_interrupt(CPUState *cpu);
+void xtensa_cpu_do_interrupt_locked(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 01d1e56feb..10d4762f36 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -195,7 +195,7 @@ static void handle_interrupt(CPUXtensaState *env)
 }
 
 /* Called from cpu_handle_interrupt with BQL held */
-void xtensa_cpu_do_interrupt(CPUState *cs)
+void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
@@ -254,7 +254,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
     check_interrupts(env);
 }
 #else
-void xtensa_cpu_do_interrupt(CPUState *cs)
+void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
 }
 #endif
@@ -263,7 +263,7 @@ bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         cs->exception_index = EXC_IRQ;
-        xtensa_cpu_do_interrupt(cs);
+        xtensa_cpu_do_interrupt_locked(cs);
         return true;
     }
     return false;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-19 18:28 ` Robert Foley
  2020-08-31 21:18   ` Richard Henderson
  2020-08-19 18:28 ` [PATCH v2 3/7] target/cris: add CRISCPUClass->do_interrupt_locked Robert Foley
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, robert.foley, open list:ARM TCG CPUs, peter.puhov,
	pbonzini, alex.bennee

Adding ->do_interrupt_locked to ARMCPUClass is preparation for
pushing the BQL down into the per-arch implementation of ->do_interrupt.

This is needed since ARM's *_cpu_exec_interrupt calls to *_do_interrupt.
With the push down of the BQL into *_cpu_exec_interrupt and
*_do_interrupt, *_cpu_exec_interrupt will call to ->do_interrupt
with lock held.  Since ->do_interrupt also has the lock, we need a way
to allow cpu_exec_interrupt to call do_interrupt with lock held.
This patch solves this issue of *_cpu_exec_interrupt needing
to call do_interrupt with lock held.

This patch is part of a series of transitions to move the
BQL down into the do_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

This approach was suggested by Paolo Bonzini.
For reference, here are two key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 target/arm/cpu-qom.h | 3 +++
 target/arm/cpu.c     | 5 +++--
 target/arm/cpu_tcg.c | 5 +++--
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
index 56395b87f6..264280194c 100644
--- a/target/arm/cpu-qom.h
+++ b/target/arm/cpu-qom.h
@@ -48,6 +48,7 @@ void aarch64_cpu_register(const ARMCPUInfo *info);
  * ARMCPUClass:
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
+ * @do_interrupt_locked: Handler for interrupts (lock already held).
  *
  * An ARM CPU model.
  */
@@ -59,6 +60,8 @@ typedef struct ARMCPUClass {
     const ARMCPUInfo *info;
     DeviceRealize parent_realize;
     DeviceReset parent_reset;
+
+    void (*do_interrupt_locked)(CPUState *cpu);
 } ARMCPUClass;
 
 typedef struct ARMCPU ARMCPU;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 46c1d92080..d15b459399 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -526,7 +526,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
 
 bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
-    CPUClass *cc = CPU_GET_CLASS(cs);
+    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     CPUARMState *env = cs->env_ptr;
     uint32_t cur_el = arm_current_el(env);
     bool secure = arm_is_secure(env);
@@ -573,7 +573,7 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
  found:
     cs->exception_index = excp_idx;
     env->exception.target_el = target_el;
-    cc->do_interrupt(cs);
+    acc->do_interrupt_locked(cs);
     return true;
 }
 
@@ -2225,6 +2225,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_write_register = arm_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->do_interrupt = arm_cpu_do_interrupt_locked;
+    acc->do_interrupt_locked = arm_cpu_do_interrupt_locked;
     cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
     cc->asidx_from_attrs = arm_asidx_from_attrs;
     cc->vmsd = &vmstate_arm_cpu;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 2fc7a29340..caf0d54c2c 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -17,7 +17,7 @@
 
 static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
-    CPUClass *cc = CPU_GET_CLASS(cs);
+    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     bool ret = false;
@@ -33,7 +33,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if (interrupt_request & CPU_INTERRUPT_HARD
         && (armv7m_nvic_can_take_pending_exception(env->nvic))) {
         cs->exception_index = EXCP_IRQ;
-        cc->do_interrupt(cs);
+        acc->do_interrupt_locked(cs);
         ret = true;
     }
     return ret;
@@ -602,6 +602,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
     acc->info = data;
 #ifndef CONFIG_USER_ONLY
     cc->do_interrupt = arm_v7m_cpu_do_interrupt_locked;
+    acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
     cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 3/7] target/cris: add CRISCPUClass->do_interrupt_locked
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
  2020-08-19 18:28   ` Robert Foley
  2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
@ 2020-08-19 18:28 ` Robert Foley
  2020-08-31 21:19   ` Richard Henderson
  2020-08-19 18:28   ` Robert Foley
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Edgar E. Iglesias, pbonzini, alex.bennee, robert.foley, peter.puhov

Adding ->do_interrupt_locked to CRISCPUClass is preparation for
pushing the BQL down into the per-arch implementation of ->do_interrupt.

This is needed since Cris's *_cpu_exec_interrupt calls to *_do_interrupt.
With the push down of the BQL into *_cpu_exec_interrupt and
*_do_interrupt, *_cpu_exec_interrupt will call to ->do_interrupt
with lock held.  Since ->do_interrupt also has the lock, we need a way
to allow cpu_exec_interrupt to call do_interrupt with lock held.
This patch solves the issue of *_cpu_exec_interrupt needing
to call do_interrupt with lock held.

This patch is part of a series of transitions to move the
BQL down into the do_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

This approach was suggested by Paolo Bonzini.
For reference, here are two key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 target/cris/cpu-qom.h | 3 +++
 target/cris/cpu.c     | 6 ++++++
 target/cris/helper.c  | 6 +++---
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/target/cris/cpu-qom.h b/target/cris/cpu-qom.h
index f1de6041dc..dc94a17ffe 100644
--- a/target/cris/cpu-qom.h
+++ b/target/cris/cpu-qom.h
@@ -36,6 +36,7 @@
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
  * @vr: Version Register value.
+ * @do_interrupt_locked: Handler for interrupts (lock already held).
  *
  * A CRIS CPU model.
  */
@@ -48,6 +49,8 @@ typedef struct CRISCPUClass {
     DeviceReset parent_reset;
 
     uint32_t vr;
+
+    void (*do_interrupt_locked)(CPUState *cpu);
 } CRISCPUClass;
 
 typedef struct CRISCPU CRISCPU;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 40b110f161..948eeb6260 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -200,6 +200,7 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 8;
     cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
+    ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -211,6 +212,7 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 9;
     cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
+    ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -222,6 +224,7 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 10;
     cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
+    ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -233,6 +236,7 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 11;
     cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
+    ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -244,6 +248,7 @@ static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 17;
     cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
+    ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
 }
@@ -269,6 +274,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = cris_cpu_class_by_name;
     cc->has_work = cris_cpu_has_work;
     cc->do_interrupt = cris_cpu_do_interrupt_locked;
+    ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
diff --git a/target/cris/helper.c b/target/cris/helper.c
index e0ee6b4e05..3b7ee74813 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -290,7 +290,7 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
 bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
-    CPUClass *cc = CPU_GET_CLASS(cs);
+    CRISCPUClass *ccc = CRIS_CPU_CLASS(cs);
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
     bool ret = false;
@@ -299,7 +299,7 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         && (env->pregs[PR_CCS] & I_FLAG)
         && !env->locked_irq) {
         cs->exception_index = EXCP_IRQ;
-        cc->do_interrupt(cs);
+        ccc->do_interrupt_locked(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_NMI) {
@@ -311,7 +311,7 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         }
         if ((env->pregs[PR_CCS] & m_flag_archval)) {
             cs->exception_index = EXCP_NMI;
-            cc->do_interrupt(cs);
+            ccc->do_interrupt_locked(cs);
             ret = true;
         }
     }
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 4/7] target: Push BQL on ->do_interrupt down into per-arch implementation
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
@ 2020-08-19 18:28   ` Robert Foley
  2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Thomas Huth, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, open list:PowerPC TCG CPUs,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	robert.foley, open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, open list:RISC-V TCG CPUs,
	Bastian Koppelmann, Chris Wulff, Laurent Vivier, Michael Walle,
	Palmer Dabbelt, peter.puhov, Aurelien Jarno

As part of pushing the BQL down into the per-arch implementation,
the first change is to remove the holding of BQL from
cpu_handle_exception.  Next, we made changes per-arch to
re-add a new *_do_interrupt function, which gets the BQL and then
calls to *_do_interrupt_locked.  We also pointed the per-arch
->do_interrupt at the new *_do_interrupt.

This patch is part of a series of transitions to move the
BQL down into the do_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

It is worth mentioning that arm and cris are slightly different.
In a prior patch for these arches, we added a new CPUClass method
 ->do_interrupt_locked.  The only difference for arm and cris
is that their new *_do_interrupt functions will be able to
utilize this new ->do_interrupt_locked method.

avr is another exception.  avr, arm and cris all had a similar
case where their *_cpu_exec_interrupt was calling to
the CPUClass ->do_interrupt.  This causes an issue when we push
the lock down since ->do_interrupt will try to acquire the BQL, but
the calling context already has it.  To solve this for arm and
cris, we added a new CPUCLass method as explained above.  Moreover,
it was actually required for these arches since they have more than
one possible value of ->do_interrupt.  In the case of avr,
there is only one possible value of ->do_interrupt, so for that reason
we changed the avr_cpu_exec_interrupt to call directly to
avr_cpu_do_interrupt_locked rather than call cc->do_interrupt.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.

https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 accel/tcg/cpu-exec.c            |  2 --
 target/alpha/cpu.c              |  2 +-
 target/alpha/cpu.h              |  2 +-
 target/alpha/helper.c           |  9 ++++++++-
 target/arm/cpu.c                |  2 +-
 target/arm/cpu.h                |  2 ++
 target/arm/cpu_tcg.c            |  2 +-
 target/arm/helper.c             |  8 ++++++++
 target/avr/cpu.c                |  2 +-
 target/avr/cpu.h                |  2 +-
 target/avr/helper.c             | 16 ++++++++++++----
 target/cris/cpu.c               |  7 +------
 target/cris/cpu.h               |  1 +
 target/cris/helper.c            |  8 ++++++++
 target/hppa/cpu.c               |  2 +-
 target/hppa/cpu.h               |  2 +-
 target/hppa/int_helper.c        |  9 ++++++++-
 target/i386/cpu.c               |  2 +-
 target/i386/cpu.h               |  2 +-
 target/i386/seg_helper.c        |  9 ++++++++-
 target/lm32/cpu.c               |  2 +-
 target/lm32/cpu.h               |  2 +-
 target/lm32/helper.c            |  9 ++++++++-
 target/m68k/cpu.c               |  2 +-
 target/m68k/cpu.h               |  2 +-
 target/m68k/op_helper.c         | 11 +++++++++--
 target/microblaze/cpu.c         |  2 +-
 target/microblaze/cpu.h         |  2 +-
 target/microblaze/helper.c      | 11 +++++++++--
 target/mips/cpu.c               |  2 +-
 target/mips/helper.c            |  9 ++++++++-
 target/mips/internal.h          |  2 +-
 target/nios2/cpu.c              |  2 +-
 target/nios2/cpu.h              |  1 +
 target/nios2/helper.c           |  9 +++++++++
 target/openrisc/cpu.c           |  2 +-
 target/openrisc/cpu.h           |  2 +-
 target/openrisc/interrupt.c     |  9 ++++++++-
 target/ppc/cpu.h                |  1 +
 target/ppc/excp_helper.c        |  7 +++++++
 target/ppc/translate_init.inc.c |  2 +-
 target/riscv/cpu.c              |  2 +-
 target/riscv/cpu.h              |  2 +-
 target/riscv/cpu_helper.c       | 11 ++++++++++-
 target/rx/cpu.c                 |  2 +-
 target/rx/cpu.h                 |  1 +
 target/rx/helper.c              |  7 +++++++
 target/s390x/cpu.c              |  2 +-
 target/s390x/excp_helper.c      |  7 +++++++
 target/s390x/internal.h         |  1 +
 target/sh4/cpu.c                |  2 +-
 target/sh4/cpu.h                |  2 +-
 target/sh4/helper.c             | 11 +++++++++--
 target/sparc/cpu.c              |  2 +-
 target/sparc/cpu.h              |  1 +
 target/sparc/int32_helper.c     |  7 +++++++
 target/sparc/int64_helper.c     |  7 +++++++
 target/tilegx/cpu.c             |  9 ++++++++-
 target/unicore32/cpu.c          |  2 +-
 target/unicore32/cpu.h          |  1 +
 target/unicore32/softmmu.c      |  7 +++++++
 target/xtensa/cpu.c             |  2 +-
 target/xtensa/cpu.h             |  2 +-
 target/xtensa/exc_helper.c      | 11 +++++++++--
 64 files changed, 223 insertions(+), 60 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 80d0e649b2..e661635f06 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -517,9 +517,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
 #else
         if (replay_exception()) {
             CPUClass *cc = CPU_GET_CLASS(cpu);
-            qemu_mutex_lock_iothread();
             cc->do_interrupt(cpu);
-            qemu_mutex_unlock_iothread();
             cpu->exception_index = -1;
 
             if (unlikely(cpu->singlestep_enabled)) {
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index cb1074e0f9..09677c6c44 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -217,7 +217,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
-    cc->do_interrupt = alpha_cpu_do_interrupt_locked;
+    cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 4c6753df34..be29bdd530 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -276,7 +276,7 @@ struct AlphaCPU {
 extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
-void alpha_cpu_do_interrupt_locked(CPUState *cpu);
+void alpha_cpu_do_interrupt(CPUState *cpu);
 bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index ff9a2a7765..e497dd269e 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 }
 #endif /* USER_ONLY */
 
-void alpha_cpu_do_interrupt_locked(CPUState *cs)
+static void alpha_cpu_do_interrupt_locked(CPUState *cs)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -407,6 +407,13 @@ void alpha_cpu_do_interrupt_locked(CPUState *cs)
 #endif /* !USER_ONLY */
 }
 
+void alpha_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    alpha_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index d15b459399..12eda7611f 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2224,7 +2224,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_read_register = arm_cpu_gdb_read_register;
     cc->gdb_write_register = arm_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_cpu_do_interrupt_locked;
+    cc->do_interrupt = arm_cpu_do_interrupt;
     acc->do_interrupt_locked = arm_cpu_do_interrupt_locked;
     cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
     cc->asidx_from_attrs = arm_asidx_from_attrs;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 1f522964b5..57b8904dec 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -991,7 +991,9 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz);
 extern const VMStateDescription vmstate_arm_cpu;
 #endif
 
+void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_do_interrupt_locked(CPUState *cpu);
+void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
 bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index caf0d54c2c..df36cfda76 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -601,7 +601,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
 
     acc->info = data;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_v7m_cpu_do_interrupt_locked;
+    cc->do_interrupt = arm_cpu_do_interrupt;
     acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e07924daf5..f0ab750088 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9840,6 +9840,14 @@ static void handle_semihosting(CPUState *cs)
 }
 #endif
 
+void arm_cpu_do_interrupt(CPUState *cs)
+{
+    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
+    qemu_mutex_lock_iothread();
+    acc->do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 /* Handle a CPU exception for A and R profile CPUs.
  * Do any appropriate logging, handle PSCI calls, and then hand off
  * to the AArch64-entry or AArch32-entry function depending on the
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index d856069230..5d9c4ad5bf 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -197,7 +197,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = avr_cpu_class_by_name;
 
     cc->has_work = avr_cpu_has_work;
-    cc->do_interrupt = avr_cpu_do_interrupt_locked;
+    cc->do_interrupt = avr_cpu_do_interrupt;
     cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 66a26f08ef..d148e8c75a 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -156,7 +156,7 @@ typedef struct AVRCPU {
 
 extern const struct VMStateDescription vms_avr_cpu;
 
-void avr_cpu_do_interrupt_locked(CPUState *cpu);
+void avr_cpu_do_interrupt(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 096bc35945..2c8c3af580 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -24,17 +24,18 @@
 #include "exec/address-spaces.h"
 #include "exec/helper-proto.h"
 
+static void avr_cpu_do_interrupt_locked(CPUState *cs);
+
 bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     bool ret = false;
-    CPUClass *cc = CPU_GET_CLASS(cs);
     AVRCPU *cpu = AVR_CPU(cs);
     CPUAVRState *env = &cpu->env;
 
     if (interrupt_request & CPU_INTERRUPT_RESET) {
         if (cpu_interrupts_enabled(env)) {
             cs->exception_index = EXCP_RESET;
-            cc->do_interrupt(cs);
+            avr_cpu_do_interrupt_locked(cs);
 
             cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
 
@@ -45,7 +46,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
             int index = ctz32(env->intsrc);
             cs->exception_index = EXCP_INT(index);
-            cc->do_interrupt(cs);
+            avr_cpu_do_interrupt_locked(cs);
 
             env->intsrc &= env->intsrc - 1; /* clear the interrupt */
             cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
@@ -56,7 +57,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     return ret;
 }
 
-void avr_cpu_do_interrupt_locked(CPUState *cs)
+static void avr_cpu_do_interrupt_locked(CPUState *cs)
 {
     AVRCPU *cpu = AVR_CPU(cs);
     CPUAVRState *env = &cpu->env;
@@ -89,6 +90,13 @@ void avr_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void avr_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    avr_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf,
                             int len, bool is_write)
 {
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 948eeb6260..c3d77c31e8 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -199,7 +199,6 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 8;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -211,7 +210,6 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 9;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -223,7 +221,6 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 10;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -235,7 +232,6 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 11;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -247,7 +243,6 @@ static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 17;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -273,7 +268,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = cris_cpu_class_by_name;
     cc->has_work = cris_cpu_has_work;
-    cc->do_interrupt = cris_cpu_do_interrupt_locked;
+    cc->do_interrupt = cris_cpu_do_interrupt;
     ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 597ccd6451..d8ee6b9400 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -187,6 +187,7 @@ struct CRISCPU {
 extern const VMStateDescription vmstate_cris_cpu;
 #endif
 
+void cris_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_do_interrupt_locked(CPUState *cpu);
 void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 3b7ee74813..0e053782ab 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -38,6 +38,14 @@
 #define D_LOG(...) do { } while (0)
 #endif
 
+void cris_cpu_do_interrupt(CPUState *cs)
+{
+    CRISCPUClass *acc = CRIS_CPU_GET_CLASS(cs);
+    qemu_mutex_lock_iothread();
+    acc->do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 #if defined(CONFIG_USER_ONLY)
 
 void cris_cpu_do_interrupt_locked(CPUState *cs)
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 7241ffbd7f..287055f96e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -139,7 +139,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
-    cc->do_interrupt = hppa_cpu_do_interrupt_locked;
+    cc->do_interrupt = hppa_cpu_do_interrupt;
     cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 7fc7682ca8..801a4fb1ba 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,7 +323,7 @@ int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc);
 hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void hppa_cpu_do_interrupt_locked(CPUState *cpu);
+void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 31fce959d6..03cb521a96 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -90,7 +90,7 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg val)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-void hppa_cpu_do_interrupt_locked(CPUState *cs)
+static void hppa_cpu_do_interrupt_locked(CPUState *cs)
 {
     HPPACPU *cpu = HPPA_CPU(cs);
     CPUHPPAState *env = &cpu->env;
@@ -246,6 +246,13 @@ void hppa_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void hppa_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    hppa_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fdb8ae11b6..592aa0baf7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7297,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->parse_features = x86_cpu_parse_featurestr;
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = x86_cpu_do_interrupt_locked;
+    cc->do_interrupt = x86_cpu_do_interrupt;
     cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
 #endif
     cc->dump_state = x86_cpu_dump_state;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 8d4dac129b..d784eeaf29 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1770,7 +1770,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * x86_cpu_do_interrupt:
  * @cpu: vCPU the interrupt is to be handled by.
  */
-void x86_cpu_do_interrupt_locked(CPUState *cpu);
+void x86_cpu_do_interrupt(CPUState *cpu);
 bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 0d8464abec..74484eb175 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1280,7 +1280,7 @@ static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
 #endif
 }
 
-void x86_cpu_do_interrupt_locked(CPUState *cs)
+static void x86_cpu_do_interrupt_locked(CPUState *cs)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
@@ -1310,6 +1310,13 @@ void x86_cpu_do_interrupt_locked(CPUState *cs)
 #endif
 }
 
+void x86_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    x86_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
 {
     do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 93da742520..9e7d8ca929 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -222,7 +222,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
-    cc->do_interrupt = lm32_cpu_do_interrupt_locked;
+    cc->do_interrupt = lm32_cpu_do_interrupt;
     cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index cd96a2905e..01d408eb55 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -198,7 +198,7 @@ struct LM32CPU {
 extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
-void lm32_cpu_do_interrupt_locked(CPUState *cpu);
+void lm32_cpu_do_interrupt(CPUState *cpu);
 bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 8599a59df2..6184e212cf 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -148,7 +148,7 @@ void lm32_debug_excp_handler(CPUState *cs)
     }
 }
 
-void lm32_cpu_do_interrupt_locked(CPUState *cs)
+static void lm32_cpu_do_interrupt_locked(CPUState *cs)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
@@ -198,6 +198,13 @@ void lm32_cpu_do_interrupt_locked(CPUState *cs)
     }
 }
 
+void lm32_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    lm32_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     LM32CPU *cpu = LM32_CPU(cs);
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 6ac0dd87a6..f2585154f5 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -277,7 +277,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
-    cc->do_interrupt = m68k_cpu_do_interrupt_locked;
+    cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 1afbe94570..521ac67cdd 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -164,7 +164,7 @@ struct M68kCPU {
 };
 
 
-void m68k_cpu_do_interrupt_locked(CPUState *cpu);
+void m68k_cpu_do_interrupt(CPUState *cpu);
 bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 8fd6481883..3f0c99124a 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -25,7 +25,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void m68k_cpu_do_interrupt_locked(CPUState *cs)
+static void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -443,7 +443,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
     cf_interrupt_all(env, is_hw);
 }
 
-void m68k_cpu_do_interrupt_locked(CPUState *cs)
+static void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
@@ -504,6 +504,13 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
 }
 #endif
 
+void m68k_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    m68k_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index b19e386bcf..ce70f7d281 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -316,7 +316,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
-    cc->do_interrupt = mb_cpu_do_interrupt_locked;
+    cc->do_interrupt = mb_cpu_do_interrupt;
     cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 7617565a0c..a31134b65c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -315,7 +315,7 @@ struct MicroBlazeCPU {
 };
 
 
-void mb_cpu_do_interrupt_locked(CPUState *cs);
+void mb_cpu_do_interrupt(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 263cdf59be..f241587b40 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -28,7 +28,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void mb_cpu_do_interrupt_locked(CPUState *cs)
+static void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -108,7 +108,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-void mb_cpu_do_interrupt_locked(CPUState *cs)
+static void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -287,6 +287,13 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
+void mb_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    mb_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index c616a0ef5a..ec9dde5100 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -196,7 +196,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
-    cc->do_interrupt = mips_cpu_do_interrupt_locked;
+    cc->do_interrupt = mips_cpu_do_interrupt;
     cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index a85c4057d0..3941392b95 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1083,7 +1083,7 @@ static inline void set_badinstr_registers(CPUMIPSState *env)
 }
 #endif
 
-void mips_cpu_do_interrupt_locked(CPUState *cs)
+static void mips_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
     MIPSCPU *cpu = MIPS_CPU(cs);
@@ -1398,6 +1398,13 @@ void mips_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = EXCP_NONE;
 }
 
+void mips_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    mips_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/mips/internal.h b/target/mips/internal.h
index fb0181c095..7f159a9230 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -80,7 +80,7 @@ enum CPUMIPSMSADataFormat {
     DF_DOUBLE
 };
 
-void mips_cpu_do_interrupt_locked(CPUState *cpu);
+void mips_cpu_do_interrupt(CPUState *cpu);
 bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index cc813181a4..7116b3f230 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -192,7 +192,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
-    cc->do_interrupt = nios2_cpu_do_interrupt_locked;
+    cc->do_interrupt = nios2_cpu_do_interrupt;
     cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index dcf1715092..6fa60b1399 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -195,6 +195,7 @@ typedef struct Nios2CPU {
 
 
 void nios2_tcg_init(void);
+void nios2_cpu_do_interrupt(CPUState *cs);
 void nios2_cpu_do_interrupt_locked(CPUState *cs);
 int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc);
 void dump_mmu(CPUNios2State *env);
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 25c6c6d4d8..c81aa073f4 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -312,3 +312,12 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 #endif /* !CONFIG_USER_ONLY */
+
+void nios2_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    nios2_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
+
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index e428946dc2..fd2da39124 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -154,7 +154,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
-    cc->do_interrupt = openrisc_cpu_do_interrupt_locked;
+    cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index e77f075cd9..f37a52e153 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -316,7 +316,7 @@ typedef struct OpenRISCCPU {
 
 
 void cpu_openrisc_list(void);
-void openrisc_cpu_do_interrupt_locked(CPUState *cpu);
+void openrisc_cpu_do_interrupt(CPUState *cpu);
 bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index f95289444f..a5ca3ece78 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -26,7 +26,7 @@
 #include "hw/loader.h"
 #endif
 
-void openrisc_cpu_do_interrupt_locked(CPUState *cs)
+static void openrisc_cpu_do_interrupt_locked(CPUState *cs)
 {
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -101,6 +101,13 @@ void openrisc_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void openrisc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    openrisc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index ed297acdb4..2569d43e59 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1231,6 +1231,7 @@ struct PPCVirtualHypervisorClass {
                      TYPE_PPC_VIRTUAL_HYPERVISOR)
 #endif /* CONFIG_USER_ONLY */
 
+void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_do_interrupt_locked(CPUState *cpu);
 bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index fe9b122fd0..2cb1aaa296 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1428,3 +1428,10 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
     env->error_code = insn & 0x03FF0000;
     cpu_loop_exit(cs);
 }
+
+void ppc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    ppc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 653b04aef6..27ae7fa195 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10885,7 +10885,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     pcc->parent_parse_features = cc->parse_features;
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
-    cc->do_interrupt = ppc_cpu_do_interrupt_locked;
+    cc->do_interrupt = ppc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 833e6d4f1e..832171c360 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -537,7 +537,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
-    cc->do_interrupt = riscv_cpu_do_interrupt_locked;
+    cc->do_interrupt = riscv_cpu_do_interrupt;
     cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 372005b79c..a804a5d0ba 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -312,7 +312,7 @@ extern const char * const riscv_fpr_regnames[];
 extern const char * const riscv_excp_names[];
 extern const char * const riscv_intr_names[];
 
-void riscv_cpu_do_interrupt_locked(CPUState *cpu);
+void riscv_cpu_do_interrupt(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 477cf66b66..2c8ee8ca2b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -25,6 +25,8 @@
 #include "tcg/tcg-op.h"
 #include "trace.h"
 
+static void riscv_cpu_do_interrupt_locked(CPUState *cs);
+
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
@@ -814,13 +816,20 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 #endif
 }
 
+void riscv_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    riscv_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 /*
  * Handle Traps
  *
  * Adapted from Spike's processor_t::take_trap.
  *
  */
-void riscv_cpu_do_interrupt_locked(CPUState *cs)
+static void riscv_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
 
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 51e10da7cc..219e05397b 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -185,7 +185,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
 
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
-    cc->do_interrupt = rx_cpu_do_interrupt_locked;
+    cc->do_interrupt = rx_cpu_do_interrupt;
     cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index d188e7d43f..ec085d0386 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -125,6 +125,7 @@ typedef RXCPU ArchCPU;
 #define CPU_RESOLVING_TYPE TYPE_RX_CPU
 
 const char *rx_crname(uint8_t cr);
+void rx_cpu_do_interrupt(CPUState *cpu);
 void rx_cpu_do_interrupt_locked(CPUState *cpu);
 bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 332f89435a..8c0512b62a 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -119,6 +119,13 @@ void rx_cpu_do_interrupt_locked(CPUState *cs)
     env->regs[0] = env->isp;
 }
 
+void rx_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    rx_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     RXCPU *cpu = RXCPU(cs);
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index eb23d64f36..4d0d323cf9 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -493,7 +493,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = s390_cpu_class_by_name,
     cc->has_work_with_iothread_lock = s390_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = s390_cpu_do_interrupt_locked;
+    cc->do_interrupt = s390_cpu_do_interrupt;
 #endif
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index a663127f17..a020db1725 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -611,3 +611,10 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 }
 
 #endif /* CONFIG_USER_ONLY */
+
+void s390_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    s390_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 6ab0fb481a..b4660ad255 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -268,6 +268,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 
 /* excp_helper.c */
 void s390x_cpu_debug_excp_handler(CPUState *cs);
+void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_do_interrupt_locked(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 5e5921a220..18f3448183 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -218,7 +218,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
-    cc->do_interrupt = superh_cpu_do_interrupt_locked;
+    cc->do_interrupt = superh_cpu_do_interrupt;
     cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 2ae3dd132b..dbe58c7888 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -204,7 +204,7 @@ struct SuperHCPU {
 };
 
 
-void superh_cpu_do_interrupt_locked(CPUState *cpu);
+void superh_cpu_do_interrupt(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 2d61f65d50..471650b622 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -45,7 +45,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void superh_cpu_do_interrupt_locked(CPUState *cs)
+static void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -58,7 +58,7 @@ int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
 
 #else /* !CONFIG_USER_ONLY */
 
-void superh_cpu_do_interrupt_locked(CPUState *cs)
+static void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     SuperHCPU *cpu = SUPERH_CPU(cs);
     CPUSH4State *env = &cpu->env;
@@ -782,6 +782,13 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
 
 #endif
 
+void superh_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    superh_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 4c8842adcf..1c26bbd59b 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -863,7 +863,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = sparc_cpu_class_by_name;
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
-    cc->do_interrupt = sparc_cpu_do_interrupt_locked;
+    cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 3563e65d73..ec8684ec93 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -568,6 +568,7 @@ struct SPARCCPU {
 extern const VMStateDescription vmstate_sparc_cpu;
 #endif
 
+void sparc_cpu_do_interrupt(CPUState *cpu);
 void sparc_cpu_do_interrupt_locked(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
index 90f4aa4a78..7a1f15b06c 100644
--- a/target/sparc/int32_helper.c
+++ b/target/sparc/int32_helper.c
@@ -138,6 +138,13 @@ void sparc_cpu_do_interrupt_locked(CPUState *cs)
 #endif
 }
 
+void sparc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    sparc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static void leon3_cache_control_int(CPUSPARCState *env)
 {
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index b81b4abaa8..aa3d9aa585 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -198,6 +198,13 @@ void sparc_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void sparc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    sparc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 trap_state *cpu_tsptr(CPUSPARCState* env)
 {
     return &env->ts[env->tl & MAXTL_MASK];
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index a2ff335977..a450dc63a3 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -125,6 +125,13 @@ static bool tilegx_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
+static void tilegx_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    tilegx_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
@@ -147,7 +154,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
-    cc->do_interrupt = tilegx_cpu_do_interrupt_locked;
+    cc->do_interrupt = tilegx_cpu_do_interrupt;
     cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index a96077d666..06bf4b4b63 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -131,7 +131,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
-    cc->do_interrupt = uc32_cpu_do_interrupt_locked;
+    cc->do_interrupt = uc32_cpu_do_interrupt;
     cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index d948392ff3..9453b5d7b3 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -75,6 +75,7 @@ struct UniCore32CPU {
 };
 
 
+void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_do_interrupt_locked(CPUState *cpu);
 bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
index a12526a8ca..7fb28f3c12 100644
--- a/target/unicore32/softmmu.c
+++ b/target/unicore32/softmmu.c
@@ -120,6 +120,13 @@ void uc32_cpu_do_interrupt_locked(CPUState *cs)
     cpu_interrupt_request_or(cs, CPU_INTERRUPT_EXITTB);
 }
 
+void uc32_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    uc32_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address,
         int access_type, int is_user, uint32_t *phys_ptr, int *prot,
         target_ulong *page_size)
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 7962bc66a8..0f96483563 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -190,7 +190,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
-    cc->do_interrupt = xtensa_cpu_do_interrupt_locked;
+    cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index c02f531b64..32749378bf 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,7 +563,7 @@ struct XtensaCPU {
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
-void xtensa_cpu_do_interrupt_locked(CPUState *cpu);
+void xtensa_cpu_do_interrupt(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 10d4762f36..822ed7aad8 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -195,7 +195,7 @@ static void handle_interrupt(CPUXtensaState *env)
 }
 
 /* Called from cpu_handle_interrupt with BQL held */
-void xtensa_cpu_do_interrupt_locked(CPUState *cs)
+static void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
@@ -254,11 +254,18 @@ void xtensa_cpu_do_interrupt_locked(CPUState *cs)
     check_interrupts(env);
 }
 #else
-void xtensa_cpu_do_interrupt_locked(CPUState *cs)
+static void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
 }
 #endif
 
+void xtensa_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    xtensa_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 4/7] target: Push BQL on ->do_interrupt down into per-arch implementation
@ 2020-08-19 18:28   ` Robert Foley
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, pbonzini, peter.puhov, robert.foley,
	Richard Henderson, Peter Maydell, Michael Rolnik, Sarah Harris,
	Edgar E. Iglesias, Eduardo Habkost, Michael Walle,
	Laurent Vivier, Aleksandar Markovic, Aurelien Jarno, Jiaxun Yang,
	Aleksandar Rikalo, Chris Wulff, Marek Vasut, Stafford Horne,
	David Gibson, Palmer Dabbelt, Alistair Francis, Sagar Karandikar,
	Bastian Koppelmann, Yoshinori Sato, Cornelia Huck, Thomas Huth,
	David Hildenbrand, Mark Cave-Ayland, Artyom Tarasenko,
	Guan Xuetao, Max Filippov, open list:ARM TCG CPUs,
	open list:PowerPC TCG CPUs, open list:RISC-V TCG CPUs,
	open list:S390 general arch...

As part of pushing the BQL down into the per-arch implementation,
the first change is to remove the holding of BQL from
cpu_handle_exception.  Next, we made changes per-arch to
re-add a new *_do_interrupt function, which gets the BQL and then
calls to *_do_interrupt_locked.  We also pointed the per-arch
->do_interrupt at the new *_do_interrupt.

This patch is part of a series of transitions to move the
BQL down into the do_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

It is worth mentioning that arm and cris are slightly different.
In a prior patch for these arches, we added a new CPUClass method
 ->do_interrupt_locked.  The only difference for arm and cris
is that their new *_do_interrupt functions will be able to
utilize this new ->do_interrupt_locked method.

avr is another exception.  avr, arm and cris all had a similar
case where their *_cpu_exec_interrupt was calling to
the CPUClass ->do_interrupt.  This causes an issue when we push
the lock down since ->do_interrupt will try to acquire the BQL, but
the calling context already has it.  To solve this for arm and
cris, we added a new CPUCLass method as explained above.  Moreover,
it was actually required for these arches since they have more than
one possible value of ->do_interrupt.  In the case of avr,
there is only one possible value of ->do_interrupt, so for that reason
we changed the avr_cpu_exec_interrupt to call directly to
avr_cpu_do_interrupt_locked rather than call cc->do_interrupt.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.

https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 accel/tcg/cpu-exec.c            |  2 --
 target/alpha/cpu.c              |  2 +-
 target/alpha/cpu.h              |  2 +-
 target/alpha/helper.c           |  9 ++++++++-
 target/arm/cpu.c                |  2 +-
 target/arm/cpu.h                |  2 ++
 target/arm/cpu_tcg.c            |  2 +-
 target/arm/helper.c             |  8 ++++++++
 target/avr/cpu.c                |  2 +-
 target/avr/cpu.h                |  2 +-
 target/avr/helper.c             | 16 ++++++++++++----
 target/cris/cpu.c               |  7 +------
 target/cris/cpu.h               |  1 +
 target/cris/helper.c            |  8 ++++++++
 target/hppa/cpu.c               |  2 +-
 target/hppa/cpu.h               |  2 +-
 target/hppa/int_helper.c        |  9 ++++++++-
 target/i386/cpu.c               |  2 +-
 target/i386/cpu.h               |  2 +-
 target/i386/seg_helper.c        |  9 ++++++++-
 target/lm32/cpu.c               |  2 +-
 target/lm32/cpu.h               |  2 +-
 target/lm32/helper.c            |  9 ++++++++-
 target/m68k/cpu.c               |  2 +-
 target/m68k/cpu.h               |  2 +-
 target/m68k/op_helper.c         | 11 +++++++++--
 target/microblaze/cpu.c         |  2 +-
 target/microblaze/cpu.h         |  2 +-
 target/microblaze/helper.c      | 11 +++++++++--
 target/mips/cpu.c               |  2 +-
 target/mips/helper.c            |  9 ++++++++-
 target/mips/internal.h          |  2 +-
 target/nios2/cpu.c              |  2 +-
 target/nios2/cpu.h              |  1 +
 target/nios2/helper.c           |  9 +++++++++
 target/openrisc/cpu.c           |  2 +-
 target/openrisc/cpu.h           |  2 +-
 target/openrisc/interrupt.c     |  9 ++++++++-
 target/ppc/cpu.h                |  1 +
 target/ppc/excp_helper.c        |  7 +++++++
 target/ppc/translate_init.inc.c |  2 +-
 target/riscv/cpu.c              |  2 +-
 target/riscv/cpu.h              |  2 +-
 target/riscv/cpu_helper.c       | 11 ++++++++++-
 target/rx/cpu.c                 |  2 +-
 target/rx/cpu.h                 |  1 +
 target/rx/helper.c              |  7 +++++++
 target/s390x/cpu.c              |  2 +-
 target/s390x/excp_helper.c      |  7 +++++++
 target/s390x/internal.h         |  1 +
 target/sh4/cpu.c                |  2 +-
 target/sh4/cpu.h                |  2 +-
 target/sh4/helper.c             | 11 +++++++++--
 target/sparc/cpu.c              |  2 +-
 target/sparc/cpu.h              |  1 +
 target/sparc/int32_helper.c     |  7 +++++++
 target/sparc/int64_helper.c     |  7 +++++++
 target/tilegx/cpu.c             |  9 ++++++++-
 target/unicore32/cpu.c          |  2 +-
 target/unicore32/cpu.h          |  1 +
 target/unicore32/softmmu.c      |  7 +++++++
 target/xtensa/cpu.c             |  2 +-
 target/xtensa/cpu.h             |  2 +-
 target/xtensa/exc_helper.c      | 11 +++++++++--
 64 files changed, 223 insertions(+), 60 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 80d0e649b2..e661635f06 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -517,9 +517,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
 #else
         if (replay_exception()) {
             CPUClass *cc = CPU_GET_CLASS(cpu);
-            qemu_mutex_lock_iothread();
             cc->do_interrupt(cpu);
-            qemu_mutex_unlock_iothread();
             cpu->exception_index = -1;
 
             if (unlikely(cpu->singlestep_enabled)) {
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index cb1074e0f9..09677c6c44 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -217,7 +217,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
-    cc->do_interrupt = alpha_cpu_do_interrupt_locked;
+    cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 4c6753df34..be29bdd530 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -276,7 +276,7 @@ struct AlphaCPU {
 extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
-void alpha_cpu_do_interrupt_locked(CPUState *cpu);
+void alpha_cpu_do_interrupt(CPUState *cpu);
 bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index ff9a2a7765..e497dd269e 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 }
 #endif /* USER_ONLY */
 
-void alpha_cpu_do_interrupt_locked(CPUState *cs)
+static void alpha_cpu_do_interrupt_locked(CPUState *cs)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -407,6 +407,13 @@ void alpha_cpu_do_interrupt_locked(CPUState *cs)
 #endif /* !USER_ONLY */
 }
 
+void alpha_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    alpha_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index d15b459399..12eda7611f 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2224,7 +2224,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_read_register = arm_cpu_gdb_read_register;
     cc->gdb_write_register = arm_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_cpu_do_interrupt_locked;
+    cc->do_interrupt = arm_cpu_do_interrupt;
     acc->do_interrupt_locked = arm_cpu_do_interrupt_locked;
     cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
     cc->asidx_from_attrs = arm_asidx_from_attrs;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 1f522964b5..57b8904dec 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -991,7 +991,9 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz);
 extern const VMStateDescription vmstate_arm_cpu;
 #endif
 
+void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_do_interrupt_locked(CPUState *cpu);
+void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
 bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index caf0d54c2c..df36cfda76 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -601,7 +601,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
 
     acc->info = data;
 #ifndef CONFIG_USER_ONLY
-    cc->do_interrupt = arm_v7m_cpu_do_interrupt_locked;
+    cc->do_interrupt = arm_cpu_do_interrupt;
     acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e07924daf5..f0ab750088 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9840,6 +9840,14 @@ static void handle_semihosting(CPUState *cs)
 }
 #endif
 
+void arm_cpu_do_interrupt(CPUState *cs)
+{
+    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
+    qemu_mutex_lock_iothread();
+    acc->do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 /* Handle a CPU exception for A and R profile CPUs.
  * Do any appropriate logging, handle PSCI calls, and then hand off
  * to the AArch64-entry or AArch32-entry function depending on the
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index d856069230..5d9c4ad5bf 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -197,7 +197,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = avr_cpu_class_by_name;
 
     cc->has_work = avr_cpu_has_work;
-    cc->do_interrupt = avr_cpu_do_interrupt_locked;
+    cc->do_interrupt = avr_cpu_do_interrupt;
     cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 66a26f08ef..d148e8c75a 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -156,7 +156,7 @@ typedef struct AVRCPU {
 
 extern const struct VMStateDescription vms_avr_cpu;
 
-void avr_cpu_do_interrupt_locked(CPUState *cpu);
+void avr_cpu_do_interrupt(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 096bc35945..2c8c3af580 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -24,17 +24,18 @@
 #include "exec/address-spaces.h"
 #include "exec/helper-proto.h"
 
+static void avr_cpu_do_interrupt_locked(CPUState *cs);
+
 bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     bool ret = false;
-    CPUClass *cc = CPU_GET_CLASS(cs);
     AVRCPU *cpu = AVR_CPU(cs);
     CPUAVRState *env = &cpu->env;
 
     if (interrupt_request & CPU_INTERRUPT_RESET) {
         if (cpu_interrupts_enabled(env)) {
             cs->exception_index = EXCP_RESET;
-            cc->do_interrupt(cs);
+            avr_cpu_do_interrupt_locked(cs);
 
             cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
 
@@ -45,7 +46,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
             int index = ctz32(env->intsrc);
             cs->exception_index = EXCP_INT(index);
-            cc->do_interrupt(cs);
+            avr_cpu_do_interrupt_locked(cs);
 
             env->intsrc &= env->intsrc - 1; /* clear the interrupt */
             cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
@@ -56,7 +57,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     return ret;
 }
 
-void avr_cpu_do_interrupt_locked(CPUState *cs)
+static void avr_cpu_do_interrupt_locked(CPUState *cs)
 {
     AVRCPU *cpu = AVR_CPU(cs);
     CPUAVRState *env = &cpu->env;
@@ -89,6 +90,13 @@ void avr_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void avr_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    avr_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf,
                             int len, bool is_write)
 {
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 948eeb6260..c3d77c31e8 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -199,7 +199,6 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 8;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -211,7 +210,6 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 9;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -223,7 +221,6 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 10;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -235,7 +232,6 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 11;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -247,7 +243,6 @@ static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
     CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
 
     ccc->vr = 17;
-    cc->do_interrupt = crisv10_cpu_do_interrupt_locked;
     ccc->do_interrupt_locked = crisv10_cpu_do_interrupt_locked;
     cc->gdb_read_register = crisv10_cpu_gdb_read_register;
     cc->tcg_initialize = cris_initialize_crisv10_tcg;
@@ -273,7 +268,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = cris_cpu_class_by_name;
     cc->has_work = cris_cpu_has_work;
-    cc->do_interrupt = cris_cpu_do_interrupt_locked;
+    cc->do_interrupt = cris_cpu_do_interrupt;
     ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
     cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 597ccd6451..d8ee6b9400 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -187,6 +187,7 @@ struct CRISCPU {
 extern const VMStateDescription vmstate_cris_cpu;
 #endif
 
+void cris_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_do_interrupt_locked(CPUState *cpu);
 void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 3b7ee74813..0e053782ab 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -38,6 +38,14 @@
 #define D_LOG(...) do { } while (0)
 #endif
 
+void cris_cpu_do_interrupt(CPUState *cs)
+{
+    CRISCPUClass *acc = CRIS_CPU_GET_CLASS(cs);
+    qemu_mutex_lock_iothread();
+    acc->do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 #if defined(CONFIG_USER_ONLY)
 
 void cris_cpu_do_interrupt_locked(CPUState *cs)
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 7241ffbd7f..287055f96e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -139,7 +139,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
-    cc->do_interrupt = hppa_cpu_do_interrupt_locked;
+    cc->do_interrupt = hppa_cpu_do_interrupt;
     cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 7fc7682ca8..801a4fb1ba 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,7 +323,7 @@ int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc);
 hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void hppa_cpu_do_interrupt_locked(CPUState *cpu);
+void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 31fce959d6..03cb521a96 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -90,7 +90,7 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg val)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-void hppa_cpu_do_interrupt_locked(CPUState *cs)
+static void hppa_cpu_do_interrupt_locked(CPUState *cs)
 {
     HPPACPU *cpu = HPPA_CPU(cs);
     CPUHPPAState *env = &cpu->env;
@@ -246,6 +246,13 @@ void hppa_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void hppa_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    hppa_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fdb8ae11b6..592aa0baf7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7297,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->parse_features = x86_cpu_parse_featurestr;
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = x86_cpu_do_interrupt_locked;
+    cc->do_interrupt = x86_cpu_do_interrupt;
     cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
 #endif
     cc->dump_state = x86_cpu_dump_state;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 8d4dac129b..d784eeaf29 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1770,7 +1770,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * x86_cpu_do_interrupt:
  * @cpu: vCPU the interrupt is to be handled by.
  */
-void x86_cpu_do_interrupt_locked(CPUState *cpu);
+void x86_cpu_do_interrupt(CPUState *cpu);
 bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 0d8464abec..74484eb175 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1280,7 +1280,7 @@ static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
 #endif
 }
 
-void x86_cpu_do_interrupt_locked(CPUState *cs)
+static void x86_cpu_do_interrupt_locked(CPUState *cs)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
@@ -1310,6 +1310,13 @@ void x86_cpu_do_interrupt_locked(CPUState *cs)
 #endif
 }
 
+void x86_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    x86_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
 {
     do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 93da742520..9e7d8ca929 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -222,7 +222,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
-    cc->do_interrupt = lm32_cpu_do_interrupt_locked;
+    cc->do_interrupt = lm32_cpu_do_interrupt;
     cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index cd96a2905e..01d408eb55 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -198,7 +198,7 @@ struct LM32CPU {
 extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
-void lm32_cpu_do_interrupt_locked(CPUState *cpu);
+void lm32_cpu_do_interrupt(CPUState *cpu);
 bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 8599a59df2..6184e212cf 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -148,7 +148,7 @@ void lm32_debug_excp_handler(CPUState *cs)
     }
 }
 
-void lm32_cpu_do_interrupt_locked(CPUState *cs)
+static void lm32_cpu_do_interrupt_locked(CPUState *cs)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
@@ -198,6 +198,13 @@ void lm32_cpu_do_interrupt_locked(CPUState *cs)
     }
 }
 
+void lm32_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    lm32_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     LM32CPU *cpu = LM32_CPU(cs);
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 6ac0dd87a6..f2585154f5 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -277,7 +277,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
-    cc->do_interrupt = m68k_cpu_do_interrupt_locked;
+    cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 1afbe94570..521ac67cdd 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -164,7 +164,7 @@ struct M68kCPU {
 };
 
 
-void m68k_cpu_do_interrupt_locked(CPUState *cpu);
+void m68k_cpu_do_interrupt(CPUState *cpu);
 bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 8fd6481883..3f0c99124a 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -25,7 +25,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void m68k_cpu_do_interrupt_locked(CPUState *cs)
+static void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -443,7 +443,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
     cf_interrupt_all(env, is_hw);
 }
 
-void m68k_cpu_do_interrupt_locked(CPUState *cs)
+static void m68k_cpu_do_interrupt_locked(CPUState *cs)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
@@ -504,6 +504,13 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
 }
 #endif
 
+void m68k_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    m68k_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index b19e386bcf..ce70f7d281 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -316,7 +316,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
-    cc->do_interrupt = mb_cpu_do_interrupt_locked;
+    cc->do_interrupt = mb_cpu_do_interrupt;
     cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 7617565a0c..a31134b65c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -315,7 +315,7 @@ struct MicroBlazeCPU {
 };
 
 
-void mb_cpu_do_interrupt_locked(CPUState *cs);
+void mb_cpu_do_interrupt(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 263cdf59be..f241587b40 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -28,7 +28,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void mb_cpu_do_interrupt_locked(CPUState *cs)
+static void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -108,7 +108,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-void mb_cpu_do_interrupt_locked(CPUState *cs)
+static void mb_cpu_do_interrupt_locked(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -287,6 +287,13 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
+void mb_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    mb_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index c616a0ef5a..ec9dde5100 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -196,7 +196,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
-    cc->do_interrupt = mips_cpu_do_interrupt_locked;
+    cc->do_interrupt = mips_cpu_do_interrupt;
     cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index a85c4057d0..3941392b95 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1083,7 +1083,7 @@ static inline void set_badinstr_registers(CPUMIPSState *env)
 }
 #endif
 
-void mips_cpu_do_interrupt_locked(CPUState *cs)
+static void mips_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
     MIPSCPU *cpu = MIPS_CPU(cs);
@@ -1398,6 +1398,13 @@ void mips_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = EXCP_NONE;
 }
 
+void mips_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    mips_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/mips/internal.h b/target/mips/internal.h
index fb0181c095..7f159a9230 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -80,7 +80,7 @@ enum CPUMIPSMSADataFormat {
     DF_DOUBLE
 };
 
-void mips_cpu_do_interrupt_locked(CPUState *cpu);
+void mips_cpu_do_interrupt(CPUState *cpu);
 bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index cc813181a4..7116b3f230 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -192,7 +192,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
-    cc->do_interrupt = nios2_cpu_do_interrupt_locked;
+    cc->do_interrupt = nios2_cpu_do_interrupt;
     cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index dcf1715092..6fa60b1399 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -195,6 +195,7 @@ typedef struct Nios2CPU {
 
 
 void nios2_tcg_init(void);
+void nios2_cpu_do_interrupt(CPUState *cs);
 void nios2_cpu_do_interrupt_locked(CPUState *cs);
 int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc);
 void dump_mmu(CPUNios2State *env);
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 25c6c6d4d8..c81aa073f4 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -312,3 +312,12 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 #endif /* !CONFIG_USER_ONLY */
+
+void nios2_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    nios2_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
+
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index e428946dc2..fd2da39124 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -154,7 +154,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
-    cc->do_interrupt = openrisc_cpu_do_interrupt_locked;
+    cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index e77f075cd9..f37a52e153 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -316,7 +316,7 @@ typedef struct OpenRISCCPU {
 
 
 void cpu_openrisc_list(void);
-void openrisc_cpu_do_interrupt_locked(CPUState *cpu);
+void openrisc_cpu_do_interrupt(CPUState *cpu);
 bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index f95289444f..a5ca3ece78 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -26,7 +26,7 @@
 #include "hw/loader.h"
 #endif
 
-void openrisc_cpu_do_interrupt_locked(CPUState *cs)
+static void openrisc_cpu_do_interrupt_locked(CPUState *cs)
 {
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -101,6 +101,13 @@ void openrisc_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void openrisc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    openrisc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index ed297acdb4..2569d43e59 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1231,6 +1231,7 @@ struct PPCVirtualHypervisorClass {
                      TYPE_PPC_VIRTUAL_HYPERVISOR)
 #endif /* CONFIG_USER_ONLY */
 
+void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_do_interrupt_locked(CPUState *cpu);
 bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index fe9b122fd0..2cb1aaa296 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1428,3 +1428,10 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
     env->error_code = insn & 0x03FF0000;
     cpu_loop_exit(cs);
 }
+
+void ppc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    ppc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 653b04aef6..27ae7fa195 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10885,7 +10885,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     pcc->parent_parse_features = cc->parse_features;
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
-    cc->do_interrupt = ppc_cpu_do_interrupt_locked;
+    cc->do_interrupt = ppc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 833e6d4f1e..832171c360 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -537,7 +537,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
-    cc->do_interrupt = riscv_cpu_do_interrupt_locked;
+    cc->do_interrupt = riscv_cpu_do_interrupt;
     cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 372005b79c..a804a5d0ba 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -312,7 +312,7 @@ extern const char * const riscv_fpr_regnames[];
 extern const char * const riscv_excp_names[];
 extern const char * const riscv_intr_names[];
 
-void riscv_cpu_do_interrupt_locked(CPUState *cpu);
+void riscv_cpu_do_interrupt(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 477cf66b66..2c8ee8ca2b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -25,6 +25,8 @@
 #include "tcg/tcg-op.h"
 #include "trace.h"
 
+static void riscv_cpu_do_interrupt_locked(CPUState *cs);
+
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
@@ -814,13 +816,20 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 #endif
 }
 
+void riscv_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    riscv_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 /*
  * Handle Traps
  *
  * Adapted from Spike's processor_t::take_trap.
  *
  */
-void riscv_cpu_do_interrupt_locked(CPUState *cs)
+static void riscv_cpu_do_interrupt_locked(CPUState *cs)
 {
 #if !defined(CONFIG_USER_ONLY)
 
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 51e10da7cc..219e05397b 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -185,7 +185,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
 
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
-    cc->do_interrupt = rx_cpu_do_interrupt_locked;
+    cc->do_interrupt = rx_cpu_do_interrupt;
     cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index d188e7d43f..ec085d0386 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -125,6 +125,7 @@ typedef RXCPU ArchCPU;
 #define CPU_RESOLVING_TYPE TYPE_RX_CPU
 
 const char *rx_crname(uint8_t cr);
+void rx_cpu_do_interrupt(CPUState *cpu);
 void rx_cpu_do_interrupt_locked(CPUState *cpu);
 bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 332f89435a..8c0512b62a 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -119,6 +119,13 @@ void rx_cpu_do_interrupt_locked(CPUState *cs)
     env->regs[0] = env->isp;
 }
 
+void rx_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    rx_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     RXCPU *cpu = RXCPU(cs);
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index eb23d64f36..4d0d323cf9 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -493,7 +493,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = s390_cpu_class_by_name,
     cc->has_work_with_iothread_lock = s390_cpu_has_work;
 #ifdef CONFIG_TCG
-    cc->do_interrupt = s390_cpu_do_interrupt_locked;
+    cc->do_interrupt = s390_cpu_do_interrupt;
 #endif
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index a663127f17..a020db1725 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -611,3 +611,10 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 }
 
 #endif /* CONFIG_USER_ONLY */
+
+void s390_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    s390_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 6ab0fb481a..b4660ad255 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -268,6 +268,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 
 /* excp_helper.c */
 void s390x_cpu_debug_excp_handler(CPUState *cs);
+void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_do_interrupt_locked(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 5e5921a220..18f3448183 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -218,7 +218,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
-    cc->do_interrupt = superh_cpu_do_interrupt_locked;
+    cc->do_interrupt = superh_cpu_do_interrupt;
     cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 2ae3dd132b..dbe58c7888 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -204,7 +204,7 @@ struct SuperHCPU {
 };
 
 
-void superh_cpu_do_interrupt_locked(CPUState *cpu);
+void superh_cpu_do_interrupt(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 2d61f65d50..471650b622 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -45,7 +45,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void superh_cpu_do_interrupt_locked(CPUState *cs)
+static void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     cs->exception_index = -1;
 }
@@ -58,7 +58,7 @@ int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
 
 #else /* !CONFIG_USER_ONLY */
 
-void superh_cpu_do_interrupt_locked(CPUState *cs)
+static void superh_cpu_do_interrupt_locked(CPUState *cs)
 {
     SuperHCPU *cpu = SUPERH_CPU(cs);
     CPUSH4State *env = &cpu->env;
@@ -782,6 +782,13 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
 
 #endif
 
+void superh_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    superh_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 4c8842adcf..1c26bbd59b 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -863,7 +863,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = sparc_cpu_class_by_name;
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
-    cc->do_interrupt = sparc_cpu_do_interrupt_locked;
+    cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 3563e65d73..ec8684ec93 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -568,6 +568,7 @@ struct SPARCCPU {
 extern const VMStateDescription vmstate_sparc_cpu;
 #endif
 
+void sparc_cpu_do_interrupt(CPUState *cpu);
 void sparc_cpu_do_interrupt_locked(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
index 90f4aa4a78..7a1f15b06c 100644
--- a/target/sparc/int32_helper.c
+++ b/target/sparc/int32_helper.c
@@ -138,6 +138,13 @@ void sparc_cpu_do_interrupt_locked(CPUState *cs)
 #endif
 }
 
+void sparc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    sparc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static void leon3_cache_control_int(CPUSPARCState *env)
 {
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index b81b4abaa8..aa3d9aa585 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -198,6 +198,13 @@ void sparc_cpu_do_interrupt_locked(CPUState *cs)
     cs->exception_index = -1;
 }
 
+void sparc_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    sparc_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 trap_state *cpu_tsptr(CPUSPARCState* env)
 {
     return &env->ts[env->tl & MAXTL_MASK];
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index a2ff335977..a450dc63a3 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -125,6 +125,13 @@ static bool tilegx_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     cpu_loop_exit_restore(cs, retaddr);
 }
 
+static void tilegx_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    tilegx_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
@@ -147,7 +154,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
-    cc->do_interrupt = tilegx_cpu_do_interrupt_locked;
+    cc->do_interrupt = tilegx_cpu_do_interrupt;
     cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index a96077d666..06bf4b4b63 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -131,7 +131,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
-    cc->do_interrupt = uc32_cpu_do_interrupt_locked;
+    cc->do_interrupt = uc32_cpu_do_interrupt;
     cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index d948392ff3..9453b5d7b3 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -75,6 +75,7 @@ struct UniCore32CPU {
 };
 
 
+void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_do_interrupt_locked(CPUState *cpu);
 bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
index a12526a8ca..7fb28f3c12 100644
--- a/target/unicore32/softmmu.c
+++ b/target/unicore32/softmmu.c
@@ -120,6 +120,13 @@ void uc32_cpu_do_interrupt_locked(CPUState *cs)
     cpu_interrupt_request_or(cs, CPU_INTERRUPT_EXITTB);
 }
 
+void uc32_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    uc32_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address,
         int access_type, int is_user, uint32_t *phys_ptr, int *prot,
         target_ulong *page_size)
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 7962bc66a8..0f96483563 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -190,7 +190,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
-    cc->do_interrupt = xtensa_cpu_do_interrupt_locked;
+    cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index c02f531b64..32749378bf 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,7 +563,7 @@ struct XtensaCPU {
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
-void xtensa_cpu_do_interrupt_locked(CPUState *cpu);
+void xtensa_cpu_do_interrupt(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 10d4762f36..822ed7aad8 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -195,7 +195,7 @@ static void handle_interrupt(CPUXtensaState *env)
 }
 
 /* Called from cpu_handle_interrupt with BQL held */
-void xtensa_cpu_do_interrupt_locked(CPUState *cs)
+static void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
@@ -254,11 +254,18 @@ void xtensa_cpu_do_interrupt_locked(CPUState *cs)
     check_interrupts(env);
 }
 #else
-void xtensa_cpu_do_interrupt_locked(CPUState *cs)
+static void xtensa_cpu_do_interrupt_locked(CPUState *cs)
 {
 }
 #endif
 
+void xtensa_cpu_do_interrupt(CPUState *cs)
+{
+    qemu_mutex_lock_iothread();
+    xtensa_cpu_do_interrupt_locked(cs);
+    qemu_mutex_unlock_iothread();
+}
+
 bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 5/7] accel/tcg: Change BQL critical section in cpu_handle_interrupt
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
                   ` (3 preceding siblings ...)
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-19 18:28 ` Robert Foley
  2020-08-31 21:44   ` Richard Henderson
  2020-08-19 18:28   ` Robert Foley
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, Richard Henderson, alex.bennee, robert.foley, peter.puhov

We are changing the critical section from being around
the majority of the cpu_handle_interrupt to instead
be around just the call to ->cpu_exec_interrupt.

This is in preparation for pushing down the BQL into the
per arch implementation.

We should mention that we discussed these changes as well as
some open questions here:
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01189.html
With the main open question being:
BQL is clearly needed to protect the critical section around the call to
->cpu_exec_interrupt.  What else is the BQL protecting in cpu_handle_interrupt
that we need to consider?  Are we missing anything here?

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 accel/tcg/cpu-exec.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index e661635f06..499a8bdc5e 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -556,7 +556,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
     if (unlikely(cpu_interrupt_request(cpu))) {
         int interrupt_request;
 
-        qemu_mutex_lock_iothread();
         interrupt_request = cpu_interrupt_request(cpu);
         if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
             /* Mask out external interrupts for this step. */
@@ -565,7 +564,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
         if (interrupt_request & CPU_INTERRUPT_DEBUG) {
             cpu_reset_interrupt(cpu, CPU_INTERRUPT_DEBUG);
             cpu->exception_index = EXCP_DEBUG;
-            qemu_mutex_unlock_iothread();
             return true;
         }
         if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) {
@@ -575,13 +573,13 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
             cpu_reset_interrupt(cpu, CPU_INTERRUPT_HALT);
             cpu_halted_set(cpu, 1);
             cpu->exception_index = EXCP_HLT;
-            qemu_mutex_unlock_iothread();
             return true;
         }
 #if defined(TARGET_I386)
         else if (interrupt_request & CPU_INTERRUPT_INIT) {
             X86CPU *x86_cpu = X86_CPU(cpu);
             CPUArchState *env = &x86_cpu->env;
+            qemu_mutex_lock_iothread();
             replay_interrupt();
             cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0, 0);
             do_cpu_init(x86_cpu);
@@ -593,7 +591,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
         else if (interrupt_request & CPU_INTERRUPT_RESET) {
             replay_interrupt();
             cpu_reset(cpu);
-            qemu_mutex_unlock_iothread();
             return true;
         }
 #endif
@@ -602,6 +599,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
            True when it is, and we should restart on a new TB,
            and via longjmp via cpu_loop_exit.  */
         else {
+            qemu_mutex_lock_iothread();
             if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
                 replay_interrupt();
                 /*
@@ -616,6 +614,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
             /* The target hook may have updated the 'cpu->interrupt_request';
              * reload the 'interrupt_request' value */
             interrupt_request = cpu_interrupt_request(cpu);
+            qemu_mutex_unlock_iothread();
         }
         if (interrupt_request & CPU_INTERRUPT_EXITTB) {
             cpu_reset_interrupt(cpu, CPU_INTERRUPT_EXITTB);
@@ -625,7 +624,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
         }
 
         /* If we exit via cpu_loop_exit/longjmp it is reset in cpu_exec */
-        qemu_mutex_unlock_iothread();
     }
 
     /* Finally, check if we need to exit to the main loop.  */
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 6/7] target: rename all *_cpu_exec_interrupt functions to *_cpu_exec_interrupt_locked
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
@ 2020-08-19 18:28   ` Robert Foley
  2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Thomas Huth, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, open list:PowerPC TCG CPUs,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	robert.foley, open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, open list:RISC-V TCG CPUs,
	Bastian Koppelmann, Chris Wulff, Laurent Vivier, Michael Walle,
	Palmer Dabbelt, peter.puhov, Aurelien Jarno

The rename of all *_cpu_exec_interrupt functions to
*_cpu_exec_interrupt_locked is preparation for pushing the BQL lock
around these functions down into the per-arch implementation of
*_cpu_exec_interrupt.  In a later patch, which pushes down the lock,
we will add a new *_cpu_exec_interrupt function, which grabs the BQL
and calls to *_cpu_exec_interrupt_locked.

This patch is part of a series of transitions to move the
BQL down into the cpu_exec_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 target/alpha/cpu.c              | 2 +-
 target/alpha/cpu.h              | 2 +-
 target/alpha/helper.c           | 2 +-
 target/arm/cpu.c                | 4 ++--
 target/arm/cpu.h                | 2 +-
 target/arm/cpu64.c              | 2 +-
 target/arm/cpu_tcg.c            | 5 +++--
 target/avr/cpu.c                | 2 +-
 target/avr/cpu.h                | 2 +-
 target/avr/helper.c             | 2 +-
 target/cris/cpu.c               | 2 +-
 target/cris/cpu.h               | 2 +-
 target/cris/helper.c            | 2 +-
 target/hppa/cpu.c               | 2 +-
 target/hppa/cpu.h               | 2 +-
 target/hppa/int_helper.c        | 2 +-
 target/i386/cpu.c               | 2 +-
 target/i386/cpu.h               | 2 +-
 target/i386/seg_helper.c        | 2 +-
 target/lm32/cpu.c               | 2 +-
 target/lm32/cpu.h               | 2 +-
 target/lm32/helper.c            | 2 +-
 target/m68k/cpu.c               | 2 +-
 target/m68k/cpu.h               | 2 +-
 target/m68k/op_helper.c         | 2 +-
 target/microblaze/cpu.c         | 2 +-
 target/microblaze/cpu.h         | 2 +-
 target/microblaze/helper.c      | 2 +-
 target/mips/cpu.c               | 2 +-
 target/mips/helper.c            | 2 +-
 target/mips/internal.h          | 2 +-
 target/nios2/cpu.c              | 4 ++--
 target/openrisc/cpu.c           | 2 +-
 target/openrisc/cpu.h           | 2 +-
 target/openrisc/interrupt.c     | 2 +-
 target/ppc/cpu.h                | 2 +-
 target/ppc/excp_helper.c        | 2 +-
 target/ppc/translate_init.inc.c | 2 +-
 target/riscv/cpu.c              | 2 +-
 target/riscv/cpu.h              | 2 +-
 target/riscv/cpu_helper.c       | 2 +-
 target/rx/cpu.c                 | 2 +-
 target/rx/cpu.h                 | 2 +-
 target/rx/helper.c              | 2 +-
 target/s390x/cpu.c              | 2 +-
 target/s390x/excp_helper.c      | 2 +-
 target/s390x/internal.h         | 2 +-
 target/sh4/cpu.c                | 2 +-
 target/sh4/cpu.h                | 2 +-
 target/sh4/helper.c             | 2 +-
 target/sparc/cpu.c              | 4 ++--
 target/tilegx/cpu.c             | 5 +++--
 target/unicore32/cpu.c          | 2 +-
 target/unicore32/cpu.h          | 2 +-
 target/unicore32/helper.c       | 2 +-
 target/xtensa/cpu.c             | 2 +-
 target/xtensa/cpu.h             | 2 +-
 target/xtensa/exc_helper.c      | 2 +-
 58 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 09677c6c44..623ed42e13 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,7 +218,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
     cc->do_interrupt = alpha_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt_locked;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
     cc->gdb_read_register = alpha_cpu_gdb_read_register;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index be29bdd530..9ed82b5785 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -277,7 +277,7 @@ extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
-bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool alpha_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index e497dd269e..b5fa849f0f 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -414,7 +414,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 12eda7611f..a294739b94 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -524,7 +524,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
     return unmasked || pstate_unmasked;
 }
 
-bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     CPUARMState *env = cs->env_ptr;
@@ -2217,7 +2217,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->has_work = arm_cpu_has_work;
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
     cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 57b8904dec..8f423fcd3b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -995,7 +995,7 @@ void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_do_interrupt_locked(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
-bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool arm_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
                                          MemTxAttrs *attrs);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index dd696183df..c6c2e6709c 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -782,7 +782,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);
 
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
     cc->gdb_read_register = aarch64_cpu_gdb_read_register;
     cc->gdb_write_register = aarch64_cpu_gdb_write_register;
     cc->gdb_num_core_regs = 34;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index df36cfda76..8376497139 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -15,7 +15,8 @@
 /* CPU models. These are not needed for the AArch64 linux-user build. */
 #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
 
-static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool arm_v7m_cpu_exec_interrupt_locked(CPUState *cs,
+                                              int interrupt_request)
 {
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     ARMCPU *cpu = ARM_CPU(cs);
@@ -605,7 +606,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
     acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
-    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt_locked;
     cc->gdb_core_xml_file = "arm-m-profile.xml";
 }
 
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5d9c4ad5bf..5439b1bc50 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -198,7 +198,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->has_work = avr_cpu_has_work;
     cc->do_interrupt = avr_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt_locked;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
     cc->memory_rw_debug = avr_cpu_memory_rw_debug;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index d148e8c75a..559cf56ff9 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -157,7 +157,7 @@ typedef struct AVRCPU {
 extern const struct VMStateDescription vms_avr_cpu;
 
 void avr_cpu_do_interrupt(CPUState *cpu);
-bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool avr_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 2c8c3af580..a5c72157a1 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -26,7 +26,7 @@
 
 static void avr_cpu_do_interrupt_locked(CPUState *cs);
 
-bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     bool ret = false;
     AVRCPU *cpu = AVR_CPU(cs);
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index c3d77c31e8..81acfb3d66 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -270,7 +270,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = cris_cpu_has_work;
     cc->do_interrupt = cris_cpu_do_interrupt;
     ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
-    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt_locked;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
     cc->gdb_read_register = cris_cpu_gdb_read_register;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index d8ee6b9400..a60fb9c1e7 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -190,7 +190,7 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_do_interrupt_locked(CPUState *cpu);
 void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
-bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool cris_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 0e053782ab..9dabc8af96 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -296,7 +296,7 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
-bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     CRISCPUClass *ccc = CRIS_CPU_CLASS(cs);
     CRISCPU *cpu = CRIS_CPU(cs);
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 287055f96e..e800fba3f7 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -140,7 +140,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
     cc->do_interrupt = hppa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt_locked;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
     cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 801a4fb1ba..6e32d5581a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -324,7 +324,7 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_do_interrupt(CPUState *cpu);
-bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool hppa_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 03cb521a96..82bdee5452 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -253,7 +253,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #ifndef CONFIG_USER_ONLY
     HPPACPU *cpu = HPPA_CPU(cs);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 592aa0baf7..fa40513211 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7298,7 +7298,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
     cc->do_interrupt = x86_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt_locked;
 #endif
     cc->dump_state = x86_cpu_dump_state;
     cc->set_pc = x86_cpu_set_pc;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d784eeaf29..aa183005b2 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1771,7 +1771,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * @cpu: vCPU the interrupt is to be handled by.
  */
 void x86_cpu_do_interrupt(CPUState *cpu);
-bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool x86_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
 int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 74484eb175..6485cceaae 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1322,7 +1322,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
     do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
 }
 
-bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 9e7d8ca929..c7b95f9271 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -223,7 +223,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
     cc->do_interrupt = lm32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt_locked;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
     cc->gdb_read_register = lm32_cpu_gdb_read_register;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index 01d408eb55..ee68a2563b 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -199,7 +199,7 @@ extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
+bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 6184e212cf..6c37e6a898 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -205,7 +205,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index f2585154f5..1a75e6d968 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -278,7 +278,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
     cc->do_interrupt = m68k_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt_locked;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
     cc->gdb_read_register = m68k_cpu_gdb_read_register;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 521ac67cdd..6114a94585 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -165,7 +165,7 @@ struct M68kCPU {
 
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
-bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool m68k_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 3f0c99124a..2f71e5994d 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -511,7 +511,7 @@ void m68k_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index ce70f7d281..23e1367f83 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -317,7 +317,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt_locked;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
     cc->gdb_read_register = mb_cpu_gdb_read_register;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a31134b65c..e0b665624c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -316,7 +316,7 @@ struct MicroBlazeCPU {
 
 
 void mb_cpu_do_interrupt(CPUState *cs);
-bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
+bool mb_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index f241587b40..582e607d88 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -294,7 +294,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index ec9dde5100..520aefe669 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -197,7 +197,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
     cc->do_interrupt = mips_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt_locked;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index 3941392b95..c546788bea 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1405,7 +1405,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         MIPSCPU *cpu = MIPS_CPU(cs);
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 7f159a9230..24069f6f70 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -81,7 +81,7 @@ enum CPUMIPSMSADataFormat {
 };
 
 void mips_cpu_do_interrupt(CPUState *cpu);
-bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool mips_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mips_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 7116b3f230..d2617ed28a 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -98,7 +98,7 @@ static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
     ncc->parent_realize(dev, errp);
 }
 
-static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool nios2_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     Nios2CPU *cpu = NIOS2_CPU(cs);
     CPUNios2State *env = &cpu->env;
@@ -193,7 +193,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
     cc->do_interrupt = nios2_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt_locked;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
     cc->disas_set_info = nios2_cpu_disas_set_info;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index fd2da39124..d44b76aaa7 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -155,7 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt_locked;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
     cc->gdb_read_register = openrisc_cpu_gdb_read_register;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index f37a52e153..5cb5e0fa95 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,7 +317,7 @@ typedef struct OpenRISCCPU {
 
 void cpu_openrisc_list(void);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
-bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool openrisc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index a5ca3ece78..fcfe447e96 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -108,7 +108,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool openrisc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     CPUOpenRISCState *env = &cpu->env;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2569d43e59..75e8a61f8c 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1233,7 +1233,7 @@ struct PPCVirtualHypervisorClass {
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_do_interrupt_locked(CPUState *cpu);
-bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool ppc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2cb1aaa296..51b36aff06 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1052,7 +1052,7 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool ppc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 27ae7fa195..5037299efa 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10886,7 +10886,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
     cc->do_interrupt = ppc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt_locked;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 832171c360..5d1332b8c9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -538,7 +538,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
     cc->do_interrupt = riscv_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt_locked;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
     cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a804a5d0ba..6090420ce2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -315,7 +315,7 @@ extern const char * const riscv_intr_names[];
 void riscv_cpu_do_interrupt(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
+bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 2c8ee8ca2b..9feac5966b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -78,7 +78,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 }
 #endif
 
-bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 219e05397b..c0ffc3ab2c 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -186,7 +186,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
     cc->do_interrupt = rx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt_locked;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
     cc->synchronize_from_tb = rx_cpu_synchronize_from_tb;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index ec085d0386..e08e5a4b85 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -127,7 +127,7 @@ typedef RXCPU ArchCPU;
 const char *rx_crname(uint8_t cr);
 void rx_cpu_do_interrupt(CPUState *cpu);
 void rx_cpu_do_interrupt_locked(CPUState *cpu);
-bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool rx_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 8c0512b62a..0d479264bb 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -126,7 +126,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     RXCPU *cpu = RXCPU(cs);
     CPURXState *env = &cpu->env;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 4d0d323cf9..445b654f7f 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -505,7 +505,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_crash_info = s390_cpu_get_crash_info;
     cc->write_elf64_note = s390_cpu_write_elf64_note;
 #ifdef CONFIG_TCG
-    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt_locked;
     cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
     cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
 #endif
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index a020db1725..118d21bd06 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -543,7 +543,7 @@ try_deliver:
     }
 }
 
-bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         S390CPU *cpu = S390_CPU(cs);
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index b4660ad255..cc71b3e194 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -270,7 +270,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_do_interrupt_locked(CPUState *cpu);
-bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool s390_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr);
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 18f3448183..f64ef0e84a 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -219,7 +219,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
     cc->do_interrupt = superh_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt_locked;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index dbe58c7888..c1d3400575 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -205,7 +205,7 @@ struct SuperHCPU {
 
 
 void superh_cpu_do_interrupt(CPUState *cpu);
-bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool superh_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 471650b622..176f9edb63 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -789,7 +789,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool superh_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         SuperHCPU *cpu = SUPERH_CPU(cs);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 1c26bbd59b..e2b9de6672 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -77,7 +77,7 @@ static void sparc_cpu_reset(DeviceState *dev)
     env->cache_control = 0;
 }
 
-static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool sparc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         SPARCCPU *cpu = SPARC_CPU(cs);
@@ -864,7 +864,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
     cc->do_interrupt = sparc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt_locked;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index a450dc63a3..082607e111 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -132,7 +132,8 @@ static void tilegx_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool tilegx_cpu_exec_interrupt_locked(CPUState *cs,
+                                             int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         tilegx_cpu_do_interrupt_locked(cs);
@@ -155,7 +156,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
     cc->do_interrupt = tilegx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt_locked;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
     cc->tlb_fill = tilegx_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 06bf4b4b63..4e952e6801 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -132,7 +132,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
     cc->do_interrupt = uc32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt_locked;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
     cc->tlb_fill = uc32_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 9453b5d7b3..1e5c557696 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -77,7 +77,7 @@ struct UniCore32CPU {
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_do_interrupt_locked(CPUState *cpu);
-bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool uc32_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index f024b83bc8..f09803eb1d 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -167,7 +167,7 @@ void helper_cp1_putc(target_ulong regval)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         UniCore32CPU *cpu = UNICORE32_CPU(cs);
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 0f96483563..3ab1d74044 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -191,7 +191,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt_locked;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
     cc->gdb_read_register = xtensa_cpu_gdb_read_register;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 32749378bf..be12e5ef63 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -564,7 +564,7 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
 void xtensa_cpu_do_interrupt(CPUState *cpu);
-bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
+bool xtensa_cpu_exec_interrupt_locked(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
                                       int mmu_idx, MemTxAttrs attrs,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 822ed7aad8..14362ee86e 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -266,7 +266,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool xtensa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         cs->exception_index = EXC_IRQ;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 6/7] target: rename all *_cpu_exec_interrupt functions to *_cpu_exec_interrupt_locked
@ 2020-08-19 18:28   ` Robert Foley
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, pbonzini, peter.puhov, robert.foley,
	Richard Henderson, Peter Maydell, Michael Rolnik, Sarah Harris,
	Edgar E. Iglesias, Eduardo Habkost, Michael Walle,
	Laurent Vivier, Aleksandar Markovic, Aurelien Jarno, Jiaxun Yang,
	Aleksandar Rikalo, Chris Wulff, Marek Vasut, Stafford Horne,
	David Gibson, Palmer Dabbelt, Alistair Francis, Sagar Karandikar,
	Bastian Koppelmann, Yoshinori Sato, Cornelia Huck, Thomas Huth,
	David Hildenbrand, Mark Cave-Ayland, Artyom Tarasenko,
	Guan Xuetao, Max Filippov, open list:ARM TCG CPUs,
	open list:PowerPC TCG CPUs, open list:RISC-V TCG CPUs,
	open list:S390 general arch...

The rename of all *_cpu_exec_interrupt functions to
*_cpu_exec_interrupt_locked is preparation for pushing the BQL lock
around these functions down into the per-arch implementation of
*_cpu_exec_interrupt.  In a later patch, which pushes down the lock,
we will add a new *_cpu_exec_interrupt function, which grabs the BQL
and calls to *_cpu_exec_interrupt_locked.

This patch is part of a series of transitions to move the
BQL down into the cpu_exec_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 target/alpha/cpu.c              | 2 +-
 target/alpha/cpu.h              | 2 +-
 target/alpha/helper.c           | 2 +-
 target/arm/cpu.c                | 4 ++--
 target/arm/cpu.h                | 2 +-
 target/arm/cpu64.c              | 2 +-
 target/arm/cpu_tcg.c            | 5 +++--
 target/avr/cpu.c                | 2 +-
 target/avr/cpu.h                | 2 +-
 target/avr/helper.c             | 2 +-
 target/cris/cpu.c               | 2 +-
 target/cris/cpu.h               | 2 +-
 target/cris/helper.c            | 2 +-
 target/hppa/cpu.c               | 2 +-
 target/hppa/cpu.h               | 2 +-
 target/hppa/int_helper.c        | 2 +-
 target/i386/cpu.c               | 2 +-
 target/i386/cpu.h               | 2 +-
 target/i386/seg_helper.c        | 2 +-
 target/lm32/cpu.c               | 2 +-
 target/lm32/cpu.h               | 2 +-
 target/lm32/helper.c            | 2 +-
 target/m68k/cpu.c               | 2 +-
 target/m68k/cpu.h               | 2 +-
 target/m68k/op_helper.c         | 2 +-
 target/microblaze/cpu.c         | 2 +-
 target/microblaze/cpu.h         | 2 +-
 target/microblaze/helper.c      | 2 +-
 target/mips/cpu.c               | 2 +-
 target/mips/helper.c            | 2 +-
 target/mips/internal.h          | 2 +-
 target/nios2/cpu.c              | 4 ++--
 target/openrisc/cpu.c           | 2 +-
 target/openrisc/cpu.h           | 2 +-
 target/openrisc/interrupt.c     | 2 +-
 target/ppc/cpu.h                | 2 +-
 target/ppc/excp_helper.c        | 2 +-
 target/ppc/translate_init.inc.c | 2 +-
 target/riscv/cpu.c              | 2 +-
 target/riscv/cpu.h              | 2 +-
 target/riscv/cpu_helper.c       | 2 +-
 target/rx/cpu.c                 | 2 +-
 target/rx/cpu.h                 | 2 +-
 target/rx/helper.c              | 2 +-
 target/s390x/cpu.c              | 2 +-
 target/s390x/excp_helper.c      | 2 +-
 target/s390x/internal.h         | 2 +-
 target/sh4/cpu.c                | 2 +-
 target/sh4/cpu.h                | 2 +-
 target/sh4/helper.c             | 2 +-
 target/sparc/cpu.c              | 4 ++--
 target/tilegx/cpu.c             | 5 +++--
 target/unicore32/cpu.c          | 2 +-
 target/unicore32/cpu.h          | 2 +-
 target/unicore32/helper.c       | 2 +-
 target/xtensa/cpu.c             | 2 +-
 target/xtensa/cpu.h             | 2 +-
 target/xtensa/exc_helper.c      | 2 +-
 58 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 09677c6c44..623ed42e13 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,7 +218,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
     cc->do_interrupt = alpha_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt_locked;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
     cc->gdb_read_register = alpha_cpu_gdb_read_register;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index be29bdd530..9ed82b5785 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -277,7 +277,7 @@ extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
-bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool alpha_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index e497dd269e..b5fa849f0f 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -414,7 +414,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 12eda7611f..a294739b94 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -524,7 +524,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
     return unmasked || pstate_unmasked;
 }
 
-bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     CPUARMState *env = cs->env_ptr;
@@ -2217,7 +2217,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->has_work = arm_cpu_has_work;
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
     cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 57b8904dec..8f423fcd3b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -995,7 +995,7 @@ void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_do_interrupt_locked(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
-bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool arm_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
                                          MemTxAttrs *attrs);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index dd696183df..c6c2e6709c 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -782,7 +782,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);
 
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
     cc->gdb_read_register = aarch64_cpu_gdb_read_register;
     cc->gdb_write_register = aarch64_cpu_gdb_write_register;
     cc->gdb_num_core_regs = 34;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index df36cfda76..8376497139 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -15,7 +15,8 @@
 /* CPU models. These are not needed for the AArch64 linux-user build. */
 #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
 
-static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool arm_v7m_cpu_exec_interrupt_locked(CPUState *cs,
+                                              int interrupt_request)
 {
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     ARMCPU *cpu = ARM_CPU(cs);
@@ -605,7 +606,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
     acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
-    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt_locked;
     cc->gdb_core_xml_file = "arm-m-profile.xml";
 }
 
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5d9c4ad5bf..5439b1bc50 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -198,7 +198,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->has_work = avr_cpu_has_work;
     cc->do_interrupt = avr_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt_locked;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
     cc->memory_rw_debug = avr_cpu_memory_rw_debug;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index d148e8c75a..559cf56ff9 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -157,7 +157,7 @@ typedef struct AVRCPU {
 extern const struct VMStateDescription vms_avr_cpu;
 
 void avr_cpu_do_interrupt(CPUState *cpu);
-bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool avr_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 2c8c3af580..a5c72157a1 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -26,7 +26,7 @@
 
 static void avr_cpu_do_interrupt_locked(CPUState *cs);
 
-bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     bool ret = false;
     AVRCPU *cpu = AVR_CPU(cs);
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index c3d77c31e8..81acfb3d66 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -270,7 +270,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = cris_cpu_has_work;
     cc->do_interrupt = cris_cpu_do_interrupt;
     ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
-    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt_locked;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
     cc->gdb_read_register = cris_cpu_gdb_read_register;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index d8ee6b9400..a60fb9c1e7 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -190,7 +190,7 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_do_interrupt_locked(CPUState *cpu);
 void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
-bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool cris_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 0e053782ab..9dabc8af96 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -296,7 +296,7 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
-bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     CRISCPUClass *ccc = CRIS_CPU_CLASS(cs);
     CRISCPU *cpu = CRIS_CPU(cs);
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 287055f96e..e800fba3f7 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -140,7 +140,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
     cc->do_interrupt = hppa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt_locked;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
     cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 801a4fb1ba..6e32d5581a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -324,7 +324,7 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_do_interrupt(CPUState *cpu);
-bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool hppa_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 03cb521a96..82bdee5452 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -253,7 +253,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #ifndef CONFIG_USER_ONLY
     HPPACPU *cpu = HPPA_CPU(cs);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 592aa0baf7..fa40513211 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7298,7 +7298,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
     cc->do_interrupt = x86_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt_locked;
 #endif
     cc->dump_state = x86_cpu_dump_state;
     cc->set_pc = x86_cpu_set_pc;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d784eeaf29..aa183005b2 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1771,7 +1771,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * @cpu: vCPU the interrupt is to be handled by.
  */
 void x86_cpu_do_interrupt(CPUState *cpu);
-bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool x86_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
 int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 74484eb175..6485cceaae 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1322,7 +1322,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
     do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
 }
 
-bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 9e7d8ca929..c7b95f9271 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -223,7 +223,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
     cc->do_interrupt = lm32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt_locked;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
     cc->gdb_read_register = lm32_cpu_gdb_read_register;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index 01d408eb55..ee68a2563b 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -199,7 +199,7 @@ extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
+bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 6184e212cf..6c37e6a898 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -205,7 +205,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index f2585154f5..1a75e6d968 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -278,7 +278,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
     cc->do_interrupt = m68k_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt_locked;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
     cc->gdb_read_register = m68k_cpu_gdb_read_register;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 521ac67cdd..6114a94585 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -165,7 +165,7 @@ struct M68kCPU {
 
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
-bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool m68k_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 3f0c99124a..2f71e5994d 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -511,7 +511,7 @@ void m68k_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index ce70f7d281..23e1367f83 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -317,7 +317,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt_locked;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
     cc->gdb_read_register = mb_cpu_gdb_read_register;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a31134b65c..e0b665624c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -316,7 +316,7 @@ struct MicroBlazeCPU {
 
 
 void mb_cpu_do_interrupt(CPUState *cs);
-bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
+bool mb_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index f241587b40..582e607d88 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -294,7 +294,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index ec9dde5100..520aefe669 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -197,7 +197,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
     cc->do_interrupt = mips_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt_locked;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index 3941392b95..c546788bea 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1405,7 +1405,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         MIPSCPU *cpu = MIPS_CPU(cs);
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 7f159a9230..24069f6f70 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -81,7 +81,7 @@ enum CPUMIPSMSADataFormat {
 };
 
 void mips_cpu_do_interrupt(CPUState *cpu);
-bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool mips_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mips_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 7116b3f230..d2617ed28a 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -98,7 +98,7 @@ static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
     ncc->parent_realize(dev, errp);
 }
 
-static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool nios2_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     Nios2CPU *cpu = NIOS2_CPU(cs);
     CPUNios2State *env = &cpu->env;
@@ -193,7 +193,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
     cc->do_interrupt = nios2_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt_locked;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
     cc->disas_set_info = nios2_cpu_disas_set_info;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index fd2da39124..d44b76aaa7 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -155,7 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt_locked;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
     cc->gdb_read_register = openrisc_cpu_gdb_read_register;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index f37a52e153..5cb5e0fa95 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,7 +317,7 @@ typedef struct OpenRISCCPU {
 
 void cpu_openrisc_list(void);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
-bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool openrisc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index a5ca3ece78..fcfe447e96 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -108,7 +108,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool openrisc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     CPUOpenRISCState *env = &cpu->env;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2569d43e59..75e8a61f8c 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1233,7 +1233,7 @@ struct PPCVirtualHypervisorClass {
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_do_interrupt_locked(CPUState *cpu);
-bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool ppc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2cb1aaa296..51b36aff06 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1052,7 +1052,7 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool ppc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 27ae7fa195..5037299efa 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10886,7 +10886,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
     cc->do_interrupt = ppc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt_locked;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 832171c360..5d1332b8c9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -538,7 +538,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
     cc->do_interrupt = riscv_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt_locked;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
     cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a804a5d0ba..6090420ce2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -315,7 +315,7 @@ extern const char * const riscv_intr_names[];
 void riscv_cpu_do_interrupt(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
+bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 2c8ee8ca2b..9feac5966b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -78,7 +78,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 }
 #endif
 
-bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 219e05397b..c0ffc3ab2c 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -186,7 +186,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
     cc->do_interrupt = rx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt_locked;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
     cc->synchronize_from_tb = rx_cpu_synchronize_from_tb;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index ec085d0386..e08e5a4b85 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -127,7 +127,7 @@ typedef RXCPU ArchCPU;
 const char *rx_crname(uint8_t cr);
 void rx_cpu_do_interrupt(CPUState *cpu);
 void rx_cpu_do_interrupt_locked(CPUState *cpu);
-bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool rx_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 8c0512b62a..0d479264bb 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -126,7 +126,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     RXCPU *cpu = RXCPU(cs);
     CPURXState *env = &cpu->env;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 4d0d323cf9..445b654f7f 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -505,7 +505,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_crash_info = s390_cpu_get_crash_info;
     cc->write_elf64_note = s390_cpu_write_elf64_note;
 #ifdef CONFIG_TCG
-    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt_locked;
     cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
     cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
 #endif
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index a020db1725..118d21bd06 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -543,7 +543,7 @@ try_deliver:
     }
 }
 
-bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         S390CPU *cpu = S390_CPU(cs);
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index b4660ad255..cc71b3e194 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -270,7 +270,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_do_interrupt_locked(CPUState *cpu);
-bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool s390_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr);
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 18f3448183..f64ef0e84a 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -219,7 +219,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
     cc->do_interrupt = superh_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt_locked;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index dbe58c7888..c1d3400575 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -205,7 +205,7 @@ struct SuperHCPU {
 
 
 void superh_cpu_do_interrupt(CPUState *cpu);
-bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool superh_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 471650b622..176f9edb63 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -789,7 +789,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool superh_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         SuperHCPU *cpu = SUPERH_CPU(cs);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 1c26bbd59b..e2b9de6672 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -77,7 +77,7 @@ static void sparc_cpu_reset(DeviceState *dev)
     env->cache_control = 0;
 }
 
-static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool sparc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         SPARCCPU *cpu = SPARC_CPU(cs);
@@ -864,7 +864,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
     cc->do_interrupt = sparc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt_locked;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index a450dc63a3..082607e111 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -132,7 +132,8 @@ static void tilegx_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+static bool tilegx_cpu_exec_interrupt_locked(CPUState *cs,
+                                             int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         tilegx_cpu_do_interrupt_locked(cs);
@@ -155,7 +156,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
     cc->do_interrupt = tilegx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt_locked;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
     cc->tlb_fill = tilegx_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 06bf4b4b63..4e952e6801 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -132,7 +132,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
     cc->do_interrupt = uc32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt_locked;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
     cc->tlb_fill = uc32_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 9453b5d7b3..1e5c557696 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -77,7 +77,7 @@ struct UniCore32CPU {
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_do_interrupt_locked(CPUState *cpu);
-bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
+bool uc32_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index f024b83bc8..f09803eb1d 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -167,7 +167,7 @@ void helper_cp1_putc(target_ulong regval)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         UniCore32CPU *cpu = UNICORE32_CPU(cs);
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 0f96483563..3ab1d74044 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -191,7 +191,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
+    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt_locked;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
     cc->gdb_read_register = xtensa_cpu_gdb_read_register;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 32749378bf..be12e5ef63 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -564,7 +564,7 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
 void xtensa_cpu_do_interrupt(CPUState *cpu);
-bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
+bool xtensa_cpu_exec_interrupt_locked(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
                                       int mmu_idx, MemTxAttrs attrs,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 822ed7aad8..14362ee86e 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -266,7 +266,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+bool xtensa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         cs->exception_index = EXC_IRQ;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 7/7] target: Push BQL on ->cpu_exec_interrupt down into per-arch implementation
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
@ 2020-08-19 18:28   ` Robert Foley
  2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Thomas Huth, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, open list:PowerPC TCG CPUs,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	robert.foley, open list:S390 TCG CPUs, open list:ARM TCG CPUs,
	Michael Rolnik, pbonzini, Stafford Horne, alex.bennee,
	David Gibson, open list:RISC-V TCG CPUs, Bastian Koppelmann,
	Chris Wulff, Laurent Vivier, Michael Walle, Palmer Dabbelt,
	peter.puhov, Aurelien Jarno

Push the BQL on ->cpu_exec_interrupt down into per-arch implementation.
The first step is to remove the BQL from cpu_handle_interrupt, which
currently calls ->cpu_exec_interrupt.  We then added the *_cpu_exec_interrupt
functions, which get the BQL and then call to *_cpu_exec_interrupt_locked.
We also pointed the per-arch ->cpu_exec_interrupt at the new
*cpu_exec_interrupt.

This patch is part of a series of transitions to move the
BQL down into the cpu_exec_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 accel/tcg/cpu-exec.c            |  2 --
 target/alpha/cpu.c              |  2 +-
 target/alpha/cpu.h              |  2 +-
 target/alpha/helper.c           | 11 ++++++++++-
 target/arm/cpu.c                | 13 +++++++++++--
 target/arm/cpu.h                |  2 +-
 target/arm/cpu64.c              |  2 +-
 target/arm/cpu_tcg.c            | 11 ++++++++++-
 target/avr/cpu.c                |  2 +-
 target/avr/cpu.h                |  2 +-
 target/avr/helper.c             | 11 ++++++++++-
 target/cris/cpu.c               |  2 +-
 target/cris/cpu.h               |  2 +-
 target/cris/helper.c            | 11 ++++++++++-
 target/hppa/cpu.c               |  2 +-
 target/hppa/cpu.h               |  2 +-
 target/hppa/int_helper.c        | 11 ++++++++++-
 target/i386/cpu.c               |  2 +-
 target/i386/cpu.h               |  2 +-
 target/i386/seg_helper.c        | 11 ++++++++++-
 target/lm32/cpu.c               |  2 +-
 target/lm32/cpu.h               |  2 +-
 target/lm32/helper.c            | 11 ++++++++++-
 target/m68k/cpu.c               |  2 +-
 target/m68k/cpu.h               |  2 +-
 target/m68k/op_helper.c         | 11 ++++++++++-
 target/microblaze/cpu.c         |  2 +-
 target/microblaze/cpu.h         |  2 +-
 target/microblaze/helper.c      | 11 ++++++++++-
 target/mips/cpu.c               |  2 +-
 target/mips/helper.c            | 11 ++++++++++-
 target/mips/internal.h          |  2 +-
 target/nios2/cpu.c              | 11 ++++++++++-
 target/openrisc/cpu.c           |  2 +-
 target/openrisc/cpu.h           |  2 +-
 target/openrisc/interrupt.c     | 12 +++++++++++-
 target/ppc/cpu.h                |  2 +-
 target/ppc/excp_helper.c        | 11 ++++++++++-
 target/ppc/translate_init.inc.c |  2 +-
 target/riscv/cpu.c              |  2 +-
 target/riscv/cpu.h              |  2 +-
 target/riscv/cpu_helper.c       | 11 ++++++++++-
 target/rx/cpu.c                 |  2 +-
 target/rx/cpu.h                 |  2 +-
 target/rx/helper.c              | 11 ++++++++++-
 target/s390x/cpu.c              |  2 +-
 target/s390x/excp_helper.c      | 11 ++++++++++-
 target/s390x/internal.h         |  2 +-
 target/sh4/cpu.c                |  2 +-
 target/sh4/cpu.h                |  2 +-
 target/sh4/helper.c             | 12 +++++++++++-
 target/sparc/cpu.c              | 11 ++++++++++-
 target/tilegx/cpu.c             | 11 ++++++++++-
 target/unicore32/cpu.c          |  2 +-
 target/unicore32/cpu.h          |  2 +-
 target/unicore32/helper.c       | 11 ++++++++++-
 target/xtensa/cpu.c             |  2 +-
 target/xtensa/cpu.h             |  2 +-
 target/xtensa/exc_helper.c      | 12 +++++++++++-
 59 files changed, 260 insertions(+), 61 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 499a8bdc5e..c4e54baa6f 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -599,7 +599,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
            True when it is, and we should restart on a new TB,
            and via longjmp via cpu_loop_exit.  */
         else {
-            qemu_mutex_lock_iothread();
             if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
                 replay_interrupt();
                 /*
@@ -614,7 +613,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
             /* The target hook may have updated the 'cpu->interrupt_request';
              * reload the 'interrupt_request' value */
             interrupt_request = cpu_interrupt_request(cpu);
-            qemu_mutex_unlock_iothread();
         }
         if (interrupt_request & CPU_INTERRUPT_EXITTB) {
             cpu_reset_interrupt(cpu, CPU_INTERRUPT_EXITTB);
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 623ed42e13..09677c6c44 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,7 +218,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
     cc->do_interrupt = alpha_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
     cc->gdb_read_register = alpha_cpu_gdb_read_register;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 9ed82b5785..be29bdd530 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -277,7 +277,7 @@ extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
-bool alpha_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index b5fa849f0f..3980b05318 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -414,7 +414,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -458,6 +458,15 @@ bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool alpha_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = alpha_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 {
     static const char linux_reg_names[31][4] = {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a294739b94..b82e83ad36 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -524,7 +524,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
     return unmasked || pstate_unmasked;
 }
 
-bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     CPUARMState *env = cs->env_ptr;
@@ -577,6 +577,15 @@ bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return true;
 }
 
+bool arm_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = arm_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void arm_cpu_update_virq(ARMCPU *cpu)
 {
     /*
@@ -2217,7 +2226,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->has_work = arm_cpu_has_work;
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
     cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8f423fcd3b..57b8904dec 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -995,7 +995,7 @@ void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_do_interrupt_locked(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
-bool arm_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
                                          MemTxAttrs *attrs);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c6c2e6709c..dd696183df 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -782,7 +782,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);
 
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
     cc->gdb_read_register = aarch64_cpu_gdb_read_register;
     cc->gdb_write_register = aarch64_cpu_gdb_write_register;
     cc->gdb_num_core_regs = 34;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 8376497139..f090c989f2 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -40,6 +40,15 @@ static bool arm_v7m_cpu_exec_interrupt_locked(CPUState *cs,
     return ret;
 }
 
+static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = arm_v7m_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void arm926_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -606,7 +615,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
     acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
-    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
     cc->gdb_core_xml_file = "arm-m-profile.xml";
 }
 
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5439b1bc50..5d9c4ad5bf 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -198,7 +198,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->has_work = avr_cpu_has_work;
     cc->do_interrupt = avr_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
     cc->memory_rw_debug = avr_cpu_memory_rw_debug;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 559cf56ff9..d148e8c75a 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -157,7 +157,7 @@ typedef struct AVRCPU {
 extern const struct VMStateDescription vms_avr_cpu;
 
 void avr_cpu_do_interrupt(CPUState *cpu);
-bool avr_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index a5c72157a1..042bfe30d8 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -26,7 +26,7 @@
 
 static void avr_cpu_do_interrupt_locked(CPUState *cs);
 
-bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     bool ret = false;
     AVRCPU *cpu = AVR_CPU(cs);
@@ -57,6 +57,15 @@ bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return ret;
 }
 
+bool avr_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = avr_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void avr_cpu_do_interrupt_locked(CPUState *cs)
 {
     AVRCPU *cpu = AVR_CPU(cs);
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 81acfb3d66..c3d77c31e8 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -270,7 +270,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = cris_cpu_has_work;
     cc->do_interrupt = cris_cpu_do_interrupt;
     ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
-    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
     cc->gdb_read_register = cris_cpu_gdb_read_register;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index a60fb9c1e7..d8ee6b9400 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -190,7 +190,7 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_do_interrupt_locked(CPUState *cpu);
 void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
-bool cris_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 9dabc8af96..7848313886 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -296,7 +296,7 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
-bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     CRISCPUClass *ccc = CRIS_CPU_CLASS(cs);
     CRISCPU *cpu = CRIS_CPU(cs);
@@ -326,3 +326,12 @@ bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 
     return ret;
 }
+
+bool cris_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = cris_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index e800fba3f7..287055f96e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -140,7 +140,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
     cc->do_interrupt = hppa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
     cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 6e32d5581a..801a4fb1ba 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -324,7 +324,7 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_do_interrupt(CPUState *cpu);
-bool hppa_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 82bdee5452..9239d050e9 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -253,7 +253,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #ifndef CONFIG_USER_ONLY
     HPPACPU *cpu = HPPA_CPU(cs);
@@ -268,3 +268,12 @@ bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 #endif
     return false;
 }
+
+bool hppa_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = hppa_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fa40513211..592aa0baf7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7298,7 +7298,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
     cc->do_interrupt = x86_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
 #endif
     cc->dump_state = x86_cpu_dump_state;
     cc->set_pc = x86_cpu_set_pc;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index aa183005b2..d784eeaf29 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1771,7 +1771,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * @cpu: vCPU the interrupt is to be handled by.
  */
 void x86_cpu_do_interrupt(CPUState *cpu);
-bool x86_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
 int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 6485cceaae..9ab714a79e 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1322,7 +1322,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
     do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
 }
 
-bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
@@ -1387,6 +1387,15 @@ bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return true;
 }
 
+bool x86_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = x86_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void helper_lldt(CPUX86State *env, int selector)
 {
     SegmentCache *dt;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index c7b95f9271..9e7d8ca929 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -223,7 +223,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
     cc->do_interrupt = lm32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
     cc->gdb_read_register = lm32_cpu_gdb_read_register;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index ee68a2563b..01d408eb55 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -199,7 +199,7 @@ extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
+bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 6c37e6a898..bc7dd7e09e 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -205,7 +205,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
@@ -218,6 +218,15 @@ bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = lm32_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 /* Some soc ignores the MSB on the address bus. Thus creating a shadow memory
  * area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
  * 0x80000000-0xffffffff is not cached and used to access IO devices. */
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 1a75e6d968..f2585154f5 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -278,7 +278,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
     cc->do_interrupt = m68k_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
     cc->gdb_read_register = m68k_cpu_gdb_read_register;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 6114a94585..521ac67cdd 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -165,7 +165,7 @@ struct M68kCPU {
 
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
-bool m68k_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 2f71e5994d..da1f67e9c5 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -511,7 +511,7 @@ void m68k_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
@@ -531,6 +531,15 @@ bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool m68k_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = m68k_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr)
 {
     CPUState *cs = env_cpu(env);
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 23e1367f83..ce70f7d281 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -317,7 +317,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
     cc->gdb_read_register = mb_cpu_gdb_read_register;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index e0b665624c..a31134b65c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -316,7 +316,7 @@ struct MicroBlazeCPU {
 
 
 void mb_cpu_do_interrupt(CPUState *cs);
-bool mb_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
+bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 582e607d88..023ac6d4a5 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -294,7 +294,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -309,3 +309,12 @@ bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool mb_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = mb_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 520aefe669..ec9dde5100 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -197,7 +197,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
     cc->do_interrupt = mips_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index c546788bea..ba8b06537d 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1405,7 +1405,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         MIPSCPU *cpu = MIPS_CPU(cs);
@@ -1423,6 +1423,15 @@ bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool mips_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = mips_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra)
 {
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 24069f6f70..7f159a9230 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -81,7 +81,7 @@ enum CPUMIPSMSADataFormat {
 };
 
 void mips_cpu_do_interrupt(CPUState *cpu);
-bool mips_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mips_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index d2617ed28a..4ec0a161cb 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -112,6 +112,15 @@ static bool nios2_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+static bool nios2_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = nios2_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 
 static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
@@ -193,7 +202,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
     cc->do_interrupt = nios2_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
     cc->disas_set_info = nios2_cpu_disas_set_info;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index d44b76aaa7..fd2da39124 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -155,7 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
     cc->gdb_read_register = openrisc_cpu_gdb_read_register;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 5cb5e0fa95..f37a52e153 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,7 +317,7 @@ typedef struct OpenRISCCPU {
 
 void cpu_openrisc_list(void);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
-bool openrisc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index fcfe447e96..fb98ede373 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -108,7 +108,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool openrisc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool openrisc_cpu_exec_interrupt_locked(CPUState *cs,
+                                               int interrupt_request)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     CPUOpenRISCState *env = &cpu->env;
@@ -127,3 +128,12 @@ bool openrisc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool openrisc_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = openrisc_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 75e8a61f8c..2569d43e59 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1233,7 +1233,7 @@ struct PPCVirtualHypervisorClass {
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_do_interrupt_locked(CPUState *cpu);
-bool ppc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 51b36aff06..79ad9dbf49 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1052,7 +1052,7 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool ppc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool ppc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
@@ -1435,3 +1435,12 @@ void ppc_cpu_do_interrupt(CPUState *cs)
     ppc_cpu_do_interrupt_locked(cs);
     qemu_mutex_unlock_iothread();
 }
+
+bool ppc_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = ppc_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 5037299efa..27ae7fa195 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10886,7 +10886,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
     cc->do_interrupt = ppc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5d1332b8c9..832171c360 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -538,7 +538,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
     cc->do_interrupt = riscv_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
     cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6090420ce2..a804a5d0ba 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -315,7 +315,7 @@ extern const char * const riscv_intr_names[];
 void riscv_cpu_do_interrupt(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request);
+bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9feac5966b..6012b02c5b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -78,7 +78,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 }
 #endif
 
-bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (interrupt_request & CPU_INTERRUPT_HARD) {
@@ -95,6 +95,15 @@ bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool riscv_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = riscv_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 
 /* Return true is floating point support is currently enabled */
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index c0ffc3ab2c..219e05397b 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -186,7 +186,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
     cc->do_interrupt = rx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
     cc->synchronize_from_tb = rx_cpu_synchronize_from_tb;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index e08e5a4b85..ec085d0386 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -127,7 +127,7 @@ typedef RXCPU ArchCPU;
 const char *rx_crname(uint8_t cr);
 void rx_cpu_do_interrupt(CPUState *cpu);
 void rx_cpu_do_interrupt_locked(CPUState *cpu);
-bool rx_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 0d479264bb..ffceac0e3d 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -126,7 +126,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     RXCPU *cpu = RXCPU(cs);
     CPURXState *env = &cpu->env;
@@ -150,6 +150,15 @@ bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool rx_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = rx_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 hwaddr rx_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     return addr;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 445b654f7f..4d0d323cf9 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -505,7 +505,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_crash_info = s390_cpu_get_crash_info;
     cc->write_elf64_note = s390_cpu_write_elf64_note;
 #ifdef CONFIG_TCG
-    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
     cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
     cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
 #endif
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 118d21bd06..bcc2469c72 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -543,7 +543,7 @@ try_deliver:
     }
 }
 
-bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         S390CPU *cpu = S390_CPU(cs);
@@ -567,6 +567,15 @@ bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool s390_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = s390_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void s390x_cpu_debug_excp_handler(CPUState *cs)
 {
     S390CPU *cpu = S390_CPU(cs);
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index cc71b3e194..b4660ad255 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -270,7 +270,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_do_interrupt_locked(CPUState *cpu);
-bool s390_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr);
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index f64ef0e84a..18f3448183 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -219,7 +219,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
     cc->do_interrupt = superh_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index c1d3400575..dbe58c7888 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -205,7 +205,7 @@ struct SuperHCPU {
 
 
 void superh_cpu_do_interrupt(CPUState *cpu);
-bool superh_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 176f9edb63..7a5de5f0d6 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -789,7 +789,8 @@ void superh_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool superh_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool superh_cpu_exec_interrupt_locked(CPUState *cs,
+                                             int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         SuperHCPU *cpu = SUPERH_CPU(cs);
@@ -806,6 +807,15 @@ bool superh_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool superh_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = superh_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index e2b9de6672..1d2c7aa584 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -97,6 +97,15 @@ static bool sparc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+static bool sparc_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = sparc_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
     info->print_insn = print_insn_sparc;
@@ -864,7 +873,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
     cc->do_interrupt = sparc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 082607e111..e9af4148e5 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -142,6 +142,15 @@ static bool tilegx_cpu_exec_interrupt_locked(CPUState *cs,
     return false;
 }
 
+static bool tilegx_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = tilegx_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -156,7 +165,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
     cc->do_interrupt = tilegx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
     cc->tlb_fill = tilegx_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 4e952e6801..06bf4b4b63 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -132,7 +132,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
     cc->do_interrupt = uc32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
     cc->tlb_fill = uc32_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 1e5c557696..9453b5d7b3 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -77,7 +77,7 @@ struct UniCore32CPU {
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_do_interrupt_locked(CPUState *cpu);
-bool uc32_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index f09803eb1d..75d7f6b4af 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -167,7 +167,7 @@ void helper_cp1_putc(target_ulong regval)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         UniCore32CPU *cpu = UNICORE32_CPU(cs);
@@ -181,3 +181,12 @@ bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool uc32_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = uc32_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 3ab1d74044..0f96483563 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -191,7 +191,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
     cc->gdb_read_register = xtensa_cpu_gdb_read_register;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index be12e5ef63..32749378bf 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -564,7 +564,7 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
 void xtensa_cpu_do_interrupt(CPUState *cpu);
-bool xtensa_cpu_exec_interrupt_locked(CPUState *cpu, int interrupt_request);
+bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
                                       int mmu_idx, MemTxAttrs attrs,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 14362ee86e..eb2d03048f 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -266,7 +266,8 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool xtensa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool xtensa_cpu_exec_interrupt_locked(CPUState *cs,
+                                             int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         cs->exception_index = EXC_IRQ;
@@ -275,3 +276,12 @@ bool xtensa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool xtensa_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = xtensa_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 7/7] target: Push BQL on ->cpu_exec_interrupt down into per-arch implementation
@ 2020-08-19 18:28   ` Robert Foley
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-19 18:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, pbonzini, peter.puhov, robert.foley,
	Richard Henderson, Peter Maydell, Michael Rolnik, Sarah Harris,
	Edgar E. Iglesias, Eduardo Habkost, Michael Walle,
	Laurent Vivier, Aleksandar Markovic, Aurelien Jarno, Jiaxun Yang,
	Aleksandar Rikalo, Chris Wulff, Marek Vasut, Stafford Horne,
	David Gibson, Palmer Dabbelt, Alistair Francis, Sagar Karandikar,
	Bastian Koppelmann, Yoshinori Sato, David Hildenbrand,
	Cornelia Huck, Thomas Huth, Mark Cave-Ayland, Artyom Tarasenko,
	Guan Xuetao, Max Filippov, open list:ARM TCG CPUs,
	open list:PowerPC TCG CPUs, open list:RISC-V TCG CPUs,
	open list:S390 TCG CPUs

Push the BQL on ->cpu_exec_interrupt down into per-arch implementation.
The first step is to remove the BQL from cpu_handle_interrupt, which
currently calls ->cpu_exec_interrupt.  We then added the *_cpu_exec_interrupt
functions, which get the BQL and then call to *_cpu_exec_interrupt_locked.
We also pointed the per-arch ->cpu_exec_interrupt at the new
*cpu_exec_interrupt.

This patch is part of a series of transitions to move the
BQL down into the cpu_exec_interrupt per arch functions.  This set of
transitions is needed to maintain bisectability.

The purpose of this set of changes is to set the groundwork
so that an arch could move towards removing
the BQL from the cpu_handle_interrupt/exception paths.

This approach was suggested by Paolo Bonzini.
For reference, here are key posts in the discussion, explaining
the reasoning/benefits of this approach.
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html

Signed-off-by: Robert Foley <robert.foley@linaro.org>
---
 accel/tcg/cpu-exec.c            |  2 --
 target/alpha/cpu.c              |  2 +-
 target/alpha/cpu.h              |  2 +-
 target/alpha/helper.c           | 11 ++++++++++-
 target/arm/cpu.c                | 13 +++++++++++--
 target/arm/cpu.h                |  2 +-
 target/arm/cpu64.c              |  2 +-
 target/arm/cpu_tcg.c            | 11 ++++++++++-
 target/avr/cpu.c                |  2 +-
 target/avr/cpu.h                |  2 +-
 target/avr/helper.c             | 11 ++++++++++-
 target/cris/cpu.c               |  2 +-
 target/cris/cpu.h               |  2 +-
 target/cris/helper.c            | 11 ++++++++++-
 target/hppa/cpu.c               |  2 +-
 target/hppa/cpu.h               |  2 +-
 target/hppa/int_helper.c        | 11 ++++++++++-
 target/i386/cpu.c               |  2 +-
 target/i386/cpu.h               |  2 +-
 target/i386/seg_helper.c        | 11 ++++++++++-
 target/lm32/cpu.c               |  2 +-
 target/lm32/cpu.h               |  2 +-
 target/lm32/helper.c            | 11 ++++++++++-
 target/m68k/cpu.c               |  2 +-
 target/m68k/cpu.h               |  2 +-
 target/m68k/op_helper.c         | 11 ++++++++++-
 target/microblaze/cpu.c         |  2 +-
 target/microblaze/cpu.h         |  2 +-
 target/microblaze/helper.c      | 11 ++++++++++-
 target/mips/cpu.c               |  2 +-
 target/mips/helper.c            | 11 ++++++++++-
 target/mips/internal.h          |  2 +-
 target/nios2/cpu.c              | 11 ++++++++++-
 target/openrisc/cpu.c           |  2 +-
 target/openrisc/cpu.h           |  2 +-
 target/openrisc/interrupt.c     | 12 +++++++++++-
 target/ppc/cpu.h                |  2 +-
 target/ppc/excp_helper.c        | 11 ++++++++++-
 target/ppc/translate_init.inc.c |  2 +-
 target/riscv/cpu.c              |  2 +-
 target/riscv/cpu.h              |  2 +-
 target/riscv/cpu_helper.c       | 11 ++++++++++-
 target/rx/cpu.c                 |  2 +-
 target/rx/cpu.h                 |  2 +-
 target/rx/helper.c              | 11 ++++++++++-
 target/s390x/cpu.c              |  2 +-
 target/s390x/excp_helper.c      | 11 ++++++++++-
 target/s390x/internal.h         |  2 +-
 target/sh4/cpu.c                |  2 +-
 target/sh4/cpu.h                |  2 +-
 target/sh4/helper.c             | 12 +++++++++++-
 target/sparc/cpu.c              | 11 ++++++++++-
 target/tilegx/cpu.c             | 11 ++++++++++-
 target/unicore32/cpu.c          |  2 +-
 target/unicore32/cpu.h          |  2 +-
 target/unicore32/helper.c       | 11 ++++++++++-
 target/xtensa/cpu.c             |  2 +-
 target/xtensa/cpu.h             |  2 +-
 target/xtensa/exc_helper.c      | 12 +++++++++++-
 59 files changed, 260 insertions(+), 61 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 499a8bdc5e..c4e54baa6f 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -599,7 +599,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
            True when it is, and we should restart on a new TB,
            and via longjmp via cpu_loop_exit.  */
         else {
-            qemu_mutex_lock_iothread();
             if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
                 replay_interrupt();
                 /*
@@ -614,7 +613,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
             /* The target hook may have updated the 'cpu->interrupt_request';
              * reload the 'interrupt_request' value */
             interrupt_request = cpu_interrupt_request(cpu);
-            qemu_mutex_unlock_iothread();
         }
         if (interrupt_request & CPU_INTERRUPT_EXITTB) {
             cpu_reset_interrupt(cpu, CPU_INTERRUPT_EXITTB);
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 623ed42e13..09677c6c44 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,7 +218,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->has_work = alpha_cpu_has_work;
     cc->do_interrupt = alpha_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
     cc->gdb_read_register = alpha_cpu_gdb_read_register;
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 9ed82b5785..be29bdd530 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -277,7 +277,7 @@ extern const VMStateDescription vmstate_alpha_cpu;
 #endif
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
-bool alpha_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index b5fa849f0f..3980b05318 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -414,7 +414,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -458,6 +458,15 @@ bool alpha_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool alpha_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = alpha_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 {
     static const char linux_reg_names[31][4] = {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a294739b94..b82e83ad36 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -524,7 +524,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
     return unmasked || pstate_unmasked;
 }
 
-bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cs);
     CPUARMState *env = cs->env_ptr;
@@ -577,6 +577,15 @@ bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return true;
 }
 
+bool arm_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = arm_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void arm_cpu_update_virq(ARMCPU *cpu)
 {
     /*
@@ -2217,7 +2226,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->has_work = arm_cpu_has_work;
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
     cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8f423fcd3b..57b8904dec 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -995,7 +995,7 @@ void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_do_interrupt_locked(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu);
-bool arm_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
                                          MemTxAttrs *attrs);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c6c2e6709c..dd696183df 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -782,7 +782,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);
 
-    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
     cc->gdb_read_register = aarch64_cpu_gdb_read_register;
     cc->gdb_write_register = aarch64_cpu_gdb_write_register;
     cc->gdb_num_core_regs = 34;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 8376497139..f090c989f2 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -40,6 +40,15 @@ static bool arm_v7m_cpu_exec_interrupt_locked(CPUState *cs,
     return ret;
 }
 
+static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = arm_v7m_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void arm926_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -606,7 +615,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
     acc->do_interrupt_locked = arm_v7m_cpu_do_interrupt_locked;
 #endif
 
-    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
     cc->gdb_core_xml_file = "arm-m-profile.xml";
 }
 
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5439b1bc50..5d9c4ad5bf 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -198,7 +198,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->has_work = avr_cpu_has_work;
     cc->do_interrupt = avr_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
     cc->dump_state = avr_cpu_dump_state;
     cc->set_pc = avr_cpu_set_pc;
     cc->memory_rw_debug = avr_cpu_memory_rw_debug;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 559cf56ff9..d148e8c75a 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -157,7 +157,7 @@ typedef struct AVRCPU {
 extern const struct VMStateDescription vms_avr_cpu;
 
 void avr_cpu_do_interrupt(CPUState *cpu);
-bool avr_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/avr/helper.c b/target/avr/helper.c
index a5c72157a1..042bfe30d8 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -26,7 +26,7 @@
 
 static void avr_cpu_do_interrupt_locked(CPUState *cs);
 
-bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     bool ret = false;
     AVRCPU *cpu = AVR_CPU(cs);
@@ -57,6 +57,15 @@ bool avr_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return ret;
 }
 
+bool avr_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = avr_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void avr_cpu_do_interrupt_locked(CPUState *cs)
 {
     AVRCPU *cpu = AVR_CPU(cs);
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 81acfb3d66..c3d77c31e8 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -270,7 +270,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->has_work = cris_cpu_has_work;
     cc->do_interrupt = cris_cpu_do_interrupt;
     ccc->do_interrupt_locked = cris_cpu_do_interrupt_locked;
-    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
     cc->gdb_read_register = cris_cpu_gdb_read_register;
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index a60fb9c1e7..d8ee6b9400 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -190,7 +190,7 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_do_interrupt_locked(CPUState *cpu);
 void crisv10_cpu_do_interrupt_locked(CPUState *cpu);
-bool cris_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 9dabc8af96..7848313886 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -296,7 +296,7 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 }
 #endif
 
-bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     CRISCPUClass *ccc = CRIS_CPU_CLASS(cs);
     CRISCPU *cpu = CRIS_CPU(cs);
@@ -326,3 +326,12 @@ bool cris_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 
     return ret;
 }
+
+bool cris_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = cris_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index e800fba3f7..287055f96e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -140,7 +140,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
     cc->do_interrupt = hppa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
     cc->set_pc = hppa_cpu_set_pc;
     cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 6e32d5581a..801a4fb1ba 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -324,7 +324,7 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_do_interrupt(CPUState *cpu);
-bool hppa_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 82bdee5452..9239d050e9 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -253,7 +253,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #ifndef CONFIG_USER_ONLY
     HPPACPU *cpu = HPPA_CPU(cs);
@@ -268,3 +268,12 @@ bool hppa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 #endif
     return false;
 }
+
+bool hppa_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = hppa_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fa40513211..592aa0baf7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7298,7 +7298,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->has_work = x86_cpu_has_work;
 #ifdef CONFIG_TCG
     cc->do_interrupt = x86_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
 #endif
     cc->dump_state = x86_cpu_dump_state;
     cc->set_pc = x86_cpu_set_pc;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index aa183005b2..d784eeaf29 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1771,7 +1771,7 @@ extern VMStateDescription vmstate_x86_cpu;
  * @cpu: vCPU the interrupt is to be handled by.
  */
 void x86_cpu_do_interrupt(CPUState *cpu);
-bool x86_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
 
 int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 6485cceaae..9ab714a79e 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1322,7 +1322,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
     do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
 }
 
-bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
@@ -1387,6 +1387,15 @@ bool x86_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return true;
 }
 
+bool x86_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = x86_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void helper_lldt(CPUX86State *env, int selector)
 {
     SegmentCache *dt;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index c7b95f9271..9e7d8ca929 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -223,7 +223,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = lm32_cpu_class_by_name;
     cc->has_work = lm32_cpu_has_work;
     cc->do_interrupt = lm32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
     cc->gdb_read_register = lm32_cpu_gdb_read_register;
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index ee68a2563b..01d408eb55 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -199,7 +199,7 @@ extern const VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
+bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index 6c37e6a898..bc7dd7e09e 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -205,7 +205,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     LM32CPU *cpu = LM32_CPU(cs);
     CPULM32State *env = &cpu->env;
@@ -218,6 +218,15 @@ bool lm32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = lm32_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 /* Some soc ignores the MSB on the address bus. Thus creating a shadow memory
  * area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
  * 0x80000000-0xffffffff is not cached and used to access IO devices. */
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 1a75e6d968..f2585154f5 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -278,7 +278,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->has_work = m68k_cpu_has_work;
     cc->do_interrupt = m68k_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
     cc->gdb_read_register = m68k_cpu_gdb_read_register;
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 6114a94585..521ac67cdd 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -165,7 +165,7 @@ struct M68kCPU {
 
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
-bool m68k_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 2f71e5994d..da1f67e9c5 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -511,7 +511,7 @@ void m68k_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
@@ -531,6 +531,15 @@ bool m68k_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool m68k_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = m68k_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr)
 {
     CPUState *cs = env_cpu(env);
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 23e1367f83..ce70f7d281 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -317,7 +317,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
     cc->gdb_read_register = mb_cpu_gdb_read_register;
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index e0b665624c..a31134b65c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -316,7 +316,7 @@ struct MicroBlazeCPU {
 
 
 void mb_cpu_do_interrupt(CPUState *cs);
-bool mb_cpu_exec_interrupt_locked(CPUState *cs, int int_req);
+bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 582e607d88..023ac6d4a5 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -294,7 +294,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
@@ -309,3 +309,12 @@ bool mb_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool mb_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = mb_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 520aefe669..ec9dde5100 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -197,7 +197,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work_with_iothread_lock = mips_cpu_has_work;
     cc->do_interrupt = mips_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index c546788bea..ba8b06537d 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1405,7 +1405,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         MIPSCPU *cpu = MIPS_CPU(cs);
@@ -1423,6 +1423,15 @@ bool mips_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool mips_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = mips_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra)
 {
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 24069f6f70..7f159a9230 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -81,7 +81,7 @@ enum CPUMIPSMSADataFormat {
 };
 
 void mips_cpu_do_interrupt(CPUState *cpu);
-bool mips_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mips_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index d2617ed28a..4ec0a161cb 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -112,6 +112,15 @@ static bool nios2_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+static bool nios2_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = nios2_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 
 static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
@@ -193,7 +202,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = nios2_cpu_class_by_name;
     cc->has_work = nios2_cpu_has_work;
     cc->do_interrupt = nios2_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
     cc->dump_state = nios2_cpu_dump_state;
     cc->set_pc = nios2_cpu_set_pc;
     cc->disas_set_info = nios2_cpu_disas_set_info;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index d44b76aaa7..fd2da39124 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -155,7 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->has_work = openrisc_cpu_has_work;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
     cc->gdb_read_register = openrisc_cpu_gdb_read_register;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 5cb5e0fa95..f37a52e153 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,7 +317,7 @@ typedef struct OpenRISCCPU {
 
 void cpu_openrisc_list(void);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
-bool openrisc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index fcfe447e96..fb98ede373 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -108,7 +108,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool openrisc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool openrisc_cpu_exec_interrupt_locked(CPUState *cs,
+                                               int interrupt_request)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     CPUOpenRISCState *env = &cpu->env;
@@ -127,3 +128,12 @@ bool openrisc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool openrisc_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = openrisc_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 75e8a61f8c..2569d43e59 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1233,7 +1233,7 @@ struct PPCVirtualHypervisorClass {
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_do_interrupt_locked(CPUState *cpu);
-bool ppc_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 51b36aff06..79ad9dbf49 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1052,7 +1052,7 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool ppc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool ppc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
@@ -1435,3 +1435,12 @@ void ppc_cpu_do_interrupt(CPUState *cs)
     ppc_cpu_do_interrupt_locked(cs);
     qemu_mutex_unlock_iothread();
 }
+
+bool ppc_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = ppc_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 5037299efa..27ae7fa195 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10886,7 +10886,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = ppc_cpu_parse_featurestr;
     cc->has_work_with_iothread_lock = ppc_cpu_has_work;
     cc->do_interrupt = ppc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5d1332b8c9..832171c360 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -538,7 +538,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = riscv_cpu_class_by_name;
     cc->has_work_with_iothread_lock = riscv_cpu_has_work;
     cc->do_interrupt = riscv_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
     cc->dump_state = riscv_cpu_dump_state;
     cc->set_pc = riscv_cpu_set_pc;
     cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6090420ce2..a804a5d0ba 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -315,7 +315,7 @@ extern const char * const riscv_intr_names[];
 void riscv_cpu_do_interrupt(CPUState *cpu);
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request);
+bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9feac5966b..6012b02c5b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -78,7 +78,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 }
 #endif
 
-bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (interrupt_request & CPU_INTERRUPT_HARD) {
@@ -95,6 +95,15 @@ bool riscv_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool riscv_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = riscv_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 
 /* Return true is floating point support is currently enabled */
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index c0ffc3ab2c..219e05397b 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -186,7 +186,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
     cc->class_by_name = rx_cpu_class_by_name;
     cc->has_work = rx_cpu_has_work;
     cc->do_interrupt = rx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
     cc->dump_state = rx_cpu_dump_state;
     cc->set_pc = rx_cpu_set_pc;
     cc->synchronize_from_tb = rx_cpu_synchronize_from_tb;
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
index e08e5a4b85..ec085d0386 100644
--- a/target/rx/cpu.h
+++ b/target/rx/cpu.h
@@ -127,7 +127,7 @@ typedef RXCPU ArchCPU;
 const char *rx_crname(uint8_t cr);
 void rx_cpu_do_interrupt(CPUState *cpu);
 void rx_cpu_do_interrupt_locked(CPUState *cpu);
-bool rx_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 0d479264bb..ffceac0e3d 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -126,7 +126,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     RXCPU *cpu = RXCPU(cs);
     CPURXState *env = &cpu->env;
@@ -150,6 +150,15 @@ bool rx_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool rx_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = rx_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 hwaddr rx_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     return addr;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 445b654f7f..4d0d323cf9 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -505,7 +505,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_crash_info = s390_cpu_get_crash_info;
     cc->write_elf64_note = s390_cpu_write_elf64_note;
 #ifdef CONFIG_TCG
-    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
     cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
     cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
 #endif
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 118d21bd06..bcc2469c72 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -543,7 +543,7 @@ try_deliver:
     }
 }
 
-bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         S390CPU *cpu = S390_CPU(cs);
@@ -567,6 +567,15 @@ bool s390_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool s390_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = s390_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 void s390x_cpu_debug_excp_handler(CPUState *cs)
 {
     S390CPU *cpu = S390_CPU(cs);
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index cc71b3e194..b4660ad255 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -270,7 +270,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_do_interrupt_locked(CPUState *cpu);
-bool s390_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr);
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index f64ef0e84a..18f3448183 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -219,7 +219,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = superh_cpu_class_by_name;
     cc->has_work = superh_cpu_has_work;
     cc->do_interrupt = superh_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index c1d3400575..dbe58c7888 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -205,7 +205,7 @@ struct SuperHCPU {
 
 
 void superh_cpu_do_interrupt(CPUState *cpu);
-bool superh_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 176f9edb63..7a5de5f0d6 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -789,7 +789,8 @@ void superh_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool superh_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool superh_cpu_exec_interrupt_locked(CPUState *cs,
+                                             int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         SuperHCPU *cpu = SUPERH_CPU(cs);
@@ -806,6 +807,15 @@ bool superh_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+bool superh_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = superh_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index e2b9de6672..1d2c7aa584 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -97,6 +97,15 @@ static bool sparc_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     return false;
 }
 
+static bool sparc_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = sparc_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
     info->print_insn = print_insn_sparc;
@@ -864,7 +873,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->parse_features = sparc_cpu_parse_features;
     cc->has_work_with_iothread_lock = sparc_cpu_has_work;
     cc->do_interrupt = sparc_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 082607e111..e9af4148e5 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -142,6 +142,15 @@ static bool tilegx_cpu_exec_interrupt_locked(CPUState *cs,
     return false;
 }
 
+static bool tilegx_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = tilegx_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
+
 static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -156,7 +165,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = tilegx_cpu_class_by_name;
     cc->has_work = tilegx_cpu_has_work;
     cc->do_interrupt = tilegx_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
     cc->dump_state = tilegx_cpu_dump_state;
     cc->set_pc = tilegx_cpu_set_pc;
     cc->tlb_fill = tilegx_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 4e952e6801..06bf4b4b63 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -132,7 +132,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->has_work = uc32_cpu_has_work;
     cc->do_interrupt = uc32_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
     cc->tlb_fill = uc32_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 1e5c557696..9453b5d7b3 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -77,7 +77,7 @@ struct UniCore32CPU {
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_do_interrupt_locked(CPUState *cpu);
-bool uc32_cpu_exec_interrupt_locked(CPUState *cpu, int int_req);
+bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index f09803eb1d..75d7f6b4af 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -167,7 +167,7 @@ void helper_cp1_putc(target_ulong regval)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         UniCore32CPU *cpu = UNICORE32_CPU(cs);
@@ -181,3 +181,12 @@ bool uc32_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool uc32_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = uc32_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 3ab1d74044..0f96483563 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -191,7 +191,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = xtensa_cpu_class_by_name;
     cc->has_work_with_iothread_lock = xtensa_cpu_has_work;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
-    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt_locked;
+    cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
     cc->gdb_read_register = xtensa_cpu_gdb_read_register;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index be12e5ef63..32749378bf 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -564,7 +564,7 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
 void xtensa_cpu_do_interrupt(CPUState *cpu);
-bool xtensa_cpu_exec_interrupt_locked(CPUState *cpu, int interrupt_request);
+bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                       unsigned size, MMUAccessType access_type,
                                       int mmu_idx, MemTxAttrs attrs,
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index 14362ee86e..eb2d03048f 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -266,7 +266,8 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
     qemu_mutex_unlock_iothread();
 }
 
-bool xtensa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
+static bool xtensa_cpu_exec_interrupt_locked(CPUState *cs,
+                                             int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
         cs->exception_index = EXC_IRQ;
@@ -275,3 +276,12 @@ bool xtensa_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+bool xtensa_cpu_exec_interrupt(CPUState *cs, int int_req)
+{
+    bool status;
+    qemu_mutex_lock_iothread();
+    status = xtensa_cpu_exec_interrupt_locked(cs, int_req);
+    qemu_mutex_unlock_iothread();
+    return status;
+}
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path
  2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
                   ` (6 preceding siblings ...)
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-21 10:55 ` Cornelia Huck
  2020-08-27 12:38   ` Robert Foley
  7 siblings, 1 reply; 27+ messages in thread
From: Cornelia Huck @ 2020-08-21 10:55 UTC (permalink / raw)
  To: Robert Foley
  Cc: Peter Maydell, Sarah Harris, Sagar Karandikar, David Hildenbrand,
	Anthony Green, Mark Cave-Ayland, qemu-devel, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Marek Vasut, Yoshinori Sato, Aleksandar Markovic, Thomas Huth,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	Eduardo Habkost, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, Bastian Koppelmann, Chris Wulff,
	Laurent Vivier, Michael Walle, Palmer Dabbelt, peter.puhov,
	Aurelien Jarno

On Wed, 19 Aug 2020 14:28:49 -0400
Robert Foley <robert.foley@linaro.org> wrote:

> The purpose of this change is to set the groundwork
> so that an arch could move towards removing
> the BQL from the cpu_handle_interrupt/exception paths.
> 
> The BQL is a bottleneck in scaling to more cores.
> And this cpu_handle_interrupt/exception path is one of
> the key BQL users as measured by the QEMU sync profiling (qsp).
> 
> As the first step in removing the BQL from this path, we will make
> changes to the core/common functions of cpu_handle_interrupt/exception
> to drop the holding of the BQL. The holding of the BQL is pushed down
> to the per-arch implementation code.

I have only skimmed the patches I was cc:ed on so far, but the series
seems sane to me in general.

> 
> This patch goes through several transitions of the code in order to
> maintain correctness (bisectability).  In order to maintain
> bisectability across these steps some patches need to touch many
> files across different arches, however most of the changes are trivial.
> 
> The general order of the changes is below where each step
> represents one patch.
> 
> 1) rename all *_do_interrupt functions to *_do_interrupt_locked

I'm wondering whether this renaming could be done in an automated way
(e.g. via Coccinelle). Reviewing the method for the renaming is often
easier than looking at a lot of similar code patterns.

> 
> 2) add a new function *_do_interrupt that takes the BQL and calls
> *_do_interrupt_locked, point ->do_interrupt to it, and remove 
> the BQL from cpu-exec.c's cpu_handle_exception.
> 
> 3) modify the BQL critical sections around
> ->cpu_exec_interrupt, so that the BQL critical section covers just the  
> call to ->cpu_exec_interrupt. 
> 
> 4/5) same as 1/2 for ->cpu_exec_interrupt.  This removes the BQL
> from cpu_handle_exception.

The method of doing this in steps looks fine, although the patches
produced are a bit unwieldy -- that's something we have to live with, I
guess.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path
  2020-08-21 10:55 ` [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Cornelia Huck
@ 2020-08-27 12:38   ` Robert Foley
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Foley @ 2020-08-27 12:38 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Peter Maydell, Sarah Harris, Sagar Karandikar, David Hildenbrand,
	Anthony Green, Mark Cave-Ayland, QEMU Developers, Max Filippov,
	Alistair Francis, Edgar E. Iglesias, Guan Xuetao, Marek Vasut,
	Yoshinori Sato, Aleksandar Markovic, Thomas Huth,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	Eduardo Habkost, Michael Rolnik, Paolo Bonzini, Stafford Horne,
	Alex Bennée, David Gibson, Bastian Koppelmann, Chris Wulff,
	Laurent Vivier, Michael Walle, Palmer Dabbelt, Peter Puhov,
	Aurelien Jarno

On Fri, 21 Aug 2020 at 06:56, Cornelia Huck <cohuck@redhat.com> wrote:
> >
> > As the first step in removing the BQL from this path, we will make
> > changes to the core/common functions of cpu_handle_interrupt/exception
> > to drop the holding of the BQL. The holding of the BQL is pushed down
> > to the per-arch implementation code.
>
> I have only skimmed the patches I was cc:ed on so far, but the series
> seems sane to me in general.

Thanks for the feedback !
>
> >
> > This patch goes through several transitions of the code in order to
> > maintain correctness (bisectability).  In order to maintain
> > bisectability across these steps some patches need to touch many
> > files across different arches, however most of the changes are trivial.
> >
> > The general order of the changes is below where each step
> > represents one patch.
> >
> > 1) rename all *_do_interrupt functions to *_do_interrupt_locked
>
> I'm wondering whether this renaming could be done in an automated way
> (e.g. via Coccinelle). Reviewing the method for the renaming is often
> easier than looking at a lot of similar code patterns.

Good point.   We will look into this.

Thanks,
-Rob Foley
>
> >
> > 2) add a new function *_do_interrupt that takes the BQL and calls
> > *_do_interrupt_locked, point ->do_interrupt to it, and remove
> > the BQL from cpu-exec.c's cpu_handle_exception.
> >
> > 3) modify the BQL critical sections around
> > ->cpu_exec_interrupt, so that the BQL critical section covers just the
> > call to ->cpu_exec_interrupt.
> >
> > 4/5) same as 1/2 for ->cpu_exec_interrupt.  This removes the BQL
> > from cpu_handle_exception.
>
> The method of doing this in steps looks fine, although the patches
> produced are a bit unwieldy -- that's something we have to live with, I
> guess.
>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 1/7] target: rename all *_do_interupt functions to _do_interrupt_locked
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-31 21:14     ` Richard Henderson
  -1 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:14 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Anthony Green, Mark Cave-Ayland, Thomas Huth,
	Jiaxun Yang, Max Filippov, Alistair Francis, Edgar E. Iglesias,
	Guan Xuetao, Eduardo Habkost, Marek Vasut,
	open list:Overall KVM CPUs, Yoshinori Sato, Aleksandar Markovic,
	open list:sPAPR, Richard Henderson, Artyom Tarasenko,
	Aleksandar Rikalo, open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, open list:RISC-V TCG CPUs,
	Bastian Koppelmann, Chris Wulff, Laurent Vivier, Michael Walle,
	Palmer Dabbelt, peter.puhov, Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> The rename of all *_do_interrupt functions to *_do_interrupt_locked
> is preparation for pushing the BQL lock around these functions
> down into the per-arch implementation of *_do_interrupt.
> In a later patch which pushes down the lock, we will add
> a new *_do_interrupt function which grabs the BQL and calls to
> *_do_interrupt_locked.
> 
> This is the first patch in a series of transitions to move the
> BQL down into the do_interrupt per arch function.  This set of
> transitions is needed to maintain bisectability.
> 
> The purpose of this set of changes is to set the groundwork
> so that an arch could move towards removing
> the BQL from the cpu_handle_interrupt/exception paths.
> 
> This approach was suggested by Paolo Bonzini.
> For reference, here are key posts in the discussion, explaining
> the reasoning/benefits of this approach.
> 
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> 
> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> ---

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 1/7] target: rename all *_do_interupt functions to _do_interrupt_locked
@ 2020-08-31 21:14     ` Richard Henderson
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:14 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Chris Wulff, Sagar Karandikar,
	David Hildenbrand, Anthony Green, Mark Cave-Ayland,
	Aleksandar Rikalo, Max Filippov, Alistair Francis,
	Edgar E. Iglesias, Guan Xuetao, Marek Vasut,
	open list:Overall KVM CPUs, Yoshinori Sato, Aleksandar Markovic,
	Palmer Dabbelt, David Gibson, Artyom Tarasenko, Thomas Huth,
	Eduardo Habkost, open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, peter.puhov,
	Stafford Horne, alex.bennee, Richard Henderson,
	open list:RISC-V TCG CPUs, Bastian Koppelmann, Cornelia Huck,
	Laurent Vivier, Michael Walle, open list:sPAPR, pbonzini,
	Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> The rename of all *_do_interrupt functions to *_do_interrupt_locked
> is preparation for pushing the BQL lock around these functions
> down into the per-arch implementation of *_do_interrupt.
> In a later patch which pushes down the lock, we will add
> a new *_do_interrupt function which grabs the BQL and calls to
> *_do_interrupt_locked.
> 
> This is the first patch in a series of transitions to move the
> BQL down into the do_interrupt per arch function.  This set of
> transitions is needed to maintain bisectability.
> 
> The purpose of this set of changes is to set the groundwork
> so that an arch could move towards removing
> the BQL from the cpu_handle_interrupt/exception paths.
> 
> This approach was suggested by Paolo Bonzini.
> For reference, here are key posts in the discussion, explaining
> the reasoning/benefits of this approach.
> 
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> 
> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> ---

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked
  2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
@ 2020-08-31 21:18   ` Richard Henderson
  2020-08-31 22:02     ` Richard Henderson
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:18 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, open list:ARM TCG CPUs, alex.bennee, pbonzini,
	peter.puhov

On 8/19/20 11:28 AM, Robert Foley wrote:
> Adding ->do_interrupt_locked to ARMCPUClass is preparation for
> pushing the BQL down into the per-arch implementation of ->do_interrupt.
> 
> This is needed since ARM's *_cpu_exec_interrupt calls to *_do_interrupt.
> With the push down of the BQL into *_cpu_exec_interrupt and
> *_do_interrupt, *_cpu_exec_interrupt will call to ->do_interrupt
> with lock held.  Since ->do_interrupt also has the lock, we need a way
> to allow cpu_exec_interrupt to call do_interrupt with lock held.
> This patch solves this issue of *_cpu_exec_interrupt needing
> to call do_interrupt with lock held.
> 
> This patch is part of a series of transitions to move the
> BQL down into the do_interrupt per arch functions.  This set of
> transitions is needed to maintain bisectability.
> 
> This approach was suggested by Paolo Bonzini.
> For reference, here are two key posts in the discussion, explaining
> the reasoning/benefits of this approach.
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> 
> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> ---
>  target/arm/cpu-qom.h | 3 +++
>  target/arm/cpu.c     | 5 +++--
>  target/arm/cpu_tcg.c | 5 +++--
>  3 files changed, 9 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 3/7] target/cris: add CRISCPUClass->do_interrupt_locked
  2020-08-19 18:28 ` [PATCH v2 3/7] target/cris: add CRISCPUClass->do_interrupt_locked Robert Foley
@ 2020-08-31 21:19   ` Richard Henderson
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:19 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Edgar E. Iglesias, peter.puhov, alex.bennee, pbonzini

On 8/19/20 11:28 AM, Robert Foley wrote:
> Adding ->do_interrupt_locked to CRISCPUClass is preparation for
> pushing the BQL down into the per-arch implementation of ->do_interrupt.
> 
> This is needed since Cris's *_cpu_exec_interrupt calls to *_do_interrupt.
> With the push down of the BQL into *_cpu_exec_interrupt and
> *_do_interrupt, *_cpu_exec_interrupt will call to ->do_interrupt
> with lock held.  Since ->do_interrupt also has the lock, we need a way
> to allow cpu_exec_interrupt to call do_interrupt with lock held.
> This patch solves the issue of *_cpu_exec_interrupt needing
> to call do_interrupt with lock held.
> 
> This patch is part of a series of transitions to move the
> BQL down into the do_interrupt per arch functions.  This set of
> transitions is needed to maintain bisectability.
> 
> This approach was suggested by Paolo Bonzini.
> For reference, here are two key posts in the discussion, explaining
> the reasoning/benefits of this approach.
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> 
> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> ---
>  target/cris/cpu-qom.h | 3 +++
>  target/cris/cpu.c     | 6 ++++++
>  target/cris/helper.c  | 6 +++---
>  3 files changed, 12 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 4/7] target: Push BQL on ->do_interrupt down into per-arch implementation
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-31 21:37     ` Richard Henderson
  -1 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:37 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Chris Wulff, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Aleksandar Rikalo,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Marek Vasut, Yoshinori Sato, Aleksandar Markovic, Palmer Dabbelt,
	David Gibson, Artyom Tarasenko, Thomas Huth, Eduardo Habkost,
	open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, peter.puhov,
	Stafford Horne, alex.bennee, Richard Henderson,
	open list:RISC-V TCG CPUs, Bastian Koppelmann, Cornelia Huck,
	Laurent Vivier, Michael Walle, open list:PowerPC TCG CPUs,
	pbonzini, Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> avr is another exception.  avr, arm and cris all had a similar
> case where their *_cpu_exec_interrupt was calling to
> the CPUClass ->do_interrupt.  This causes an issue when we push
> the lock down since ->do_interrupt will try to acquire the BQL, but
> the calling context already has it.

Alpha is in this lest as well, correct?

> diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
> index 4c6753df34..be29bdd530 100644
> --- a/target/alpha/cpu.h
> +++ b/target/alpha/cpu.h
> @@ -276,7 +276,7 @@ struct AlphaCPU {
>  extern const VMStateDescription vmstate_alpha_cpu;
>  #endif
>  
> -void alpha_cpu_do_interrupt_locked(CPUState *cpu);
> +void alpha_cpu_do_interrupt(CPUState *cpu);
>  bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
>  hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
> diff --git a/target/alpha/helper.c b/target/alpha/helper.c
> index ff9a2a7765..e497dd269e 100644
> --- a/target/alpha/helper.c
> +++ b/target/alpha/helper.c
> @@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
>  }
>  #endif /* USER_ONLY */
>  
> -void alpha_cpu_do_interrupt_locked(CPUState *cs)
> +static void alpha_cpu_do_interrupt_locked(CPUState *cs)
>  {
>      AlphaCPU *cpu = ALPHA_CPU(cs);
>      CPUAlphaState *env = &cpu->env;
> @@ -407,6 +407,13 @@ void alpha_cpu_do_interrupt_locked(CPUState *cs)
>  #endif /* !USER_ONLY */
>  }
>  
> +void alpha_cpu_do_interrupt(CPUState *cs)
> +{
> +    qemu_mutex_lock_iothread();
> +    alpha_cpu_do_interrupt_locked(cs);
> +    qemu_mutex_unlock_iothread();
> +}
> +
>  bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>      AlphaCPU *cpu = ALPHA_CPU(cs);

This rename should have been done in patch 1, as with all others.
Moreover, this leaves a bug in alpha_cpu_exec_interrupt in that it should be
calling alpha_cpu_do_interrupt_locked.

That seems to be the only instance of this mistake.


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 4/7] target: Push BQL on ->do_interrupt down into per-arch implementation
@ 2020-08-31 21:37     ` Richard Henderson
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:37 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Thomas Huth, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, open list:PowerPC TCG CPUs,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, open list:RISC-V TCG CPUs,
	Bastian Koppelmann, Chris Wulff, Laurent Vivier, Michael Walle,
	Palmer Dabbelt, peter.puhov, Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> avr is another exception.  avr, arm and cris all had a similar
> case where their *_cpu_exec_interrupt was calling to
> the CPUClass ->do_interrupt.  This causes an issue when we push
> the lock down since ->do_interrupt will try to acquire the BQL, but
> the calling context already has it.

Alpha is in this lest as well, correct?

> diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
> index 4c6753df34..be29bdd530 100644
> --- a/target/alpha/cpu.h
> +++ b/target/alpha/cpu.h
> @@ -276,7 +276,7 @@ struct AlphaCPU {
>  extern const VMStateDescription vmstate_alpha_cpu;
>  #endif
>  
> -void alpha_cpu_do_interrupt_locked(CPUState *cpu);
> +void alpha_cpu_do_interrupt(CPUState *cpu);
>  bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
>  hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
> diff --git a/target/alpha/helper.c b/target/alpha/helper.c
> index ff9a2a7765..e497dd269e 100644
> --- a/target/alpha/helper.c
> +++ b/target/alpha/helper.c
> @@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
>  }
>  #endif /* USER_ONLY */
>  
> -void alpha_cpu_do_interrupt_locked(CPUState *cs)
> +static void alpha_cpu_do_interrupt_locked(CPUState *cs)
>  {
>      AlphaCPU *cpu = ALPHA_CPU(cs);
>      CPUAlphaState *env = &cpu->env;
> @@ -407,6 +407,13 @@ void alpha_cpu_do_interrupt_locked(CPUState *cs)
>  #endif /* !USER_ONLY */
>  }
>  
> +void alpha_cpu_do_interrupt(CPUState *cs)
> +{
> +    qemu_mutex_lock_iothread();
> +    alpha_cpu_do_interrupt_locked(cs);
> +    qemu_mutex_unlock_iothread();
> +}
> +
>  bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>      AlphaCPU *cpu = ALPHA_CPU(cs);

This rename should have been done in patch 1, as with all others.
Moreover, this leaves a bug in alpha_cpu_exec_interrupt in that it should be
calling alpha_cpu_do_interrupt_locked.

That seems to be the only instance of this mistake.


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 5/7] accel/tcg: Change BQL critical section in cpu_handle_interrupt
  2020-08-19 18:28 ` [PATCH v2 5/7] accel/tcg: Change BQL critical section in cpu_handle_interrupt Robert Foley
@ 2020-08-31 21:44   ` Richard Henderson
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:44 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: pbonzini, peter.puhov, alex.bennee, Richard Henderson

On 8/19/20 11:28 AM, Robert Foley wrote:
> @@ -625,7 +624,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
>          }
>  
>          /* If we exit via cpu_loop_exit/longjmp it is reset in cpu_exec */
> -        qemu_mutex_unlock_iothread();

The comment no longer has an "it" to reference.
We should probably expand that to mention which lock.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 6/7] target: rename all *_cpu_exec_interrupt functions to *_cpu_exec_interrupt_locked
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-31 21:46     ` Richard Henderson
  -1 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:46 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Chris Wulff, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Aleksandar Rikalo,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Marek Vasut, Yoshinori Sato, Aleksandar Markovic, Palmer Dabbelt,
	David Gibson, Artyom Tarasenko, Thomas Huth, Eduardo Habkost,
	open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, peter.puhov,
	Stafford Horne, alex.bennee, Richard Henderson,
	open list:RISC-V TCG CPUs, Bastian Koppelmann, Cornelia Huck,
	Laurent Vivier, Michael Walle, open list:PowerPC TCG CPUs,
	pbonzini, Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> The rename of all *_cpu_exec_interrupt functions to
> *_cpu_exec_interrupt_locked is preparation for pushing the BQL lock
> around these functions down into the per-arch implementation of
> *_cpu_exec_interrupt.  In a later patch, which pushes down the lock,
> we will add a new *_cpu_exec_interrupt function, which grabs the BQL
> and calls to *_cpu_exec_interrupt_locked.
> 
> This patch is part of a series of transitions to move the
> BQL down into the cpu_exec_interrupt per arch functions.  This set of
> transitions is needed to maintain bisectability.
> 
> The purpose of this set of changes is to set the groundwork
> so that an arch could move towards removing
> the BQL from the cpu_handle_interrupt/exception paths.
> 
> This approach was suggested by Paolo Bonzini.
> For reference, here are key posts in the discussion, explaining
> the reasoning/benefits of this approach.
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> 
> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> ---

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 6/7] target: rename all *_cpu_exec_interrupt functions to *_cpu_exec_interrupt_locked
@ 2020-08-31 21:46     ` Richard Henderson
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 21:46 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Thomas Huth, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, open list:PowerPC TCG CPUs,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	open list:S390 general arch...,
	open list:ARM TCG CPUs, Michael Rolnik, pbonzini, Stafford Horne,
	alex.bennee, David Gibson, open list:RISC-V TCG CPUs,
	Bastian Koppelmann, Chris Wulff, Laurent Vivier, Michael Walle,
	Palmer Dabbelt, peter.puhov, Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> The rename of all *_cpu_exec_interrupt functions to
> *_cpu_exec_interrupt_locked is preparation for pushing the BQL lock
> around these functions down into the per-arch implementation of
> *_cpu_exec_interrupt.  In a later patch, which pushes down the lock,
> we will add a new *_cpu_exec_interrupt function, which grabs the BQL
> and calls to *_cpu_exec_interrupt_locked.
> 
> This patch is part of a series of transitions to move the
> BQL down into the cpu_exec_interrupt per arch functions.  This set of
> transitions is needed to maintain bisectability.
> 
> The purpose of this set of changes is to set the groundwork
> so that an arch could move towards removing
> the BQL from the cpu_handle_interrupt/exception paths.
> 
> This approach was suggested by Paolo Bonzini.
> For reference, here are key posts in the discussion, explaining
> the reasoning/benefits of this approach.
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> 
> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> ---

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked
  2020-08-31 21:18   ` Richard Henderson
@ 2020-08-31 22:02     ` Richard Henderson
  2020-08-31 23:44       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 22:02 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, open list:ARM TCG CPUs, alex.bennee, pbonzini,
	peter.puhov

On 8/31/20 2:18 PM, Richard Henderson wrote:
> On 8/19/20 11:28 AM, Robert Foley wrote:
>> Adding ->do_interrupt_locked to ARMCPUClass is preparation for
>> pushing the BQL down into the per-arch implementation of ->do_interrupt.
>>
>> This is needed since ARM's *_cpu_exec_interrupt calls to *_do_interrupt.
>> With the push down of the BQL into *_cpu_exec_interrupt and
>> *_do_interrupt, *_cpu_exec_interrupt will call to ->do_interrupt
>> with lock held.  Since ->do_interrupt also has the lock, we need a way
>> to allow cpu_exec_interrupt to call do_interrupt with lock held.
>> This patch solves this issue of *_cpu_exec_interrupt needing
>> to call do_interrupt with lock held.
>>
>> This patch is part of a series of transitions to move the
>> BQL down into the do_interrupt per arch functions.  This set of
>> transitions is needed to maintain bisectability.
>>
>> This approach was suggested by Paolo Bonzini.
>> For reference, here are two key posts in the discussion, explaining
>> the reasoning/benefits of this approach.
>> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
>> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
>> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
>> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
>>
>> Signed-off-by: Robert Foley <robert.foley@linaro.org>
>> ---
>>  target/arm/cpu-qom.h | 3 +++
>>  target/arm/cpu.c     | 5 +++--
>>  target/arm/cpu_tcg.c | 5 +++--
>>  3 files changed, 9 insertions(+), 4 deletions(-)
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

I take it back.  These two cc->do_interrupt calls can be replaced with direct
calls.

> #ifndef CONFIG_USER_ONLY
>     cc->do_interrupt = arm_v7m_cpu_do_interrupt;
> #endif
> 
>     cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;

If we are in arm_v7m_cpu_exec_interrupt we will always call
arm_v7m_cpu_do_interrupt.

I think the mismatch of #ifdef, which implies a different destination is
possible, is a bug -- cc->do_interrupt is not otherwise assigned and in fact
would be NULL.

I suspect that some of these slots themselves should be ifdefed, so that we
cannot assign to them when they are unused.  That would help keep the ifdefs in
the cpu init functions in sync.

This same condition is *not* true for cris -- there is no
crisv10_cpu_exec_interrupt -- so you do need the new do_interrupt_locked field
there.


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 7/7] target: Push BQL on ->cpu_exec_interrupt down into per-arch implementation
  2020-08-19 18:28   ` Robert Foley
@ 2020-08-31 22:11     ` Richard Henderson
  -1 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 22:11 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Chris Wulff, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Aleksandar Rikalo,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Marek Vasut, Yoshinori Sato, Aleksandar Markovic, Palmer Dabbelt,
	David Gibson, Artyom Tarasenko, Thomas Huth, Eduardo Habkost,
	open list:S390 TCG CPUs, open list:ARM TCG CPUs, Michael Rolnik,
	peter.puhov, Stafford Horne, alex.bennee, Richard Henderson,
	open list:RISC-V TCG CPUs, Bastian Koppelmann, Cornelia Huck,
	Laurent Vivier, Michael Walle, open list:PowerPC TCG CPUs,
	pbonzini, Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 499a8bdc5e..c4e54baa6f 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -599,7 +599,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
>             True when it is, and we should restart on a new TB,
>             and via longjmp via cpu_loop_exit.  */
>          else {
> -            qemu_mutex_lock_iothread();
>              if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
>                  replay_interrupt();
>                  /*
> @@ -614,7 +613,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
>              /* The target hook may have updated the 'cpu->interrupt_request';
>               * reload the 'interrupt_request' value */
>              interrupt_request = cpu_interrupt_request(cpu);
> -            qemu_mutex_unlock_iothread();
>          }
>          if (interrupt_request & CPU_INTERRUPT_EXITTB) {
>              cpu_reset_interrupt(cpu, CPU_INTERRUPT_EXITTB);

I think you need a change to patch 5, because this patch reduces the scope
further, around cpu_interrupt_request, etc.

I think patch 5 should have

+    bool success;
+    qemu_mutex_lock_iothread();
+    success = cc->cpu_exec_interrupt(cpu, interrupt_request);
+    qemu_mutex_unlok_iothread();
+    if (success) {
-    if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {

That way this patch maintains the scope of the lock.


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 7/7] target: Push BQL on ->cpu_exec_interrupt down into per-arch implementation
@ 2020-08-31 22:11     ` Richard Henderson
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2020-08-31 22:11 UTC (permalink / raw)
  To: Robert Foley, qemu-devel
  Cc: Peter Maydell, Sarah Harris, Cornelia Huck, Sagar Karandikar,
	David Hildenbrand, Mark Cave-Ayland, Thomas Huth, Jiaxun Yang,
	Max Filippov, Alistair Francis, Edgar E. Iglesias, Guan Xuetao,
	Eduardo Habkost, Marek Vasut, Yoshinori Sato,
	Aleksandar Markovic, open list:PowerPC TCG CPUs,
	Richard Henderson, Artyom Tarasenko, Aleksandar Rikalo,
	open list:S390 TCG CPUs, open list:ARM TCG CPUs, Michael Rolnik,
	pbonzini, Stafford Horne, alex.bennee, David Gibson,
	open list:RISC-V TCG CPUs, Bastian Koppelmann, Chris Wulff,
	Laurent Vivier, Michael Walle, Palmer Dabbelt, peter.puhov,
	Aurelien Jarno

On 8/19/20 11:28 AM, Robert Foley wrote:
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 499a8bdc5e..c4e54baa6f 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -599,7 +599,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
>             True when it is, and we should restart on a new TB,
>             and via longjmp via cpu_loop_exit.  */
>          else {
> -            qemu_mutex_lock_iothread();
>              if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
>                  replay_interrupt();
>                  /*
> @@ -614,7 +613,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
>              /* The target hook may have updated the 'cpu->interrupt_request';
>               * reload the 'interrupt_request' value */
>              interrupt_request = cpu_interrupt_request(cpu);
> -            qemu_mutex_unlock_iothread();
>          }
>          if (interrupt_request & CPU_INTERRUPT_EXITTB) {
>              cpu_reset_interrupt(cpu, CPU_INTERRUPT_EXITTB);

I think you need a change to patch 5, because this patch reduces the scope
further, around cpu_interrupt_request, etc.

I think patch 5 should have

+    bool success;
+    qemu_mutex_lock_iothread();
+    success = cc->cpu_exec_interrupt(cpu, interrupt_request);
+    qemu_mutex_unlok_iothread();
+    if (success) {
-    if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {

That way this patch maintains the scope of the lock.


r~


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked
  2020-08-31 22:02     ` Richard Henderson
@ 2020-08-31 23:44       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 23:44 UTC (permalink / raw)
  To: Richard Henderson, Peter Maydell
  Cc: peter.puhov, Paolo Bonzini, qemu-arm, Robert Foley,
	qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 2907 bytes --]

Le mar. 1 sept. 2020 00:02, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> On 8/31/20 2:18 PM, Richard Henderson wrote:
> > On 8/19/20 11:28 AM, Robert Foley wrote:
> >> Adding ->do_interrupt_locked to ARMCPUClass is preparation for
> >> pushing the BQL down into the per-arch implementation of ->do_interrupt.
> >>
> >> This is needed since ARM's *_cpu_exec_interrupt calls to *_do_interrupt.
> >> With the push down of the BQL into *_cpu_exec_interrupt and
> >> *_do_interrupt, *_cpu_exec_interrupt will call to ->do_interrupt
> >> with lock held.  Since ->do_interrupt also has the lock, we need a way
> >> to allow cpu_exec_interrupt to call do_interrupt with lock held.
> >> This patch solves this issue of *_cpu_exec_interrupt needing
> >> to call do_interrupt with lock held.
> >>
> >> This patch is part of a series of transitions to move the
> >> BQL down into the do_interrupt per arch functions.  This set of
> >> transitions is needed to maintain bisectability.
> >>
> >> This approach was suggested by Paolo Bonzini.
> >> For reference, here are two key posts in the discussion, explaining
> >> the reasoning/benefits of this approach.
> >> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html
> >> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html
> >> https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html
> >> https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html
> >>
> >> Signed-off-by: Robert Foley <robert.foley@linaro.org>
> >> ---
> >>  target/arm/cpu-qom.h | 3 +++
> >>  target/arm/cpu.c     | 5 +++--
> >>  target/arm/cpu_tcg.c | 5 +++--
> >>  3 files changed, 9 insertions(+), 4 deletions(-)
> >
> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
> I take it back.  These two cc->do_interrupt calls can be replaced with
> direct
> calls.
>
> > #ifndef CONFIG_USER_ONLY
> >     cc->do_interrupt = arm_v7m_cpu_do_interrupt;
> > #endif
> >
> >     cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
>
> If we are in arm_v7m_cpu_exec_interrupt we will always call
> arm_v7m_cpu_do_interrupt.
>
> I think the mismatch of #ifdef, which implies a different destination is
> possible, is a bug -- cc->do_interrupt is not otherwise assigned and in
> fact
> would be NULL.
>
> I suspect that some of these slots themselves should be ifdefed, so that we
> cannot assign to them when they are unused.  That would help keep the
> ifdefs in
> the cpu init functions in sync.
>

I tried to do this once but this breaks sizeof(CPUState) archived in
libqemu.a vs linking softmmu / user.
IIRC Peter explained why we can't do that. I'll search the post tomorrow.


> This same condition is *not* true for cris -- there is no
> crisv10_cpu_exec_interrupt -- so you do need the new do_interrupt_locked
> field
> there.
>
>
> r~
>
>

[-- Attachment #2: Type: text/html, Size: 4493 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2020-08-31 23:45 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-19 18:28 [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Robert Foley
2020-08-19 18:28 ` [PATCH v2 1/7] target: rename all *_do_interupt functions to _do_interrupt_locked Robert Foley
2020-08-19 18:28   ` Robert Foley
2020-08-31 21:14   ` Richard Henderson
2020-08-31 21:14     ` Richard Henderson
2020-08-19 18:28 ` [PATCH v2 2/7] target/arm: add ARMCPUClass->do_interrupt_locked Robert Foley
2020-08-31 21:18   ` Richard Henderson
2020-08-31 22:02     ` Richard Henderson
2020-08-31 23:44       ` Philippe Mathieu-Daudé
2020-08-19 18:28 ` [PATCH v2 3/7] target/cris: add CRISCPUClass->do_interrupt_locked Robert Foley
2020-08-31 21:19   ` Richard Henderson
2020-08-19 18:28 ` [PATCH v2 4/7] target: Push BQL on ->do_interrupt down into per-arch implementation Robert Foley
2020-08-19 18:28   ` Robert Foley
2020-08-31 21:37   ` Richard Henderson
2020-08-31 21:37     ` Richard Henderson
2020-08-19 18:28 ` [PATCH v2 5/7] accel/tcg: Change BQL critical section in cpu_handle_interrupt Robert Foley
2020-08-31 21:44   ` Richard Henderson
2020-08-19 18:28 ` [PATCH v2 6/7] target: rename all *_cpu_exec_interrupt functions to *_cpu_exec_interrupt_locked Robert Foley
2020-08-19 18:28   ` Robert Foley
2020-08-31 21:46   ` Richard Henderson
2020-08-31 21:46     ` Richard Henderson
2020-08-19 18:28 ` [PATCH v2 7/7] target: Push BQL on ->cpu_exec_interrupt down into per-arch implementation Robert Foley
2020-08-19 18:28   ` Robert Foley
2020-08-31 22:11   ` Richard Henderson
2020-08-31 22:11     ` Richard Henderson
2020-08-21 10:55 ` [PATCH v2 0/7] accel/tcg: remove implied BQL from cpu_handle_interrupt/exception path Cornelia Huck
2020-08-27 12:38   ` Robert Foley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.