* [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt
@ 2026-08-19 14:56 Philippe Mathieu-Daudé
2026-08-19 14:56 ` [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp Philippe Mathieu-Daudé
` (11 more replies)
0 siblings, 12 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
This series was inspired by a previous thread on the list [*].
Refactor the CPU halt-to-execution transition logic in TCG as
something more explicit and composable.
Core problem: TCGCPUOps::cpu_exec_halt callback mixed concerns,
it checked for work, processed async events, and handled state
transitions all in one place.
Solution: introduces two dedicated callbacks:
* process_async_events(): Process target-specific async events
before checking for work. Called early in cpu_exec().
* transition_halt_to_exec(): Perform target-specific state updates
when transitioning from halt to execution.
This separation allows the generic cpu_exec() code to orchestrate
the flow cleanly (process events, check for work, transition state).
Only 2 targets need to be migrated (x86 and ARM) then we can remove
the redundant cpu_exec_halt() hook.
The changes are expected to be purely refactoring with no functional
impact.
Series structure:
Patches 1-2: Preparatory refactoring and guard additions
Patch 3: Introduce the new hooks and orchestration logic
Patch 4: Refactor cpu_exec() flow to use new infrastructure
Patches 5-7: x86 extraction and conversion
Patches 8-9: ARM extraction and conversion
Patch 10: Remove the now-redundant cpu_exec_halt hook
Testing: CI test suite
[*] https://lore.kernel.org/qemu-devel/CABgObfaDAhrpnVqQaKgG6uxPQe1YDu77YOsUEx9nqrN=3M2cGw@mail.gmail.com/
Philippe Mathieu-Daudé (11):
accel/tcg: Rename for exception codes named @ret as @excp
accel/tcg: Restrict EXCP_HALTED handling to system emulation
accel/tcg: Check %halted field in cpu_handle_halt() caller
accel/tcg: Refactor halt-to-execution flow in cpu_exec()
accel/tcg: Introduce .process_async_events and
.transition_halt_to_exec
target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt()
target/arm: Convert cpu_exec_halt() to transition_halt_to_exec()
target/i386: Extract async event processing out of x86_cpu_exec_halt()
target/i386: Extract halt-to-exec transition out of
x86_cpu_exec_halt()
target/i386: Convert cpu_exec_halt() to transition_halt_to_exec()
accel/tcg: Remove the now redundant cpu_exec_halt() hook
include/accel/tcg/cpu-ops.h | 30 +++++++-------
target/arm/internals.h | 3 --
target/i386/tcg/helper-tcg.h | 3 +-
accel/tcg/cpu-exec.c | 63 ++++++++++++++++-------------
accel/tcg/tcg-accel-ops-mttcg.c | 7 ++--
accel/tcg/tcg-accel-ops-rr.c | 8 ++--
accel/tcg/tcg-accel-ops.c | 7 ++--
target/alpha/cpu.c | 1 -
target/arm/cpu.c | 22 +++++-----
target/arm/tcg/cpu-v7m.c | 1 -
target/avr/cpu.c | 1 -
target/hexagon/cpu.c | 1 -
target/hppa/cpu.c | 1 -
target/i386/tcg/system/seg_helper.c | 14 ++++---
target/i386/tcg/tcg-cpu.c | 3 +-
target/loongarch/tcg/tcg_cpu.c | 1 -
target/m68k/cpu.c | 1 -
target/microblaze/cpu.c | 1 -
target/mips/cpu.c | 1 -
target/or1k/cpu.c | 1 -
target/ppc/cpu_init.c | 1 -
target/riscv/tcg/tcg-cpu.c | 1 -
target/rx/cpu.c | 1 -
target/s390x/cpu.c | 1 -
target/sh4/cpu.c | 1 -
target/sparc/cpu.c | 1 -
target/tricore/cpu.c | 1 -
target/xtensa/cpu.c | 1 -
28 files changed, 84 insertions(+), 94 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 19:55 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 02/11] accel/tcg: Restrict EXCP_HALTED handling to system emulation Philippe Mathieu-Daudé
` (10 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Rename meaningless @ret or @r variables as @excp to
directly denote the value is an exception. No logical
changes, purely cosmetic/clarity improvement.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
accel/tcg/cpu-exec.c | 24 ++++++++++++------------
accel/tcg/tcg-accel-ops-mttcg.c | 7 ++++---
accel/tcg/tcg-accel-ops-rr.c | 8 ++++----
accel/tcg/tcg-accel-ops.c | 7 ++++---
4 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 257211235db..53d90c400d5 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -687,7 +687,7 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
}
}
-static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
+static inline bool cpu_handle_exception(CPUState *cpu, int *excp)
{
if (cpu->exception_index < 0) {
#ifndef CONFIG_USER_ONLY
@@ -703,8 +703,8 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
if (cpu->exception_index >= EXCP_INTERRUPT) {
/* exit request from the cpu execution loop */
- *ret = cpu->exception_index;
- if (*ret == EXCP_DEBUG) {
+ *excp = cpu->exception_index;
+ if (*excp == EXCP_DEBUG) {
cpu_handle_debug_exception(cpu);
}
cpu->exception_index = -1;
@@ -720,7 +720,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
if (tcg_ops->fake_user_interrupt) {
tcg_ops->fake_user_interrupt(cpu);
}
- *ret = cpu->exception_index;
+ *excp = cpu->exception_index;
cpu->exception_index = -1;
return true;
#else
@@ -738,13 +738,13 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
* raised when single-stepping so that GDB doesn't miss the
* next instruction.
*/
- *ret = EXCP_DEBUG;
+ *excp = EXCP_DEBUG;
cpu_handle_debug_exception(cpu);
return true;
}
} else if (!replay_has_interrupt()) {
/* give a chance to iothread in replay mode */
- *ret = EXCP_INTERRUPT;
+ *excp = EXCP_INTERRUPT;
return true;
}
#endif
@@ -935,10 +935,10 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
static int __attribute__((noinline))
cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
{
- int ret;
+ int excp;
/* if an exception is pending, we execute it here */
- while (!cpu_handle_exception(cpu, &ret)) {
+ while (!cpu_handle_exception(cpu, &excp)) {
TranslationBlock *last_tb = NULL;
int tb_exit = 0;
@@ -1006,7 +1006,7 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
align_clocks(sc, cpu);
}
}
- return ret;
+ return excp;
}
static int cpu_exec_setjmp(CPUState *cpu, SyncClocks *sc)
@@ -1021,7 +1021,7 @@ static int cpu_exec_setjmp(CPUState *cpu, SyncClocks *sc)
int cpu_exec(CPUState *cpu)
{
- int ret;
+ int excp;
SyncClocks sc = { 0 };
/* replay_interrupt may need current_cpu */
@@ -1042,10 +1042,10 @@ int cpu_exec(CPUState *cpu)
*/
init_delay_params(&sc, cpu);
- ret = cpu_exec_setjmp(cpu, &sc);
+ excp = cpu_exec_setjmp(cpu, &sc);
cpu_exec_exit(cpu);
- return ret;
+ return excp;
}
bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
index 69560fdb9d8..e7edd1945f2 100644
--- a/accel/tcg/tcg-accel-ops-mttcg.c
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
@@ -90,11 +90,12 @@ static void *mttcg_cpu_thread_fn(void *arg)
qemu_process_cpu_events(cpu);
if (cpu_can_run(cpu)) {
- int r;
+ int excp;
+
bql_unlock();
- r = tcg_cpu_exec(cpu);
+ excp = tcg_cpu_exec(cpu);
bql_lock();
- switch (r) {
+ switch (excp) {
case EXCP_DEBUG:
cpu_handle_guest_debug(cpu);
break;
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
index cdaa3e11808..d6c2fc019c9 100644
--- a/accel/tcg/tcg-accel-ops-rr.c
+++ b/accel/tcg/tcg-accel-ops-rr.c
@@ -277,22 +277,22 @@ static void *rr_cpu_thread_fn(void *arg)
(cpu->singlestep_flags & SSTEP_NOTIMER) == 0);
if (cpu_can_run(cpu)) {
- int r;
+ int excp;
bql_unlock();
if (icount_enabled()) {
icount_prepare_for_run(cpu, cpu_budget);
}
- r = tcg_cpu_exec(cpu);
+ excp = tcg_cpu_exec(cpu);
if (icount_enabled()) {
icount_process_data(cpu);
}
bql_lock();
- if (r == EXCP_DEBUG) {
+ if (excp == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
break;
- } else if (r == EXCP_ATOMIC) {
+ } else if (excp == EXCP_ATOMIC) {
bql_unlock();
cpu_exec_step_atomic(cpu);
bql_lock();
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
index 560fe2554ba..9c3d2214162 100644
--- a/accel/tcg/tcg-accel-ops.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -77,13 +77,14 @@ void tcg_cpu_destroy(CPUState *cpu)
int tcg_cpu_exec(CPUState *cpu)
{
- int ret;
+ int excp;
+
assert(tcg_enabled());
cpu_exec_start(cpu);
- ret = cpu_exec(cpu);
+ excp = cpu_exec(cpu);
cpu_exec_end(cpu);
- return ret;
+ return excp;
}
static void tcg_cpu_reset_hold(CPUState *cpu)
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 02/11] accel/tcg: Restrict EXCP_HALTED handling to system emulation
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
2026-08-19 14:56 ` [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:01 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 03/11] accel/tcg: Check %halted field in cpu_handle_halt() caller Philippe Mathieu-Daudé
` (9 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
EXCP_HALTED is defined and documented in "exec/cpu-common.h" as:
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
Since vCPUs can not be halted in user-mode emulation, guard the
whole block within !CONFIG_USER_ONLY section. No logic changes.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
accel/tcg/cpu-exec.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 53d90c400d5..69207301d1d 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -653,9 +653,9 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
qemu_spin_unlock(&tb_next->jmp_lock);
}
+#ifndef CONFIG_USER_ONLY
static inline bool cpu_handle_halt(CPUState *cpu)
{
-#ifndef CONFIG_USER_ONLY
if (cpu->halted) {
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
bool leave_halt = tcg_ops->cpu_exec_halt(cpu);
@@ -666,10 +666,10 @@ static inline bool cpu_handle_halt(CPUState *cpu)
cpu->halted = 0;
}
-#endif /* !CONFIG_USER_ONLY */
return false;
}
+#endif /* !CONFIG_USER_ONLY */
static inline void cpu_handle_debug_exception(CPUState *cpu)
{
@@ -1027,9 +1027,11 @@ int cpu_exec(CPUState *cpu)
/* replay_interrupt may need current_cpu */
current_cpu = cpu;
+#ifndef CONFIG_USER_ONLY
if (cpu_handle_halt(cpu)) {
return EXCP_HALTED;
}
+#endif
RCU_READ_LOCK_GUARD();
cpu_exec_enter(cpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 03/11] accel/tcg: Check %halted field in cpu_handle_halt() caller
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
2026-08-19 14:56 ` [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp Philippe Mathieu-Daudé
2026-08-19 14:56 ` [PATCH 02/11] accel/tcg: Restrict EXCP_HALTED handling to system emulation Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:02 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 04/11] accel/tcg: Refactor halt-to-execution flow in cpu_exec() Philippe Mathieu-Daudé
` (8 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
In cpu_exec(), check CPUState::halted field early before
calling cpu_handle_halt(). The logic is the same but allow
to simplify the async event processing hooks that will be
added in the next commit.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
accel/tcg/cpu-exec.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 69207301d1d..46b723cb734 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -656,17 +656,15 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
#ifndef CONFIG_USER_ONLY
static inline bool cpu_handle_halt(CPUState *cpu)
{
- if (cpu->halted) {
- const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
- bool leave_halt = tcg_ops->cpu_exec_halt(cpu);
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
+ bool leave_halt = tcg_ops->cpu_exec_halt(cpu);
- if (!leave_halt) {
- return true;
- }
-
- cpu->halted = 0;
+ if (!leave_halt) {
+ return true;
}
+ cpu->halted = 0; /* allow execution */
+
return false;
}
#endif /* !CONFIG_USER_ONLY */
@@ -1028,8 +1026,11 @@ int cpu_exec(CPUState *cpu)
current_cpu = cpu;
#ifndef CONFIG_USER_ONLY
- if (cpu_handle_halt(cpu)) {
- return EXCP_HALTED;
+ if (cpu->halted) {
+ if (cpu_handle_halt(cpu)) {
+ return EXCP_HALTED;
+ }
+ assert(!cpu->halted);
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 04/11] accel/tcg: Refactor halt-to-execution flow in cpu_exec()
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 03/11] accel/tcg: Check %halted field in cpu_handle_halt() caller Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:03 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 05/11] accel/tcg: Introduce .process_async_events and .transition_halt_to_exec Philippe Mathieu-Daudé
` (7 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Invert cpu_handle_halt()'s logic to read in cpu_exec() as
"if halted, try to process async events and find work; if
no work, return".
Rename as cpu_has_work_after_processing_async_events().
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
accel/tcg/cpu-exec.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 46b723cb734..1a942664895 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -654,18 +654,18 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
}
#ifndef CONFIG_USER_ONLY
-static inline bool cpu_handle_halt(CPUState *cpu)
+static bool cpu_has_work_after_processing_async_events(CPUState *cpu)
{
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
bool leave_halt = tcg_ops->cpu_exec_halt(cpu);
if (!leave_halt) {
- return true;
+ return false;
}
cpu->halted = 0; /* allow execution */
- return false;
+ return true;
}
#endif /* !CONFIG_USER_ONLY */
@@ -1027,7 +1027,7 @@ int cpu_exec(CPUState *cpu)
#ifndef CONFIG_USER_ONLY
if (cpu->halted) {
- if (cpu_handle_halt(cpu)) {
+ if (!cpu_has_work_after_processing_async_events(cpu)) {
return EXCP_HALTED;
}
assert(!cpu->halted);
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 05/11] accel/tcg: Introduce .process_async_events and .transition_halt_to_exec
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 04/11] accel/tcg: Refactor halt-to-execution flow in cpu_exec() Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:06 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt() Philippe Mathieu-Daudé
` (6 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Decompose the halt-to-execution transition into distinct steps:
- process_async_events() called first to handle
target-specific asynchronous events,
- transition_halt_to_exec() called after a halted
CPU has detected pending work and is about to
resume execution.
Either callback is optional; targets that don't implement them
fall back to the existing cpu_exec_halt() callback for backward
compatibility.
cpu_has_work_after_processing_async_events() orchestrates these
callbacks: process async events, check for work, transition from
halt, and clear the halted flag.
Inspired-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
include/accel/tcg/cpu-ops.h | 17 ++++++++++++++++-
accel/tcg/cpu-exec.c | 21 +++++++++++++++++----
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/include/accel/tcg/cpu-ops.h b/include/accel/tcg/cpu-ops.h
index 3ff6e6810e0..16c19da997d 100644
--- a/include/accel/tcg/cpu-ops.h
+++ b/include/accel/tcg/cpu-ops.h
@@ -169,6 +169,20 @@ struct TCGCPUOps {
*/
vaddr (*untagged_addr)(CPUState *cs, vaddr addr);
#else
+ /**
+ * @process_async_events: Process target-specific asynchronous CPU events.
+ *
+ * Called at the start of cpu_exec() to handle target-specific event
+ * processing before instruction execution begins.
+ */
+ void (*process_async_events)(CPUState *cpu);
+ /**
+ * @transition_halt_to_exec: Prepare CPU state when exiting halt.
+ *
+ * Called after a halted CPU has detected pending work and is about to
+ * resume execution. Target-specific cleanup and state synchronization.
+ */
+ void (*transition_halt_to_exec)(CPUState *cpu);
/** @do_interrupt: Callback for interrupt handling. */
void (*do_interrupt)(CPUState *cpu);
/** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
@@ -185,7 +199,8 @@ struct TCGCPUOps {
* if it should remain in the halted state. (This should generally
* be the same value that cpu_has_work() would return.)
*
- * This method must be provided. If the target does not need to
+ * Either %transition_halt_to_exec() or this method must be provided.
+ * If the target does not need to
* do anything special for halt, the same function used for its
* SysemuCPUOps::has_work method can be used here, as they have the
* same function signature.
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 1a942664895..54561ed31c1 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -48,6 +48,7 @@
#include "internal-common.h"
#if !defined(CONFIG_USER_ONLY)
#include "accel/tcg/iommu.h"
+#include "hw/core/sysemu-cpu-ops.h"
#endif
/* -icount align implementation. */
@@ -657,10 +658,22 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
static bool cpu_has_work_after_processing_async_events(CPUState *cpu)
{
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
- bool leave_halt = tcg_ops->cpu_exec_halt(cpu);
- if (!leave_halt) {
- return false;
+ if (tcg_ops->transition_halt_to_exec) {
+ assert(!tcg_ops->cpu_exec_halt);
+ if (tcg_ops->process_async_events) {
+ tcg_ops->process_async_events(cpu);
+ }
+ if (!cpu_has_work(cpu)) {
+ return false;
+ }
+ tcg_ops->transition_halt_to_exec(cpu);
+ } else {
+ assert(!tcg_ops->process_async_events);
+ assert(cpu->cc->sysemu_ops->has_work == tcg_ops->cpu_exec_halt);
+ if (!tcg_ops->cpu_exec_halt(cpu)) {
+ return false;
+ }
}
cpu->halted = 0; /* allow execution */
@@ -1059,7 +1072,7 @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
/* Check mandatory TCGCPUOps handlers */
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
#ifndef CONFIG_USER_ONLY
- assert(tcg_ops->cpu_exec_halt);
+ assert(tcg_ops->cpu_exec_halt || tcg_ops->transition_halt_to_exec);
assert(tcg_ops->cpu_exec_interrupt);
assert(tcg_ops->cpu_exec_reset);
assert(tcg_ops->pointer_wrap);
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt()
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 05/11] accel/tcg: Introduce .process_async_events and .transition_halt_to_exec Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:13 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 07/11] target/arm: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
` (5 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Refactor the target-specific halt-to-execution transition
logic (disable WFE/WFI timers, clear the halt_reason flag)
into a separate arm_cpu_transition_halt_to_exec() function.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
target/arm/cpu.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 77aa78f00e2..8e9b584559d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -870,18 +870,26 @@ static bool arm_cpu_internal_is_big_endian(CPUState *cs)
}
#ifdef CONFIG_TCG
+static void arm_cpu_transition_halt_to_exec(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+
+ assert(cpu_has_work(cs));
+
+ /* We're about to come out of WFI/WFE: disable the WFxT timer */
+ if (cpu->wfxt_timer) {
+ timer_del(cpu->wfxt_timer);
+ }
+ /* clear the halt reason */
+ cpu->env.halt_reason = NOT_HALTED;
+}
+
bool arm_cpu_exec_halt(CPUState *cs)
{
bool leave_halt = cpu_has_work(cs);
if (leave_halt) {
- /* We're about to come out of WFI/WFE: disable the WFxT timer */
- ARMCPU *cpu = ARM_CPU(cs);
- if (cpu->wfxt_timer) {
- timer_del(cpu->wfxt_timer);
- }
- /* clear the halt reason */
- cpu->env.halt_reason = NOT_HALTED;
+ arm_cpu_transition_halt_to_exec(cs);
}
return leave_halt;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 07/11] target/arm: Convert cpu_exec_halt() to transition_halt_to_exec()
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt() Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:15 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 08/11] target/i386: Extract async event processing out of x86_cpu_exec_halt() Philippe Mathieu-Daudé
` (4 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
arm_cpu_exec_halt() now merely checks cpu_has_work() and
conditionally call arm_cpu_transition_halt_to_exec(), which is now
the generic flow in cpu_has_work_after_processing_async_events().
Register the transition_halt_to_exec handler to use the generic
target-agnostic flow and remove the arm_cpu_exec_halt() wrapper.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
target/arm/internals.h | 3 ---
target/arm/cpu.c | 12 +-----------
target/arm/tcg/cpu-v7m.c | 1 -
3 files changed, 1 insertion(+), 15 deletions(-)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 4026f67579e..8a9ee04e72e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -431,9 +431,6 @@ void arm_restore_state_to_opc(CPUState *cs,
#ifdef CONFIG_TCG
TCGTBCPUState arm_get_tb_cpu_state(CPUState *cs);
void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
-
-/* Our implementation of TCGCPUOps::cpu_exec_halt */
-bool arm_cpu_exec_halt(CPUState *cs);
int arm_cpu_mmu_index(CPUState *cs, bool ifetch);
#endif /* CONFIG_TCG */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 8e9b584559d..22fae41125f 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -883,16 +883,6 @@ static void arm_cpu_transition_halt_to_exec(CPUState *cs)
/* clear the halt reason */
cpu->env.halt_reason = NOT_HALTED;
}
-
-bool arm_cpu_exec_halt(CPUState *cs)
-{
- bool leave_halt = cpu_has_work(cs);
-
- if (leave_halt) {
- arm_cpu_transition_halt_to_exec(cs);
- }
- return leave_halt;
-}
#endif
/*
@@ -2612,7 +2602,7 @@ static const TCGCPUOps arm_tcg_ops = {
.tlb_fill_align = arm_cpu_tlb_fill_align,
.pointer_wrap = aprofile_pointer_wrap,
.cpu_exec_interrupt = arm_cpu_exec_interrupt,
- .cpu_exec_halt = arm_cpu_exec_halt,
+ .transition_halt_to_exec = arm_cpu_transition_halt_to_exec,
.cpu_exec_reset = cpu_reset,
.do_interrupt = arm_cpu_do_interrupt,
.do_transaction_failed = arm_cpu_do_transaction_failed,
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index dc249ce1f14..e30eb8cc52a 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -257,7 +257,6 @@ static const TCGCPUOps arm_v7m_tcg_ops = {
.tlb_fill_align = arm_cpu_tlb_fill_align,
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
- .cpu_exec_halt = arm_cpu_exec_halt,
.cpu_exec_reset = cpu_reset,
.do_interrupt = arm_v7m_cpu_do_interrupt,
.do_transaction_failed = arm_cpu_do_transaction_failed,
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 08/11] target/i386: Extract async event processing out of x86_cpu_exec_halt()
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (6 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 07/11] target/arm: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:16 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 09/11] target/i386: Extract halt-to-exec transition " Philippe Mathieu-Daudé
` (3 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Refactor the target-specific async event processing logic (APIC
polling) into a separate x86_cpu_process_async_events() function.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
target/i386/tcg/helper-tcg.h | 1 +
target/i386/tcg/system/seg_helper.c | 11 +++++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index f4b2ff740d5..cab197368b9 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -37,6 +37,7 @@
*/
void x86_cpu_do_interrupt(CPUState *cpu);
#ifndef CONFIG_USER_ONLY
+void x86_cpu_process_async_events(CPUState *cpu);
bool x86_cpu_exec_halt(CPUState *cpu);
bool x86_need_replay_interrupt(int interrupt_request);
bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
diff --git a/target/i386/tcg/system/seg_helper.c b/target/i386/tcg/system/seg_helper.c
index 8c7856be81e..4856a6b3bab 100644
--- a/target/i386/tcg/system/seg_helper.c
+++ b/target/i386/tcg/system/seg_helper.c
@@ -128,10 +128,9 @@ void x86_cpu_do_interrupt(CPUState *cs)
}
}
-bool x86_cpu_exec_halt(CPUState *cpu)
+void x86_cpu_process_async_events(CPUState *cpu)
{
X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
if (cpu_test_interrupt(cpu, CPU_INTERRUPT_POLL)) {
bql_lock();
@@ -139,6 +138,14 @@ bool x86_cpu_exec_halt(CPUState *cpu)
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
bql_unlock();
}
+}
+
+bool x86_cpu_exec_halt(CPUState *cpu)
+{
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+
+ x86_cpu_process_async_events(cpu);
if (!cpu_has_work(cpu)) {
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 09/11] target/i386: Extract halt-to-exec transition out of x86_cpu_exec_halt()
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (7 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 08/11] target/i386: Extract async event processing out of x86_cpu_exec_halt() Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:17 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
` (2 subsequent siblings)
11 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Refactor the halt-to-execution target-specific transition logic
(setting trap flag in debug register and injecting debug exceptions)
into a separate x86_cpu_transition_halt_to_exec() function.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
target/i386/tcg/helper-tcg.h | 1 +
target/i386/tcg/system/seg_helper.c | 20 +++++++++++++-------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index cab197368b9..65819670493 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -39,6 +39,7 @@ void x86_cpu_do_interrupt(CPUState *cpu);
#ifndef CONFIG_USER_ONLY
void x86_cpu_process_async_events(CPUState *cpu);
bool x86_cpu_exec_halt(CPUState *cpu);
+void x86_cpu_transition_halt_to_exec(CPUState *cpu);
bool x86_need_replay_interrupt(int interrupt_request);
bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
#endif
diff --git a/target/i386/tcg/system/seg_helper.c b/target/i386/tcg/system/seg_helper.c
index 4856a6b3bab..9b2adcca76c 100644
--- a/target/i386/tcg/system/seg_helper.c
+++ b/target/i386/tcg/system/seg_helper.c
@@ -140,22 +140,28 @@ void x86_cpu_process_async_events(CPUState *cpu)
}
}
-bool x86_cpu_exec_halt(CPUState *cpu)
+void x86_cpu_transition_halt_to_exec(CPUState *cpu)
{
X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
+ CPUX86State *env = cpu_env(cpu);
- x86_cpu_process_async_events(cpu);
-
- if (!cpu_has_work(cpu)) {
- return false;
- }
+ assert(cpu_has_work(cpu));
/* Complete HLT instruction. */
if (env->eflags & TF_MASK) {
env->dr[6] |= DR6_BS;
do_interrupt_all(x86_cpu, EXCP01_DB, 0, 0, env->eip, 0);
}
+}
+
+bool x86_cpu_exec_halt(CPUState *cpu)
+{
+ if (!cpu_has_work(cpu)) {
+ return false;
+ }
+
+ x86_cpu_transition_halt_to_exec(cpu);
+
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec()
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (8 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 09/11] target/i386: Extract halt-to-exec transition " Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 20:18 ` Richard Henderson
2026-08-19 20:19 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook Philippe Mathieu-Daudé
2026-08-20 9:26 ` [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Mark Cave-Ayland
11 siblings, 2 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
x86_cpu_exec_halt() now merely checks cpu_has_work() and
conditionally call x86_cpu_transition_halt_to_exec(), which is now
the generic flow in cpu_has_work_after_processing_async_events().
Register both process_async_events and transition_halt_to_exec
handlers to use the generic target-agnostic flow, and remove the
x86_cpu_exec_halt() wrapper.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
target/i386/tcg/helper-tcg.h | 1 -
target/i386/tcg/system/seg_helper.c | 11 -----------
target/i386/tcg/tcg-cpu.c | 3 ++-
3 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 65819670493..d224cb3c1c7 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -38,7 +38,6 @@
void x86_cpu_do_interrupt(CPUState *cpu);
#ifndef CONFIG_USER_ONLY
void x86_cpu_process_async_events(CPUState *cpu);
-bool x86_cpu_exec_halt(CPUState *cpu);
void x86_cpu_transition_halt_to_exec(CPUState *cpu);
bool x86_need_replay_interrupt(int interrupt_request);
bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
diff --git a/target/i386/tcg/system/seg_helper.c b/target/i386/tcg/system/seg_helper.c
index 9b2adcca76c..7a3f14a255e 100644
--- a/target/i386/tcg/system/seg_helper.c
+++ b/target/i386/tcg/system/seg_helper.c
@@ -154,17 +154,6 @@ void x86_cpu_transition_halt_to_exec(CPUState *cpu)
}
}
-bool x86_cpu_exec_halt(CPUState *cpu)
-{
- if (!cpu_has_work(cpu)) {
- return false;
- }
-
- x86_cpu_transition_halt_to_exec(cpu);
-
- return true;
-}
-
bool x86_need_replay_interrupt(int interrupt_request)
{
/*
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index 6f5dc06b3b9..e4fc212aca5 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -180,7 +180,8 @@ const TCGCPUOps x86_tcg_ops = {
.tlb_fill = x86_cpu_tlb_fill,
.pointer_wrap = x86_pointer_wrap,
.do_interrupt = x86_cpu_do_interrupt,
- .cpu_exec_halt = x86_cpu_exec_halt,
+ .process_async_events = x86_cpu_process_async_events,
+ .transition_halt_to_exec = x86_cpu_transition_halt_to_exec,
.cpu_exec_interrupt = x86_cpu_exec_interrupt,
.cpu_exec_reset = x86_cpu_exec_reset,
.do_unaligned_access = x86_cpu_do_unaligned_access,
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (9 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
@ 2026-08-19 14:56 ` Philippe Mathieu-Daudé
2026-08-19 15:05 ` Philippe Mathieu-Daudé
2026-08-19 20:20 ` Richard Henderson
2026-08-20 9:26 ` [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Mark Cave-Ayland
11 siblings, 2 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 14:56 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Every target setting the cpu_exec_halt callback alias it to
their cpu_has_work() function, making the callback redundant.
Call cpu_has_work() directly in accel/tcg/cpu-exec.c
cpu_has_work_after_processing_async_events() and remove the
boilerplate cpu_exec_halt hook registration. No functional
impact expected.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
include/accel/tcg/cpu-ops.h | 17 -----------------
accel/tcg/cpu-exec.c | 23 ++++++++---------------
target/alpha/cpu.c | 1 -
target/avr/cpu.c | 1 -
target/hexagon/cpu.c | 1 -
target/hppa/cpu.c | 1 -
target/loongarch/tcg/tcg_cpu.c | 1 -
target/m68k/cpu.c | 1 -
target/microblaze/cpu.c | 1 -
target/mips/cpu.c | 1 -
target/or1k/cpu.c | 1 -
target/ppc/cpu_init.c | 1 -
target/riscv/tcg/tcg-cpu.c | 1 -
target/rx/cpu.c | 1 -
target/s390x/cpu.c | 1 -
target/sh4/cpu.c | 1 -
target/sparc/cpu.c | 1 -
target/tricore/cpu.c | 1 -
target/xtensa/cpu.c | 1 -
19 files changed, 8 insertions(+), 49 deletions(-)
diff --git a/include/accel/tcg/cpu-ops.h b/include/accel/tcg/cpu-ops.h
index 16c19da997d..a88cc4dc572 100644
--- a/include/accel/tcg/cpu-ops.h
+++ b/include/accel/tcg/cpu-ops.h
@@ -189,23 +189,6 @@ struct TCGCPUOps {
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
/** @cpu_exec_reset: Callback for reset in cpu_exec. */
void (*cpu_exec_reset)(CPUState *cpu);
- /**
- * @cpu_exec_halt: Callback for handling halt in cpu_exec.
- *
- * The target CPU should do any special processing here that it needs
- * to do when the CPU is in the halted state.
- *
- * Return true to indicate that the CPU should now leave halt, false
- * if it should remain in the halted state. (This should generally
- * be the same value that cpu_has_work() would return.)
- *
- * Either %transition_halt_to_exec() or this method must be provided.
- * If the target does not need to
- * do anything special for halt, the same function used for its
- * SysemuCPUOps::has_work method can be used here, as they have the
- * same function signature.
- */
- bool (*cpu_exec_halt)(CPUState *cpu);
/**
* @tlb_fill_align: Handle a softmmu tlb miss
* @cpu: cpu context
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 54561ed31c1..bfdc42ab6a0 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -48,7 +48,6 @@
#include "internal-common.h"
#if !defined(CONFIG_USER_ONLY)
#include "accel/tcg/iommu.h"
-#include "hw/core/sysemu-cpu-ops.h"
#endif
/* -icount align implementation. */
@@ -659,21 +658,16 @@ static bool cpu_has_work_after_processing_async_events(CPUState *cpu)
{
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
+ if (tcg_ops->process_async_events) {
+ tcg_ops->process_async_events(cpu);
+ }
+
+ if (!cpu_has_work(cpu)) {
+ return false;
+ }
+
if (tcg_ops->transition_halt_to_exec) {
- assert(!tcg_ops->cpu_exec_halt);
- if (tcg_ops->process_async_events) {
- tcg_ops->process_async_events(cpu);
- }
- if (!cpu_has_work(cpu)) {
- return false;
- }
tcg_ops->transition_halt_to_exec(cpu);
- } else {
- assert(!tcg_ops->process_async_events);
- assert(cpu->cc->sysemu_ops->has_work == tcg_ops->cpu_exec_halt);
- if (!tcg_ops->cpu_exec_halt(cpu)) {
- return false;
- }
}
cpu->halted = 0; /* allow execution */
@@ -1072,7 +1066,6 @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
/* Check mandatory TCGCPUOps handlers */
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
#ifndef CONFIG_USER_ONLY
- assert(tcg_ops->cpu_exec_halt || tcg_ops->transition_halt_to_exec);
assert(tcg_ops->cpu_exec_interrupt);
assert(tcg_ops->cpu_exec_reset);
assert(tcg_ops->pointer_wrap);
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 12e86021663..7d1d036e1d3 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -265,7 +265,6 @@ static const TCGCPUOps alpha_tcg_ops = {
.tlb_fill = alpha_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_notreached,
.cpu_exec_interrupt = alpha_cpu_exec_interrupt,
- .cpu_exec_halt = alpha_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = alpha_cpu_do_interrupt,
.do_transaction_failed = alpha_cpu_do_transaction_failed,
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index f8409f32ab9..a01e6fa4751 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -246,7 +246,6 @@ static const TCGCPUOps avr_tcg_ops = {
.restore_state_to_opc = avr_restore_state_to_opc,
.mmu_index = avr_cpu_mmu_index,
.cpu_exec_interrupt = avr_cpu_exec_interrupt,
- .cpu_exec_halt = avr_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.tlb_fill = avr_cpu_tlb_fill,
.do_interrupt = avr_cpu_do_interrupt,
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 7067e5b70f7..9765716b516 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -768,7 +768,6 @@ static const TCGCPUOps hexagon_tcg_ops = {
.cpu_exec_reset = cpu_reset,
.tlb_fill = hexagon_tlb_fill,
.do_unaligned_access = hexagon_cpu_do_unaligned_access,
- .cpu_exec_halt = hexagon_cpu_has_work,
.do_interrupt = hexagon_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */
};
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 07b49e51326..7b1309a7c38 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -270,7 +270,6 @@ static const TCGCPUOps hppa_tcg_ops = {
.tlb_fill_align = hppa_cpu_tlb_fill_align,
.pointer_wrap = cpu_pointer_wrap_notreached,
.cpu_exec_interrupt = hppa_cpu_exec_interrupt,
- .cpu_exec_halt = hppa_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = hppa_cpu_do_interrupt,
.do_unaligned_access = hppa_cpu_do_unaligned_access,
diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c
index 4b1d44a1644..7ea2a1eb933 100644
--- a/target/loongarch/tcg/tcg_cpu.c
+++ b/target/loongarch/tcg/tcg_cpu.c
@@ -327,7 +327,6 @@ const TCGCPUOps loongarch_tcg_ops = {
.tlb_fill = loongarch_cpu_tlb_fill,
.pointer_wrap = loongarch_pointer_wrap,
.cpu_exec_interrupt = loongarch_cpu_exec_interrupt,
- .cpu_exec_halt = loongarch_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = loongarch_cpu_do_interrupt,
.do_transaction_failed = loongarch_cpu_do_transaction_failed,
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index ce2707dee5a..f349013ad41 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -643,7 +643,6 @@ static const TCGCPUOps m68k_tcg_ops = {
.tlb_fill = m68k_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = m68k_cpu_exec_interrupt,
- .cpu_exec_halt = m68k_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = m68k_cpu_do_interrupt,
.do_transaction_failed = m68k_cpu_transaction_failed,
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 389a5124b12..6013a8def8e 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -448,7 +448,6 @@ static const TCGCPUOps mb_tcg_ops = {
.tlb_fill = mb_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = mb_cpu_exec_interrupt,
- .cpu_exec_halt = mb_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = mb_cpu_do_interrupt,
.do_transaction_failed = mb_cpu_transaction_failed,
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 669c7d99bb7..cebc2283599 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -664,7 +664,6 @@ static const TCGCPUOps mips_tcg_ops = {
.tlb_fill = mips_cpu_tlb_fill,
.pointer_wrap = mips_pointer_wrap,
.cpu_exec_interrupt = mips_cpu_exec_interrupt,
- .cpu_exec_halt = mips_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = mips_cpu_do_interrupt,
.do_transaction_failed = mips_cpu_do_transaction_failed,
diff --git a/target/or1k/cpu.c b/target/or1k/cpu.c
index 66c00c0930c..42d9351b6d7 100644
--- a/target/or1k/cpu.c
+++ b/target/or1k/cpu.c
@@ -266,7 +266,6 @@ static const TCGCPUOps openrisc_tcg_ops = {
.tlb_fill = openrisc_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
- .cpu_exec_halt = openrisc_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = openrisc_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index e3a1075aad3..85a91ff4bb6 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7498,7 +7498,6 @@ static const TCGCPUOps ppc_tcg_ops = {
.tlb_fill = ppc_cpu_tlb_fill,
.pointer_wrap = ppc_pointer_wrap,
.cpu_exec_interrupt = ppc_cpu_exec_interrupt,
- .cpu_exec_halt = ppc_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = ppc_cpu_do_interrupt,
.cpu_exec_enter = ppc_cpu_exec_enter,
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 9e3cc87f8a3..cd303660f1f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -287,7 +287,6 @@ const TCGCPUOps riscv_tcg_ops = {
.tlb_fill = riscv_cpu_tlb_fill,
.pointer_wrap = riscv_pointer_wrap,
.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
- .cpu_exec_halt = riscv_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = riscv_cpu_do_interrupt,
.do_transaction_failed = riscv_cpu_do_transaction_failed,
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 9b8473d71cf..69946928995 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -227,7 +227,6 @@ static const TCGCPUOps rx_tcg_ops = {
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = rx_cpu_exec_interrupt,
- .cpu_exec_halt = rx_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = rx_cpu_do_interrupt,
};
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 641ea96c8ea..efbfb072bbf 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -382,7 +382,6 @@ static const TCGCPUOps s390_tcg_ops = {
.tlb_fill = s390_cpu_tlb_fill,
.pointer_wrap = s390_pointer_wrap,
.cpu_exec_interrupt = s390_cpu_exec_interrupt,
- .cpu_exec_halt = s390_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = s390_cpu_do_interrupt,
.debug_excp_handler = s390x_cpu_debug_excp_handler,
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index ad2ec28c1b7..8d53e11006d 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -298,7 +298,6 @@ static const TCGCPUOps superh_tcg_ops = {
.tlb_fill = superh_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_notreached,
.cpu_exec_interrupt = superh_cpu_exec_interrupt,
- .cpu_exec_halt = superh_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = superh_cpu_do_interrupt,
.do_unaligned_access = superh_cpu_do_unaligned_access,
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 1bc14b586bb..2baa5036871 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -1073,7 +1073,6 @@ static const TCGCPUOps sparc_tcg_ops = {
.tlb_fill = sparc_cpu_tlb_fill,
.pointer_wrap = sparc_pointer_wrap,
.cpu_exec_interrupt = sparc_cpu_exec_interrupt,
- .cpu_exec_halt = sparc_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = sparc_cpu_do_interrupt,
.do_transaction_failed = sparc_cpu_do_transaction_failed,
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index 96e2817dee7..f79d6fe5d5d 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -192,7 +192,6 @@ static const TCGCPUOps tricore_tcg_ops = {
.tlb_fill = tricore_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = tricore_cpu_exec_interrupt,
- .cpu_exec_halt = tricore_cpu_has_work,
.cpu_exec_reset = cpu_reset,
};
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 7c25b9ab707..99c8bd4b5fb 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -325,7 +325,6 @@ static const TCGCPUOps xtensa_tcg_ops = {
.tlb_fill = xtensa_cpu_tlb_fill,
.pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
- .cpu_exec_halt = xtensa_cpu_has_work,
.cpu_exec_reset = cpu_reset,
.do_interrupt = xtensa_cpu_do_interrupt,
.do_transaction_failed = xtensa_cpu_do_transaction_failed,
--
2.53.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook
2026-08-19 14:56 ` [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook Philippe Mathieu-Daudé
@ 2026-08-19 15:05 ` Philippe Mathieu-Daudé
2026-08-19 20:20 ` Richard Henderson
1 sibling, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-19 15:05 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
On 19/8/26 16:56, Philippe Mathieu-Daudé wrote:
> Every target setting the cpu_exec_halt callback alias it to
> their cpu_has_work() function, making the callback redundant.
>
> Call cpu_has_work() directly in accel/tcg/cpu-exec.c
> cpu_has_work_after_processing_async_events() and remove the
> boilerplate cpu_exec_halt hook registration. No functional
> impact expected.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> include/accel/tcg/cpu-ops.h | 17 -----------------
> accel/tcg/cpu-exec.c | 23 ++++++++---------------
> target/alpha/cpu.c | 1 -
> target/avr/cpu.c | 1 -
> target/hexagon/cpu.c | 1 -
> target/hppa/cpu.c | 1 -
> target/loongarch/tcg/tcg_cpu.c | 1 -
> target/m68k/cpu.c | 1 -
> target/microblaze/cpu.c | 1 -
> target/mips/cpu.c | 1 -
> target/or1k/cpu.c | 1 -
> target/ppc/cpu_init.c | 1 -
> target/riscv/tcg/tcg-cpu.c | 1 -
> target/rx/cpu.c | 1 -
> target/s390x/cpu.c | 1 -
> target/sh4/cpu.c | 1 -
> target/sparc/cpu.c | 1 -
> target/tricore/cpu.c | 1 -
> target/xtensa/cpu.c | 1 -
> 19 files changed, 8 insertions(+), 49 deletions(-)
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 54561ed31c1..bfdc42ab6a0 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -48,7 +48,6 @@
> #include "internal-common.h"
> #if !defined(CONFIG_USER_ONLY)
> #include "accel/tcg/iommu.h"
> -#include "hw/core/sysemu-cpu-ops.h"
> #endif
>
> /* -icount align implementation. */
> @@ -659,21 +658,16 @@ static bool cpu_has_work_after_processing_async_events(CPUState *cpu)
> {
> const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
>
> + if (tcg_ops->process_async_events) {
> + tcg_ops->process_async_events(cpu);
> + }
> +
> + if (!cpu_has_work(cpu)) {
> + return false;
> + }
> +
> if (tcg_ops->transition_halt_to_exec) {
> - assert(!tcg_ops->cpu_exec_halt);
> - if (tcg_ops->process_async_events) {
> - tcg_ops->process_async_events(cpu);
> - }
> - if (!cpu_has_work(cpu)) {
> - return false;
> - }
> tcg_ops->transition_halt_to_exec(cpu);
> - } else {
> - assert(!tcg_ops->process_async_events);
> - assert(cpu->cc->sysemu_ops->has_work == tcg_ops->cpu_exec_halt);
> - if (!tcg_ops->cpu_exec_halt(cpu)) {
> - return false;
> - }
> }
Hmm maybe I should squash:
-- >8 --
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 22fae41125f..9761bb173c1 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -874,8 +874,6 @@ static void arm_cpu_transition_halt_to_exec(CPUState
*cs)
{
ARMCPU *cpu = ARM_CPU(cs);
- assert(cpu_has_work(cs));
-
/* We're about to come out of WFI/WFE: disable the WFxT timer */
if (cpu->wfxt_timer) {
timer_del(cpu->wfxt_timer);
diff --git a/target/i386/tcg/system/seg_helper.c
b/target/i386/tcg/system/seg_helper.c
index 7a3f14a255e..cbea6bebeb5 100644
--- a/target/i386/tcg/system/seg_helper.c
+++ b/target/i386/tcg/system/seg_helper.c
@@ -145,8 +145,6 @@ void x86_cpu_transition_halt_to_exec(CPUState *cpu)
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = cpu_env(cpu);
- assert(cpu_has_work(cpu));
-
/* Complete HLT instruction. */
if (env->eflags & TF_MASK) {
env->dr[6] |= DR6_BS;
---
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp
2026-08-19 14:56 ` [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp Philippe Mathieu-Daudé
@ 2026-08-19 19:55 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 19:55 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Rename meaningless @ret or @r variables as @excp to
> directly denote the value is an exception. No logical
> changes, purely cosmetic/clarity improvement.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> accel/tcg/cpu-exec.c | 24 ++++++++++++------------
> accel/tcg/tcg-accel-ops-mttcg.c | 7 ++++---
> accel/tcg/tcg-accel-ops-rr.c | 8 ++++----
> accel/tcg/tcg-accel-ops.c | 7 ++++---
> 4 files changed, 24 insertions(+), 22 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 02/11] accel/tcg: Restrict EXCP_HALTED handling to system emulation
2026-08-19 14:56 ` [PATCH 02/11] accel/tcg: Restrict EXCP_HALTED handling to system emulation Philippe Mathieu-Daudé
@ 2026-08-19 20:01 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:01 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> EXCP_HALTED is defined and documented in "exec/cpu-common.h" as:
>
> #define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
>
> Since vCPUs can not be halted in user-mode emulation, guard the
> whole block within !CONFIG_USER_ONLY section. No logic changes.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> accel/tcg/cpu-exec.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 03/11] accel/tcg: Check %halted field in cpu_handle_halt() caller
2026-08-19 14:56 ` [PATCH 03/11] accel/tcg: Check %halted field in cpu_handle_halt() caller Philippe Mathieu-Daudé
@ 2026-08-19 20:02 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:02 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> In cpu_exec(), checkCPUState::halted field early before
> calling cpu_handle_halt(). The logic is the same but allow
> to simplify the async event processing hooks that will be
> added in the next commit.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> accel/tcg/cpu-exec.c | 21 +++++++++++----------
> 1 file changed, 11 insertions(+), 10 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 04/11] accel/tcg: Refactor halt-to-execution flow in cpu_exec()
2026-08-19 14:56 ` [PATCH 04/11] accel/tcg: Refactor halt-to-execution flow in cpu_exec() Philippe Mathieu-Daudé
@ 2026-08-19 20:03 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:03 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Invert cpu_handle_halt()'s logic to read in cpu_exec() as
> "if halted, try to process async events and find work; if
> no work, return".
> Rename as cpu_has_work_after_processing_async_events().
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> accel/tcg/cpu-exec.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 05/11] accel/tcg: Introduce .process_async_events and .transition_halt_to_exec
2026-08-19 14:56 ` [PATCH 05/11] accel/tcg: Introduce .process_async_events and .transition_halt_to_exec Philippe Mathieu-Daudé
@ 2026-08-19 20:06 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:06 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Decompose the halt-to-execution transition into distinct steps:
>
> - process_async_events() called first to handle
> target-specific asynchronous events,
>
> - transition_halt_to_exec() called after a halted
> CPU has detected pending work and is about to
> resume execution.
>
> Either callback is optional; targets that don't implement them
> fall back to the existing cpu_exec_halt() callback for backward
> compatibility.
>
> cpu_has_work_after_processing_async_events() orchestrates these
> callbacks: process async events, check for work, transition from
> halt, and clear the halted flag.
>
> Inspired-by: Paolo Bonzini<pbonzini@redhat.com>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> include/accel/tcg/cpu-ops.h | 17 ++++++++++++++++-
> accel/tcg/cpu-exec.c | 21 +++++++++++++++++----
> 2 files changed, 33 insertions(+), 5 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt()
2026-08-19 14:56 ` [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt() Philippe Mathieu-Daudé
@ 2026-08-19 20:13 ` Richard Henderson
2026-08-19 21:40 ` Peter Maydell
0 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:13 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Refactor the target-specific halt-to-execution transition
> logic (disable WFE/WFI timers, clear the halt_reason flag)
> into a separate arm_cpu_transition_halt_to_exec() function.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> target/arm/cpu.c | 22 +++++++++++++++-------
> 1 file changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 77aa78f00e2..8e9b584559d 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -870,18 +870,26 @@ static bool arm_cpu_internal_is_big_endian(CPUState *cs)
> }
>
> #ifdef CONFIG_TCG
> +static void arm_cpu_transition_halt_to_exec(CPUState *cs)
> +{
> + ARMCPU *cpu = ARM_CPU(cs);
> +
> + assert(cpu_has_work(cs));
In reply to patch 11 you suggest removing this.
I wonder why you added it in the first place.
Anyway,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
> +
> + /* We're about to come out of WFI/WFE: disable the WFxT timer */
> + if (cpu->wfxt_timer) {
> + timer_del(cpu->wfxt_timer);
> + }
> + /* clear the halt reason */
> + cpu->env.halt_reason = NOT_HALTED;
> +}
> +
> bool arm_cpu_exec_halt(CPUState *cs)
> {
> bool leave_halt = cpu_has_work(cs);
>
> if (leave_halt) {
> - /* We're about to come out of WFI/WFE: disable the WFxT timer */
> - ARMCPU *cpu = ARM_CPU(cs);
> - if (cpu->wfxt_timer) {
> - timer_del(cpu->wfxt_timer);
> - }
> - /* clear the halt reason */
> - cpu->env.halt_reason = NOT_HALTED;
> + arm_cpu_transition_halt_to_exec(cs);
> }
> return leave_halt;
> }
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 07/11] target/arm: Convert cpu_exec_halt() to transition_halt_to_exec()
2026-08-19 14:56 ` [PATCH 07/11] target/arm: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
@ 2026-08-19 20:15 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:15 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> arm_cpu_exec_halt() now merely checks cpu_has_work() and
> conditionally call arm_cpu_transition_halt_to_exec(), which is now
> the generic flow in cpu_has_work_after_processing_async_events().
>
> Register the transition_halt_to_exec handler to use the generic
> target-agnostic flow and remove the arm_cpu_exec_halt() wrapper.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> target/arm/internals.h | 3 ---
> target/arm/cpu.c | 12 +-----------
> target/arm/tcg/cpu-v7m.c | 1 -
> 3 files changed, 1 insertion(+), 15 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/11] target/i386: Extract async event processing out of x86_cpu_exec_halt()
2026-08-19 14:56 ` [PATCH 08/11] target/i386: Extract async event processing out of x86_cpu_exec_halt() Philippe Mathieu-Daudé
@ 2026-08-19 20:16 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:16 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Refactor the target-specific async event processing logic (APIC
> polling) into a separate x86_cpu_process_async_events() function.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> target/i386/tcg/helper-tcg.h | 1 +
> target/i386/tcg/system/seg_helper.c | 11 +++++++++--
> 2 files changed, 10 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/11] target/i386: Extract halt-to-exec transition out of x86_cpu_exec_halt()
2026-08-19 14:56 ` [PATCH 09/11] target/i386: Extract halt-to-exec transition " Philippe Mathieu-Daudé
@ 2026-08-19 20:17 ` Richard Henderson
0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:17 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Refactor the halt-to-execution target-specific transition logic
> (setting trap flag in debug register and injecting debug exceptions)
> into a separate x86_cpu_transition_halt_to_exec() function.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> target/i386/tcg/helper-tcg.h | 1 +
> target/i386/tcg/system/seg_helper.c | 20 +++++++++++++-------
> 2 files changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
> index cab197368b9..65819670493 100644
> --- a/target/i386/tcg/helper-tcg.h
> +++ b/target/i386/tcg/helper-tcg.h
> @@ -39,6 +39,7 @@ void x86_cpu_do_interrupt(CPUState *cpu);
> #ifndef CONFIG_USER_ONLY
> void x86_cpu_process_async_events(CPUState *cpu);
> bool x86_cpu_exec_halt(CPUState *cpu);
> +void x86_cpu_transition_halt_to_exec(CPUState *cpu);
> bool x86_need_replay_interrupt(int interrupt_request);
> bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
> #endif
> diff --git a/target/i386/tcg/system/seg_helper.c b/target/i386/tcg/system/seg_helper.c
> index 4856a6b3bab..9b2adcca76c 100644
> --- a/target/i386/tcg/system/seg_helper.c
> +++ b/target/i386/tcg/system/seg_helper.c
> @@ -140,22 +140,28 @@ void x86_cpu_process_async_events(CPUState *cpu)
> }
> }
>
> -bool x86_cpu_exec_halt(CPUState *cpu)
> +void x86_cpu_transition_halt_to_exec(CPUState *cpu)
> {
> X86CPU *x86_cpu = X86_CPU(cpu);
> - CPUX86State *env = &x86_cpu->env;
> + CPUX86State *env = cpu_env(cpu);
>
> - x86_cpu_process_async_events(cpu);
> -
> - if (!cpu_has_work(cpu)) {
> - return false;
> - }
> + assert(cpu_has_work(cpu));
>
Likewise, why did you add this?
Anyway,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec()
2026-08-19 14:56 ` [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
@ 2026-08-19 20:18 ` Richard Henderson
2026-08-19 20:19 ` Richard Henderson
1 sibling, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:18 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> x86_cpu_exec_halt() now merely checks cpu_has_work() and
> conditionally call x86_cpu_transition_halt_to_exec(), which is now
> the generic flow in cpu_has_work_after_processing_async_events().
>
> Register both process_async_events and transition_halt_to_exec
> handlers to use the generic target-agnostic flow, and remove the
> x86_cpu_exec_halt() wrapper.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> target/i386/tcg/helper-tcg.h | 1 -
> target/i386/tcg/system/seg_helper.c | 11 -----------
> target/i386/tcg/tcg-cpu.c | 3 ++-
> 3 files changed, 2 insertions(+), 13 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec()
2026-08-19 14:56 ` [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
2026-08-19 20:18 ` Richard Henderson
@ 2026-08-19 20:19 ` Richard Henderson
1 sibling, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:19 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> x86_cpu_exec_halt() now merely checks cpu_has_work() and
> conditionally call x86_cpu_transition_halt_to_exec(), which is now
> the generic flow in cpu_has_work_after_processing_async_events().
>
> Register both process_async_events and transition_halt_to_exec
> handlers to use the generic target-agnostic flow, and remove the
> x86_cpu_exec_halt() wrapper.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> target/i386/tcg/helper-tcg.h | 1 -
> target/i386/tcg/system/seg_helper.c | 11 -----------
> target/i386/tcg/tcg-cpu.c | 3 ++-
> 3 files changed, 2 insertions(+), 13 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook
2026-08-19 14:56 ` [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook Philippe Mathieu-Daudé
2026-08-19 15:05 ` Philippe Mathieu-Daudé
@ 2026-08-19 20:20 ` Richard Henderson
1 sibling, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2026-08-19 20:20 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Pierrick Bouvier
On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> Every target setting the cpu_exec_halt callback alias it to
> their cpu_has_work() function, making the callback redundant.
>
> Call cpu_has_work() directly in accel/tcg/cpu-exec.c
> cpu_has_work_after_processing_async_events() and remove the
> boilerplate cpu_exec_halt hook registration. No functional
> impact expected.
>
> Signed-off-by: Philippe Mathieu-Daudé<philmd@oss.qualcomm.com>
> ---
> include/accel/tcg/cpu-ops.h | 17 -----------------
> accel/tcg/cpu-exec.c | 23 ++++++++---------------
> target/alpha/cpu.c | 1 -
> target/avr/cpu.c | 1 -
> target/hexagon/cpu.c | 1 -
> target/hppa/cpu.c | 1 -
> target/loongarch/tcg/tcg_cpu.c | 1 -
> target/m68k/cpu.c | 1 -
> target/microblaze/cpu.c | 1 -
> target/mips/cpu.c | 1 -
> target/or1k/cpu.c | 1 -
> target/ppc/cpu_init.c | 1 -
> target/riscv/tcg/tcg-cpu.c | 1 -
> target/rx/cpu.c | 1 -
> target/s390x/cpu.c | 1 -
> target/sh4/cpu.c | 1 -
> target/sparc/cpu.c | 1 -
> target/tricore/cpu.c | 1 -
> target/xtensa/cpu.c | 1 -
> 19 files changed, 8 insertions(+), 49 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt()
2026-08-19 20:13 ` Richard Henderson
@ 2026-08-19 21:40 ` Peter Maydell
2026-08-20 7:29 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 30+ messages in thread
From: Peter Maydell @ 2026-08-19 21:40 UTC (permalink / raw)
To: Richard Henderson
Cc: Philippe Mathieu-Daudé, qemu-devel, Paolo Bonzini,
Daniel Henrique Barboza, Pierrick Bouvier
On Wed, 19 Aug 2026 at 21:14, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
> > Refactor the target-specific halt-to-execution transition
> > logic (disable WFE/WFI timers, clear the halt_reason flag)
> > into a separate arm_cpu_transition_halt_to_exec() function.
> >
> > Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> > ---
> > target/arm/cpu.c | 22 +++++++++++++++-------
> > 1 file changed, 15 insertions(+), 7 deletions(-)
> >
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index 77aa78f00e2..8e9b584559d 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -870,18 +870,26 @@ static bool arm_cpu_internal_is_big_endian(CPUState *cs)
> > }
> >
> > #ifdef CONFIG_TCG
> > +static void arm_cpu_transition_halt_to_exec(CPUState *cs)
> > +{
> > + ARMCPU *cpu = ARM_CPU(cs);
> > +
> > + assert(cpu_has_work(cs));
>
> In reply to patch 11 you suggest removing this.
> I wonder why you added it in the first place.
Does the accel loop enforce that we hold the BQL when
arm_cpu_exec_halt() is called? If not then the assertion
is racy, because something might get in and e.g. lower
an IRQ line so that cpu_has_work() is no longer true
(which would be fine -- it just means we made the decision
to wake up and that won vs the incoming interrupt).
On the one hand, if we don't have the BQL in has_work and
exec_halt then we should be a lot more careful about how
we code them (e.g. use of the right kind of atomics, and
there's no way the call to do_interrupt_all() in the x86
exec_halt can be safe without the BQL, surely).
On the other hand, if we do have the BQL in exec_halt
then why is the x86 implementation explicitly taking
the BQL when it calls apic_poll_irq()?
-- PMM
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt()
2026-08-19 21:40 ` Peter Maydell
@ 2026-08-20 7:29 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-20 7:29 UTC (permalink / raw)
To: Peter Maydell, Richard Henderson
Cc: qemu-devel, Paolo Bonzini, Daniel Henrique Barboza,
Pierrick Bouvier
On 2026-08-19 23:40, Peter Maydell wrote:
> On Wed, 19 Aug 2026 at 21:14, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> On 8/19/26 07:56, Philippe Mathieu-Daudé wrote:
>>> Refactor the target-specific halt-to-execution transition
>>> logic (disable WFE/WFI timers, clear the halt_reason flag)
>>> into a separate arm_cpu_transition_halt_to_exec() function.
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
>>> ---
>>> target/arm/cpu.c | 22 +++++++++++++++-------
>>> 1 file changed, 15 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>>> index 77aa78f00e2..8e9b584559d 100644
>>> --- a/target/arm/cpu.c
>>> +++ b/target/arm/cpu.c
>>> @@ -870,18 +870,26 @@ static bool arm_cpu_internal_is_big_endian(CPUState *cs)
>>> }
>>>
>>> #ifdef CONFIG_TCG
>>> +static void arm_cpu_transition_halt_to_exec(CPUState *cs)
>>> +{
>>> + ARMCPU *cpu = ARM_CPU(cs);
>>> +
>>> + assert(cpu_has_work(cs));
>>
>> In reply to patch 11 you suggest removing this.
>> I wonder why you added it in the first place.
>
> Does the accel loop enforce that we hold the BQL when
> arm_cpu_exec_halt() is called?
For MTTCG:
mttcg_cpu_thread_fn()
{
bql_lock();
while (1)
qemu_process_cpu_events(cpu);
if (cpu_can_run(cpu)) {
bql_unlock();
tcg_cpu_exec(cpu);
cpu_exec(cpu);
if (cpu->halted) {
cpu_has_work_after_processing_async_events(cpu);
process_async_events(cpu);
x86_cpu_process_async_events(); // APIC takes BQL
cpu_has_work(cpu);
transition_halt_to_exec(cpu);
arm_cpu_transition_halt_to_exec(); // timer_lock
x86_cpu_transition_halt_to_exec();
...
bql_lock();
...
}
void x86_cpu_process_async_events()
{
/* (BQL not held) */
if (cpu_test_interrupt()) {
bql_lock();
apic_poll_irq();
apic_sync_vapic();
apic_update_irq();
cpu_interrupt();
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
bql_unlock();
}
}
void arm_cpu_transition_halt_to_exec()
{
/* (BQL not held) */
timer_del();
qemu_mutex_lock();
timer_del_locked();
qemu_mutex_unlock();
}
void x86_cpu_transition_halt_to_exec()
{
/* (BQL not held) */
do_interrupt_all();
handle_even_inj();
x86_ldl_phys(VMCB);
address_space_ldl_le(VMCB);
device MMIO?
x86_stl_phys(VMCB);
address_space_stl_le(VMCB);
device MMIO?
}
VMCB address is guest-controlled, it comes from the guest %EAX
register passed to the VMRUN instruction (see helper_vmrun).
(I'm not looking further at the SVM specification).
> If not then the assertion
> is racy, because something might get in and e.g. lower
> an IRQ line so that cpu_has_work() is no longer true
> (which would be fine -- it just means we made the decision
> to wake up and that won vs the incoming interrupt).
>
> On the one hand, if we don't have the BQL in has_work and
> exec_halt then we should be a lot more careful about how
> we code them (e.g. use of the right kind of atomics, and
> there's no way the call to do_interrupt_all() in the x86
> exec_halt can be safe without the BQL, surely).
>
> On the other hand, if we do have the BQL in exec_halt
> then why is the x86 implementation explicitly taking
> the BQL when it calls apic_poll_irq()?
This analysis is similar before this series applied.
I don't have any idea how to proceed, I suppose from
here you expect Paolo / Richard to provide their feedback.
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
` (10 preceding siblings ...)
2026-08-19 14:56 ` [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook Philippe Mathieu-Daudé
@ 2026-08-20 9:26 ` Mark Cave-Ayland
2026-08-20 9:56 ` Philippe Mathieu-Daudé
11 siblings, 1 reply; 30+ messages in thread
From: Mark Cave-Ayland @ 2026-08-20 9:26 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
On 19/08/2026 15:56, Philippe Mathieu-Daudé wrote:
Hi Phil,
No objections to the idea of the patch, however I do have a couple of
questions:
> This series was inspired by a previous thread on the list [*].
>
> Refactor the CPU halt-to-execution transition logic in TCG as
> something more explicit and composable.
>
> Core problem: TCGCPUOps::cpu_exec_halt callback mixed concerns,
> it checked for work, processed async events, and handled state
> transitions all in one place.
>
> Solution: introduces two dedicated callbacks:
>
> * process_async_events(): Process target-specific async events
> before checking for work. Called early in cpu_exec().
Can you explain exactly what you mean by async events here in the
context of TCG? Looking at the thread indicated below suggests this is
terminology borrowed from KVM with which I am less familiar.
> * transition_halt_to_exec(): Perform target-specific state updates
> when transitioning from halt to execution.
That's quite a name :) Would something like cpu_exec_resume() be more
descriptive here (as well as keeping the cpu_exec_ prefix used by other
callbacks)?
> This separation allows the generic cpu_exec() code to orchestrate
> the flow cleanly (process events, check for work, transition state).
>
> Only 2 targets need to be migrated (x86 and ARM) then we can remove
> the redundant cpu_exec_halt() hook.
>
> The changes are expected to be purely refactoring with no functional
> impact.
>
> Series structure:
>
> Patches 1-2: Preparatory refactoring and guard additions
> Patch 3: Introduce the new hooks and orchestration logic
> Patch 4: Refactor cpu_exec() flow to use new infrastructure
> Patches 5-7: x86 extraction and conversion
> Patches 8-9: ARM extraction and conversion
> Patch 10: Remove the now-redundant cpu_exec_halt hook
>
> Testing: CI test suite
>
> [*] https://urldefense.proofpoint.com/v2/url?u=https-3A__lore.kernel.org_qemu-2Ddevel_CABgObfaDAhrpnVqQaKgG6uxPQe1YDu77YOsUEx9nqrN-3D3M2cGw-40mail.gmail.com_&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=sBca7couYmrH5p0nURqPPrh51jIPm0xJ4Tk5aHPSTzVFUbwS1-pc6webrznl259Y&s=eDmByvd3KnM-OoPHj78lDNqJAdxt6w0rKnaJOuyWJbM&e=
>
> Philippe Mathieu-Daudé (11):
> accel/tcg: Rename for exception codes named @ret as @excp
> accel/tcg: Restrict EXCP_HALTED handling to system emulation
> accel/tcg: Check %halted field in cpu_handle_halt() caller
> accel/tcg: Refactor halt-to-execution flow in cpu_exec()
> accel/tcg: Introduce .process_async_events and
> .transition_halt_to_exec
> target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt()
> target/arm: Convert cpu_exec_halt() to transition_halt_to_exec()
> target/i386: Extract async event processing out of x86_cpu_exec_halt()
> target/i386: Extract halt-to-exec transition out of
> x86_cpu_exec_halt()
> target/i386: Convert cpu_exec_halt() to transition_halt_to_exec()
> accel/tcg: Remove the now redundant cpu_exec_halt() hook
>
> include/accel/tcg/cpu-ops.h | 30 +++++++-------
> target/arm/internals.h | 3 --
> target/i386/tcg/helper-tcg.h | 3 +-
> accel/tcg/cpu-exec.c | 63 ++++++++++++++++-------------
> accel/tcg/tcg-accel-ops-mttcg.c | 7 ++--
> accel/tcg/tcg-accel-ops-rr.c | 8 ++--
> accel/tcg/tcg-accel-ops.c | 7 ++--
> target/alpha/cpu.c | 1 -
> target/arm/cpu.c | 22 +++++-----
> target/arm/tcg/cpu-v7m.c | 1 -
> target/avr/cpu.c | 1 -
> target/hexagon/cpu.c | 1 -
> target/hppa/cpu.c | 1 -
> target/i386/tcg/system/seg_helper.c | 14 ++++---
> target/i386/tcg/tcg-cpu.c | 3 +-
> target/loongarch/tcg/tcg_cpu.c | 1 -
> target/m68k/cpu.c | 1 -
> target/microblaze/cpu.c | 1 -
> target/mips/cpu.c | 1 -
> target/or1k/cpu.c | 1 -
> target/ppc/cpu_init.c | 1 -
> target/riscv/tcg/tcg-cpu.c | 1 -
> target/rx/cpu.c | 1 -
> target/s390x/cpu.c | 1 -
> target/sh4/cpu.c | 1 -
> target/sparc/cpu.c | 1 -
> target/tricore/cpu.c | 1 -
> target/xtensa/cpu.c | 1 -
> 28 files changed, 84 insertions(+), 94 deletions(-)
ATB,
Mark.
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt
2026-08-20 9:26 ` [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Mark Cave-Ayland
@ 2026-08-20 9:56 ` Philippe Mathieu-Daudé
2026-08-24 21:31 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-20 9:56 UTC (permalink / raw)
To: Mark Cave-Ayland, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Hi Mark,
On 2026-08-20 11:26, Mark Cave-Ayland wrote:
> On 19/08/2026 15:56, Philippe Mathieu-Daudé wrote:
>
> Hi Phil,
>
> No objections to the idea of the patch, however I do have a couple of
> questions:
>
>> This series was inspired by a previous thread on the list [*].
>>
>> Refactor the CPU halt-to-execution transition logic in TCG as
>> something more explicit and composable.
>>
>> Core problem: TCGCPUOps::cpu_exec_halt callback mixed concerns,
>> it checked for work, processed async events, and handled state
>> transitions all in one place.
>>
>> Solution: introduces two dedicated callbacks:
>>
>> * process_async_events(): Process target-specific async events
>> before checking for work. Called early in cpu_exec().
>
> Can you explain exactly what you mean by async events here in the
> context of TCG? Looking at the thread indicated below suggests this is
> terminology borrowed from KVM with which I am less familiar.
"asynchronous interrupts/events that arrive (from timers, other threads)
while a vCPU is halted"?
>
>> * transition_halt_to_exec(): Perform target-specific state updates
>> when transitioning from halt to execution.
>
> That's quite a name :) Would something like cpu_exec_resume() be more
> descriptive here (as well as keeping the cpu_exec_ prefix used by other
> callbacks)?
Naming is hard, I rather something self-explaining when reading the
code; we transition the state but do not resume yet. Anyway what about
.resume_halted/resume_from_halt/resume_from_sleep/resume_execution
instead of .transition_halt_to_exec?
>
>> This separation allows the generic cpu_exec() code to orchestrate
>> the flow cleanly (process events, check for work, transition state).
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt
2026-08-20 9:56 ` Philippe Mathieu-Daudé
@ 2026-08-24 21:31 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-24 21:31 UTC (permalink / raw)
To: Mark Cave-Ayland, qemu-devel
Cc: Paolo Bonzini, Daniel Henrique Barboza, Peter Maydell,
Richard Henderson, Pierrick Bouvier
Hey Mark,
On 20/8/26 11:56, Philippe Mathieu-Daudé wrote:
> Hi Mark,
>
> On 2026-08-20 11:26, Mark Cave-Ayland wrote:
>> On 19/08/2026 15:56, Philippe Mathieu-Daudé wrote:
>>
>> Hi Phil,
>>
>> No objections to the idea of the patch, however I do have a couple of
>> questions:
>>
>>> This series was inspired by a previous thread on the list [*].
>>>
>>> Refactor the CPU halt-to-execution transition logic in TCG as
>>> something more explicit and composable.
>>>
>>> Core problem: TCGCPUOps::cpu_exec_halt callback mixed concerns,
>>> it checked for work, processed async events, and handled state
>>> transitions all in one place.
>>>
>>> Solution: introduces two dedicated callbacks:
>>>
>>> * process_async_events(): Process target-specific async events
>>> before checking for work. Called early in cpu_exec().
>>
>> Can you explain exactly what you mean by async events here in the
>> context of TCG? Looking at the thread indicated below suggests this is
>> terminology borrowed from KVM with which I am less familiar.
>
> "asynchronous interrupts/events that arrive (from timers, other threads)
> while a vCPU is halted"?
>
>>
>>> * transition_halt_to_exec(): Perform target-specific state updates
>>> when transitioning from halt to execution.
>>
>> That's quite a name :) Would something like cpu_exec_resume() be more
>> descriptive here (as well as keeping the cpu_exec_ prefix used by
>> other callbacks)?
>
> Naming is hard, I rather something self-explaining when reading the
> code; we transition the state but do not resume yet. Anyway what about
> .resume_halted/resume_from_halt/resume_from_sleep/resume_execution
> instead of .transition_halt_to_exec?
WDYT?
>
>>
>>> This separation allows the generic cpu_exec() code to orchestrate
>>> the flow cleanly (process events, check for work, transition state).
>
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2026-08-24 21:32 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19 14:56 [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Philippe Mathieu-Daudé
2026-08-19 14:56 ` [PATCH 01/11] accel/tcg: Rename for exception codes named @ret as @excp Philippe Mathieu-Daudé
2026-08-19 19:55 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 02/11] accel/tcg: Restrict EXCP_HALTED handling to system emulation Philippe Mathieu-Daudé
2026-08-19 20:01 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 03/11] accel/tcg: Check %halted field in cpu_handle_halt() caller Philippe Mathieu-Daudé
2026-08-19 20:02 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 04/11] accel/tcg: Refactor halt-to-execution flow in cpu_exec() Philippe Mathieu-Daudé
2026-08-19 20:03 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 05/11] accel/tcg: Introduce .process_async_events and .transition_halt_to_exec Philippe Mathieu-Daudé
2026-08-19 20:06 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 06/11] target/arm: Extract halt-to-exec transition out of arm_cpu_exec_halt() Philippe Mathieu-Daudé
2026-08-19 20:13 ` Richard Henderson
2026-08-19 21:40 ` Peter Maydell
2026-08-20 7:29 ` Philippe Mathieu-Daudé
2026-08-19 14:56 ` [PATCH 07/11] target/arm: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
2026-08-19 20:15 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 08/11] target/i386: Extract async event processing out of x86_cpu_exec_halt() Philippe Mathieu-Daudé
2026-08-19 20:16 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 09/11] target/i386: Extract halt-to-exec transition " Philippe Mathieu-Daudé
2026-08-19 20:17 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 10/11] target/i386: Convert cpu_exec_halt() to transition_halt_to_exec() Philippe Mathieu-Daudé
2026-08-19 20:18 ` Richard Henderson
2026-08-19 20:19 ` Richard Henderson
2026-08-19 14:56 ` [PATCH 11/11] accel/tcg: Remove the now redundant cpu_exec_halt() hook Philippe Mathieu-Daudé
2026-08-19 15:05 ` Philippe Mathieu-Daudé
2026-08-19 20:20 ` Richard Henderson
2026-08-20 9:26 ` [PATCH 00/11] accel/tcg: Make halt-to-exec transition explicit and remove cpu_exec_halt Mark Cave-Ayland
2026-08-20 9:56 ` Philippe Mathieu-Daudé
2026-08-24 21:31 ` Philippe Mathieu-Daudé
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.