* [PATCH v2 00/12] accel/tcg: Improve tb_flush usage
@ 2025-09-23 2:39 Richard Henderson
2025-09-23 2:39 ` [PATCH v2 01/12] gdbstub: Remove tb_flush uses Richard Henderson
` (11 more replies)
0 siblings, 12 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
It is too easy to mis-use tb_flush(). For instance, because of
the cpu argument, some parts assumed that it needed to call the
global flush function for every cpu. It is easy to forget that
the flush is not complete when the call returns: we have merely
queued work to the cpu run loop. So: remove tb_flush and expose
only the core as tb_flush__exclusive, to be used only when we
are already within an exclusive context.
In some cases (gdbstub, alpha, riscv, ppc spapr),
we can eliminate the need for tb_flush completely.
Changes for v2:
- Assert exclusivity in tb_flush__exclusive (pbo)
r~
Richard Henderson (12):
gdbstub: Remove tb_flush uses
accel/tcg: Split out tb_flush__exclusive
target/alpha: Simplify call_pal implementation
target/riscv: Record misa_ext in TCGTBCPUState.cs_base
accel/tcg: Move post-load tb_flush to vm_change_state hook
hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init
linux-user: Use tb_flush_exclusive to start second thread
plugins: Use tb_flush__exclusive
accel/tcg: Introduce EXCP_TB_FLUSH
accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code
accel/tcg: Remove tb_flush
accel/tcg: Tighten assert in tb_flush__exclusive
include/exec/cpu-common.h | 1 +
include/exec/tb-flush.h | 18 ++++++--------
target/alpha/helper.h | 1 -
accel/tcg/tb-maint.c | 43 +++++++++++----------------------
accel/tcg/tcg-accel-ops-mttcg.c | 7 ++++++
accel/tcg/tcg-accel-ops-rr.c | 9 +++++--
accel/tcg/tcg-all.c | 21 ++++++++++++++++
accel/tcg/translate-all.c | 5 +---
gdbstub/system.c | 4 ---
gdbstub/user.c | 3 ---
hw/core/cpu-system.c | 8 ------
hw/ppc/spapr_hcall.c | 4 +--
linux-user/mmap.c | 4 +--
linux-user/syscall.c | 2 +-
plugins/core.c | 6 ++---
plugins/loader.c | 2 +-
target/alpha/sys_helper.c | 6 -----
target/alpha/translate.c | 21 +++++-----------
target/riscv/csr.c | 3 ---
target/riscv/tcg/tcg-cpu.c | 3 ++-
20 files changed, 75 insertions(+), 96 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 01/12] gdbstub: Remove tb_flush uses
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 9:11 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive Richard Henderson
` (10 subsequent siblings)
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Alex Bennée, Philippe Mathieu-Daudé
This hasn't been needed since d828b92b8a6
("accel/tcg: Introduce CF_BP_PAGE").
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
---
gdbstub/system.c | 4 ----
gdbstub/user.c | 3 ---
2 files changed, 7 deletions(-)
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 5be0d3c58c..df3514dc74 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -18,7 +18,6 @@
#include "gdbstub/syscalls.h"
#include "gdbstub/commands.h"
#include "exec/hwaddr.h"
-#include "exec/tb-flush.h"
#include "accel/accel-ops.h"
#include "accel/accel-cpu-ops.h"
#include "system/cpus.h"
@@ -174,9 +173,6 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
} else {
trace_gdbstub_hit_break();
}
- if (tcg_enabled()) {
- tb_flush(cpu);
- }
ret = GDB_SIGNAL_TRAP;
break;
case RUN_STATE_PAUSED:
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 67403e5a25..2e14ded3f0 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -15,7 +15,6 @@
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "exec/hwaddr.h"
-#include "exec/tb-flush.h"
#include "exec/gdbstub.h"
#include "gdbstub/commands.h"
#include "gdbstub/syscalls.h"
@@ -220,7 +219,6 @@ int gdb_handlesig(CPUState *cpu, int sig, const char *reason, void *siginfo,
/* disable single step if it was enabled */
cpu_single_step(cpu, 0);
- tb_flush(cpu);
if (sig != 0) {
gdb_set_stop_cpu(cpu);
@@ -539,7 +537,6 @@ static void disable_gdbstub(CPUState *thread_cpu)
/* no cpu_watchpoint_remove_all for user-mode */
cpu_single_step(cpu, 0);
}
- tb_flush(thread_cpu);
}
void gdbserver_fork_end(CPUState *cpu, pid_t pid)
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
2025-09-23 2:39 ` [PATCH v2 01/12] gdbstub: Remove tb_flush uses Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 7:17 ` Philippe Mathieu-Daudé
2025-09-23 9:16 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 03/12] target/alpha: Simplify call_pal implementation Richard Henderson
` (9 subsequent siblings)
11 siblings, 2 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Expose a routine to be called when no cpus are running.
Simplify the do_tb_flush run_on_cpu callback, because
that is explicitly called with start_exclusive; there
is no need for the mmap_lock as well.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/exec/tb-flush.h | 13 +++++++++++++
accel/tcg/tb-maint.c | 33 ++++++++++++++++++++-------------
2 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/include/exec/tb-flush.h b/include/exec/tb-flush.h
index 142c240d94..5076b13bbd 100644
--- a/include/exec/tb-flush.h
+++ b/include/exec/tb-flush.h
@@ -8,6 +8,19 @@
#ifndef _TB_FLUSH_H_
#define _TB_FLUSH_H_
+/**
+ * tb_flush__exclusive() - flush all translation blocks
+ *
+ * Used to flush all the translation blocks in the system.
+ * Sometimes it is simpler to flush everything than work out which
+ * individual translations are now invalid and ensure they are
+ * not called anymore.
+ *
+ * Must be called from an exclusive context, e.g. start_exclusive
+ * or vm_stop.
+ */
+void tb_flush__exclusive(void);
+
/**
* tb_flush() - flush all translation blocks
* @cs: CPUState (must be valid, but treated as anonymous pointer)
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 0048316f99..71216fa75e 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -36,6 +36,9 @@
#include "internal-common.h"
#ifdef CONFIG_USER_ONLY
#include "user/page-protection.h"
+#define runstate_is_running() true
+#else
+#include "system/runstate.h"
#endif
@@ -756,17 +759,18 @@ static void tb_remove(TranslationBlock *tb)
}
#endif /* CONFIG_USER_ONLY */
-/* flush all the translation blocks */
-static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
+/*
+ * Flush all the translation blocks.
+ * Must be called from a context in which no cpus are running,
+ * e.g. start_exclusive() or vm_stop().
+ */
+void tb_flush__exclusive(void)
{
- bool did_flush = false;
+ CPUState *cpu;
- mmap_lock();
- /* If it is already been done on request of another CPU, just retry. */
- if (tb_ctx.tb_flush_count != tb_flush_count.host_int) {
- goto done;
- }
- did_flush = true;
+ assert(tcg_enabled());
+ assert(!runstate_is_running() ||
+ (current_cpu && cpu_in_serial_context(current_cpu)));
CPU_FOREACH(cpu) {
tcg_flush_jmp_cache(cpu);
@@ -778,11 +782,14 @@ static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
tcg_region_reset_all();
/* XXX: flush processor icache at this point if cache flush is expensive */
qatomic_inc(&tb_ctx.tb_flush_count);
+ qemu_plugin_flush_cb();
+}
-done:
- mmap_unlock();
- if (did_flush) {
- qemu_plugin_flush_cb();
+static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
+{
+ /* If it is already been done on request of another CPU, just retry. */
+ if (tb_ctx.tb_flush_count == tb_flush_count.host_int) {
+ tb_flush__exclusive();
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 03/12] target/alpha: Simplify call_pal implementation
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
2025-09-23 2:39 ` [PATCH v2 01/12] gdbstub: Remove tb_flush uses Richard Henderson
2025-09-23 2:39 ` [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 7:30 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base Richard Henderson
` (8 subsequent siblings)
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
Since 288a5fe980f, we don't link translation blocks
directly to palcode entry points. If we load palbr
from env instead of encoding the constant, we avoid
all need for tb_flush().
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/alpha/helper.h | 1 -
target/alpha/sys_helper.c | 6 ------
target/alpha/translate.c | 21 ++++++---------------
3 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/target/alpha/helper.h b/target/alpha/helper.h
index d60f208703..788d2fbf28 100644
--- a/target/alpha/helper.h
+++ b/target/alpha/helper.h
@@ -90,7 +90,6 @@ DEF_HELPER_FLAGS_2(ieee_input_s, TCG_CALL_NO_WG, void, env, i64)
#if !defined (CONFIG_USER_ONLY)
DEF_HELPER_FLAGS_1(tbia, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_2(tbis, TCG_CALL_NO_RWG, void, env, i64)
-DEF_HELPER_FLAGS_1(tb_flush, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_1(halt, void, i64)
diff --git a/target/alpha/sys_helper.c b/target/alpha/sys_helper.c
index 51e3254428..87e37605c1 100644
--- a/target/alpha/sys_helper.c
+++ b/target/alpha/sys_helper.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/cputlb.h"
-#include "exec/tb-flush.h"
#include "exec/helper-proto.h"
#include "system/runstate.h"
#include "system/system.h"
@@ -38,11 +37,6 @@ void helper_tbis(CPUAlphaState *env, uint64_t p)
tlb_flush_page(env_cpu(env), p);
}
-void helper_tb_flush(CPUAlphaState *env)
-{
- tb_flush(env_cpu(env));
-}
-
void helper_halt(uint64_t restart)
{
if (restart) {
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index cebab0318c..f11b382438 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -48,8 +48,6 @@ struct DisasContext {
#ifdef CONFIG_USER_ONLY
MemOp unalign;
-#else
- uint64_t palbr;
#endif
uint32_t tbflags;
int mem_idx;
@@ -1155,7 +1153,6 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
#else
{
TCGv tmp = tcg_temp_new();
- uint64_t entry;
gen_pc_disp(ctx, tmp, 0);
if (ctx->tbflags & ENV_FLAG_PAL_MODE) {
@@ -1165,12 +1162,11 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
}
tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUAlphaState, exc_addr));
- entry = ctx->palbr;
- entry += (palcode & 0x80
- ? 0x2000 + (palcode - 0x80) * 64
- : 0x1000 + palcode * 64);
-
- tcg_gen_movi_i64(cpu_pc, entry);
+ tcg_gen_ld_i64(cpu_pc, tcg_env, offsetof(CPUAlphaState, palbr));
+ tcg_gen_addi_i64(cpu_pc, cpu_pc,
+ palcode & 0x80
+ ? 0x2000 + (palcode - 0x80) * 64
+ : 0x1000 + palcode * 64);
return DISAS_PC_UPDATED;
}
#endif
@@ -1292,11 +1288,7 @@ static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
case 7:
/* PALBR */
tcg_gen_st_i64(vb, tcg_env, offsetof(CPUAlphaState, palbr));
- /* Changing the PAL base register implies un-chaining all of the TBs
- that ended with a CALL_PAL. Since the base register usually only
- changes during boot, flushing everything works well. */
- gen_helper_tb_flush(tcg_env);
- return DISAS_PC_STALE;
+ break;
case 32 ... 39:
/* Accessing the "non-shadow" general registers. */
@@ -2874,7 +2866,6 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
ctx->ir = cpu_std_ir;
ctx->unalign = (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
#else
- ctx->palbr = env->palbr;
ctx->ir = (ctx->tbflags & ENV_FLAG_PAL_MODE ? cpu_pal_ir : cpu_std_ir);
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (2 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 03/12] target/alpha: Simplify call_pal implementation Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-24 6:17 ` LIU Zhiwei
` (2 more replies)
2025-09-23 2:39 ` [PATCH v2 05/12] accel/tcg: Move post-load tb_flush to vm_change_state hook Richard Henderson
` (7 subsequent siblings)
11 siblings, 3 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, qemu-riscv
The tb_flush within write_misa was incorrect. It assumed
that we could adjust the ISA of the current processor and
discard all TB and all would be well. But MISA is per vcpu,
so globally flushing TB does not mean that the TB matches
the MISA of any given vcpu.
By recording misa in the tb state, we ensure that the code
generated matches the vcpu.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
Cc: Alistair Francis <alistair.francis@wdc.com>
Cc: Weiwei Li <liwei1518@gmail.com>
Cc: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Cc: qemu-riscv@nongnu.org
---
target/riscv/csr.c | 3 ---
target/riscv/tcg/tcg-cpu.c | 3 ++-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8842e07a73..3c8989f522 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -25,7 +25,6 @@
#include "pmu.h"
#include "time_helper.h"
#include "exec/cputlb.h"
-#include "exec/tb-flush.h"
#include "exec/icount.h"
#include "accel/tcg/getpc.h"
#include "qemu/guest-random.h"
@@ -2173,8 +2172,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
env->mstatus &= ~MSTATUS_FS;
}
- /* flush translation cache */
- tb_flush(env_cpu(env));
env->xl = riscv_cpu_mxl(env);
return RISCV_EXCP_NONE;
}
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 78fb279184..143ab079d4 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -191,7 +191,8 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
return (TCGTBCPUState){
.pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
- .flags = flags
+ .flags = flags,
+ .cs_base = env->misa_ext,
};
}
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 05/12] accel/tcg: Move post-load tb_flush to vm_change_state hook
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (3 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 7:22 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init Richard Henderson
` (6 subsequent siblings)
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier, Peter Xu
We need not call tb_flush once per cpu, only once per vmload.
By moving the call from cpu_common_post_load to a tcg-specific
vm_change_state_handler, we do even better than that: we only
flush when called from HMP triggered loadvm, when we had old
state to flush.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
Cc: Peter Xu <peterx@redhat.com>
---
accel/tcg/tcg-all.c | 21 +++++++++++++++++++++
hw/core/cpu-system.c | 8 --------
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 5125e1a4e2..a0bc0e58c7 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -38,6 +38,8 @@
#include "qemu/target-info.h"
#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
+#include "exec/tb-flush.h"
+#include "system/runstate.h"
#endif
#include "accel/accel-ops.h"
#include "accel/accel-cpu-ops.h"
@@ -82,6 +84,23 @@ static void tcg_accel_instance_init(Object *obj)
bool one_insn_per_tb;
+#ifndef CONFIG_USER_ONLY
+static void tcg_vm_change_state(void *opaque, bool running, RunState state)
+{
+ if (state == RUN_STATE_RESTORE_VM) {
+ /*
+ * loadvm will update the content of RAM, bypassing the usual
+ * mechanisms that ensure we flush TBs for writes to memory
+ * we've translated code from, so we must flush all TBs.
+ *
+ * vm_stop() has just stopped all cpus, so we are exclusive.
+ */
+ assert(!running);
+ tb_flush__exclusive();
+ }
+}
+#endif
+
static int tcg_init_machine(AccelState *as, MachineState *ms)
{
TCGState *s = TCG_STATE(as);
@@ -124,6 +143,8 @@ static int tcg_init_machine(AccelState *as, MachineState *ms)
default:
g_assert_not_reached();
}
+
+ qemu_add_vm_change_state_handler(tcg_vm_change_state, NULL);
#endif
tcg_allowed = true;
diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c
index 09c928c1f9..1fd9571017 100644
--- a/hw/core/cpu-system.c
+++ b/hw/core/cpu-system.c
@@ -207,14 +207,6 @@ static int cpu_common_post_load(void *opaque, int version_id)
cpu_reset_interrupt(cpu, 0x01);
tlb_flush(cpu);
-
- /*
- * loadvm has just updated the content of RAM, bypassing the
- * usual mechanisms that ensure we flush TBs for writes to
- * memory we've translated code from. So we must flush all TBs,
- * which will now be stale.
- */
- tb_flush(cpu);
}
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (4 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 05/12] accel/tcg: Move post-load tb_flush to vm_change_state hook Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 4:49 ` Harsh Prateek Bora
2025-09-23 8:55 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 07/12] linux-user: Use tb_flush_exclusive to start second thread Richard Henderson
` (5 subsequent siblings)
11 siblings, 2 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Nicholas Piggin, Harsh Prateek Bora, qemu-ppc
We only need invalidate tbs from a single page, not flush
all translations.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Harsh Prateek Bora <harshpb@linux.ibm.com>
Cc: qemu-ppc@nongnu.org
---
hw/ppc/spapr_hcall.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index c594d4b916..feb31d5dd8 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -8,7 +8,7 @@
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
-#include "exec/tb-flush.h"
+#include "exec/translation-block.h"
#include "exec/target_page.h"
#include "helper_regs.h"
#include "hw/ppc/ppc.h"
@@ -301,7 +301,7 @@ static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
if (kvm_enabled()) {
kvmppc_icbi_range(cpu, pdst, len);
} else if (tcg_enabled()) {
- tb_flush(CPU(cpu));
+ tb_invalidate_phys_range(CPU(cpu), dst, len);
} else {
g_assert_not_reached();
}
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 07/12] linux-user: Use tb_flush_exclusive to start second thread
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (5 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 8:50 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 08/12] plugins: Use tb_flush__exclusive Richard Henderson
` (4 subsequent siblings)
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
When we start the second thread, we discard all translations
so that we can re-do them with CF_PARALLEL. Since there is
as yet only one cpu, and we are processing a syscall, there
are no live translation blocks and we have exclusivity.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/mmap.c | 4 ++--
linux-user/syscall.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 002e1e668e..bd2bbaf1f4 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -1010,7 +1010,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
CPUState *cpu = thread_cpu;
if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
tcg_cflags_set(cpu, CF_PARALLEL);
- tb_flush(cpu);
+ tb_flush__exclusive();
}
}
@@ -1450,7 +1450,7 @@ abi_ulong target_shmat(CPUArchState *cpu_env, int shmid,
*/
if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
tcg_cflags_set(cpu, CF_PARALLEL);
- tb_flush(cpu);
+ tb_flush__exclusive();
}
if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 91360a072c..d9c394856f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6633,7 +6633,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
*/
if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
tcg_cflags_set(cpu, CF_PARALLEL);
- tb_flush(cpu);
+ tb_flush__exclusive();
}
/* we create a new CPU instance. */
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 08/12] plugins: Use tb_flush__exclusive
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (6 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 07/12] linux-user: Use tb_flush_exclusive to start second thread Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 7:33 ` Philippe Mathieu-Daudé
2025-09-23 13:35 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH Richard Henderson
` (3 subsequent siblings)
11 siblings, 2 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier
In all cases, we are already within start_exclusive.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
Cc: Alex Bennée" <alex.bennee@linaro.org>
Cc: Alexandre Iooss <erdnaxe@crans.org>
Cc: Mahmoud Mandour <ma.mandourr@gmail.com>
Cc: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
plugins/core.c | 6 ++----
plugins/loader.c | 2 +-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/plugins/core.c b/plugins/core.c
index c6e9ef1478..4ae1a6ae17 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -248,7 +248,7 @@ static void plugin_grow_scoreboards__locked(CPUState *cpu)
}
plugin.scoreboard_alloc_size = scoreboard_size;
/* force all tb to be flushed, as scoreboard pointers were changed. */
- tb_flush(cpu);
+ tb_flush__exclusive();
}
end_exclusive();
}
@@ -684,8 +684,6 @@ void qemu_plugin_user_exit(void)
* with the one in fork_start(). That is:
* - start_exclusive(), which acquires qemu_cpu_list_lock,
* must be called before acquiring plugin.lock.
- * - tb_flush(), which acquires mmap_lock(), must be called
- * while plugin.lock is not held.
*/
start_exclusive();
@@ -705,7 +703,7 @@ void qemu_plugin_user_exit(void)
}
qemu_rec_mutex_unlock(&plugin.lock);
- tb_flush(current_cpu);
+ tb_flush__exclusive();
end_exclusive();
/* now it's safe to handle the exit case */
diff --git a/plugins/loader.c b/plugins/loader.c
index 8f0d75c904..6849e1c518 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -378,7 +378,7 @@ static void plugin_flush_destroy(CPUState *cpu, run_on_cpu_data arg)
struct qemu_plugin_reset_data *data = arg.host_ptr;
g_assert(cpu_in_exclusive_context(cpu));
- tb_flush(cpu);
+ tb_flush__exclusive();
plugin_reset_destroy(data);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (7 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 08/12] plugins: Use tb_flush__exclusive Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 7:10 ` Paolo Bonzini
2025-09-23 2:39 ` [PATCH v2 10/12] accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code Richard Henderson
` (2 subsequent siblings)
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
We are going to disallow tb_flush from within the context
of a running cpu. Introduce a tcg-internal exception to
return out of the cpu run loop and perform the flush there.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/exec/cpu-common.h | 1 +
accel/tcg/tcg-accel-ops-mttcg.c | 7 +++++++
accel/tcg/tcg-accel-ops-rr.c | 9 +++++++--
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 9b658a3f48..ce9f116ac3 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -20,6 +20,7 @@
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
#define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */
#define EXCP_ATOMIC 0x10005 /* stop-the-world and emulate atomic */
+#define EXCP_TB_FLUSH 0x10006 /* stop-the-world and flush all tb */
void cpu_exec_init_all(void);
void cpu_exec_step_atomic(CPUState *cpu);
diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
index cf1ee7ac25..c7b8e8a713 100644
--- a/accel/tcg/tcg-accel-ops-mttcg.c
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
@@ -27,6 +27,7 @@
#include "system/tcg.h"
#include "system/replay.h"
#include "exec/icount.h"
+#include "exec/tb-flush.h"
#include "qemu/main-loop.h"
#include "qemu/notify.h"
#include "qemu/guest-random.h"
@@ -106,6 +107,12 @@ static void *mttcg_cpu_thread_fn(void *arg)
bql_unlock();
cpu_exec_step_atomic(cpu);
bql_lock();
+ break;
+ case EXCP_TB_FLUSH:
+ start_exclusive();
+ tb_flush__exclusive();
+ end_exclusive();
+ break;
default:
/* Ignore everything else? */
break;
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
index 2fb4643997..85dade50a8 100644
--- a/accel/tcg/tcg-accel-ops-rr.c
+++ b/accel/tcg/tcg-accel-ops-rr.c
@@ -32,6 +32,7 @@
#include "qemu/notify.h"
#include "qemu/guest-random.h"
#include "exec/cpu-common.h"
+#include "exec/tb-flush.h"
#include "tcg/startup.h"
#include "tcg-accel-ops.h"
#include "tcg-accel-ops-rr.h"
@@ -288,14 +289,18 @@ static void *rr_cpu_thread_fn(void *arg)
}
bql_lock();
- if (r == EXCP_DEBUG) {
+ switch (r) {
+ case EXCP_DEBUG:
cpu_handle_guest_debug(cpu);
break;
- } else if (r == EXCP_ATOMIC) {
+ case EXCP_ATOMIC:
bql_unlock();
cpu_exec_step_atomic(cpu);
bql_lock();
break;
+ case EXCP_TB_FLUSH:
+ tb_flush__exclusive();
+ break;
}
} else if (cpu->stop) {
if (cpu->unplug) {
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 10/12] accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (8 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 9:15 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 11/12] accel/tcg: Remove tb_flush Richard Henderson
2025-09-23 2:39 ` [PATCH v2 12/12] accel/tcg: Tighten assert in tb_flush__exclusive Richard Henderson
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/translate-all.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index d468667b0d..d7cc346414 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -288,11 +288,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s)
assert_no_pages_locked();
tb = tcg_tb_alloc(tcg_ctx);
if (unlikely(!tb)) {
- /* flush must be done */
- tb_flush(cpu);
mmap_unlock();
- /* Make the execution loop process the flush as soon as possible. */
- cpu->exception_index = EXCP_INTERRUPT;
+ cpu->exception_index = EXCP_TB_FLUSH;
cpu_loop_exit(cpu);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 11/12] accel/tcg: Remove tb_flush
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (9 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 10/12] accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
2025-09-23 7:24 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 12/12] accel/tcg: Tighten assert in tb_flush__exclusive Richard Henderson
11 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
All uses have been replaced with tb_flush__exclusive.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/exec/tb-flush.h | 15 ---------------
accel/tcg/tb-maint.c | 22 ----------------------
2 files changed, 37 deletions(-)
diff --git a/include/exec/tb-flush.h b/include/exec/tb-flush.h
index 5076b13bbd..d6586b9d5f 100644
--- a/include/exec/tb-flush.h
+++ b/include/exec/tb-flush.h
@@ -21,21 +21,6 @@
*/
void tb_flush__exclusive(void);
-/**
- * tb_flush() - flush all translation blocks
- * @cs: CPUState (must be valid, but treated as anonymous pointer)
- *
- * Used to flush all the translation blocks in the system. Sometimes
- * it is simpler to flush everything than work out which individual
- * translations are now invalid and ensure they are not called
- * anymore.
- *
- * tb_flush() takes care of running the flush in an exclusive context
- * if it is not already running in one. This means no guest code will
- * run until this complete.
- */
-void tb_flush(CPUState *cs);
-
void tcg_flush_jmp_cache(CPUState *cs);
#endif /* _TB_FLUSH_H_ */
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 71216fa75e..879ed12442 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -785,28 +785,6 @@ void tb_flush__exclusive(void)
qemu_plugin_flush_cb();
}
-static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
-{
- /* If it is already been done on request of another CPU, just retry. */
- if (tb_ctx.tb_flush_count == tb_flush_count.host_int) {
- tb_flush__exclusive();
- }
-}
-
-void tb_flush(CPUState *cpu)
-{
- if (tcg_enabled()) {
- unsigned tb_flush_count = qatomic_read(&tb_ctx.tb_flush_count);
-
- if (cpu_in_serial_context(cpu)) {
- do_tb_flush(cpu, RUN_ON_CPU_HOST_INT(tb_flush_count));
- } else {
- async_safe_run_on_cpu(cpu, do_tb_flush,
- RUN_ON_CPU_HOST_INT(tb_flush_count));
- }
- }
-}
-
/* remove @orig from its @n_orig-th jump list */
static inline void tb_remove_from_jmp_list(TranslationBlock *orig, int n_orig)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 12/12] accel/tcg: Tighten assert in tb_flush__exclusive
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
` (10 preceding siblings ...)
2025-09-23 2:39 ` [PATCH v2 11/12] accel/tcg: Remove tb_flush Richard Henderson
@ 2025-09-23 2:39 ` Richard Henderson
11 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 2:39 UTC (permalink / raw)
To: qemu-devel
Now that tb_flush is gone, with its cpu_in_serial_context
check, we can tighten to cpu_in_exclusive_context.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/tb-maint.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 879ed12442..81e8ec14d4 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -770,7 +770,7 @@ void tb_flush__exclusive(void)
assert(tcg_enabled());
assert(!runstate_is_running() ||
- (current_cpu && cpu_in_serial_context(current_cpu)));
+ (current_cpu && cpu_in_exclusive_context(current_cpu)));
CPU_FOREACH(cpu) {
tcg_flush_jmp_cache(cpu);
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init
2025-09-23 2:39 ` [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init Richard Henderson
@ 2025-09-23 4:49 ` Harsh Prateek Bora
2025-09-23 8:55 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 36+ messages in thread
From: Harsh Prateek Bora @ 2025-09-23 4:49 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Nicholas Piggin, qemu-ppc, Chinmay Rath, anushree.mathur
+ Chinmay, Anu - FYI
On 9/23/25 08:09, Richard Henderson wrote:
> We only need invalidate tbs from a single page, not flush
> all translations.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Harsh Prateek Bora <harshpb@linux.ibm.com>
> Cc: qemu-ppc@nongnu.org
> ---
> hw/ppc/spapr_hcall.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index c594d4b916..feb31d5dd8 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -8,7 +8,7 @@
> #include "qemu/main-loop.h"
> #include "qemu/module.h"
> #include "qemu/error-report.h"
> -#include "exec/tb-flush.h"
> +#include "exec/translation-block.h"
> #include "exec/target_page.h"
> #include "helper_regs.h"
> #include "hw/ppc/ppc.h"
> @@ -301,7 +301,7 @@ static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
> if (kvm_enabled()) {
> kvmppc_icbi_range(cpu, pdst, len);
> } else if (tcg_enabled()) {
> - tb_flush(CPU(cpu));
> + tb_invalidate_phys_range(CPU(cpu), dst, len);
Much needed improvement. Thanks.
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
> } else {
> g_assert_not_reached();
> }
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH
2025-09-23 2:39 ` [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH Richard Henderson
@ 2025-09-23 7:10 ` Paolo Bonzini
2025-09-23 20:02 ` Richard Henderson
0 siblings, 1 reply; 36+ messages in thread
From: Paolo Bonzini @ 2025-09-23 7:10 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 9/23/25 04:39, Richard Henderson wrote:
> We are going to disallow tb_flush from within the context
> of a running cpu. Introduce a tcg-internal exception to
> return out of the cpu run loop and perform the flush there.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
One small difference is that different CPUs can fail tcg_tb_alloc() at
the same time and flush multiple times.
I think the check on the generation count should remain. Instead of
introducing EXCP_TB_FLUSH, you can keep the guts of tb_flush() as
void tb_queue_flush(CPUState *cpu)
{
unsigned tb_flush_count = qatomic_read(&tb_ctx.tb_flush_count);
async_safe_run_on_cpu(cpu, do_tb_flush,
RUN_ON_CPU_HOST_INT(tb_flush_count));
}
With the unconditional async_safe_run_on_cpu() hidden behind a function,
this patch goes away while the next one survives as
if (unlikely(!tb)) {
- /* flush must be done */
- tb_flush(cpu);
mmap_unlock();
- /* Make the execution loop process the flush as soon as
possible. */
- cpu->exception_index = EXCP_INTERRUPT;
+ tb_queue_flush(cpu);
cpu_loop_exit(cpu);
}
Paolo
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive
2025-09-23 2:39 ` [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive Richard Henderson
@ 2025-09-23 7:17 ` Philippe Mathieu-Daudé
2025-09-23 9:16 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 7:17 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Pierrick Bouvier
On 23/9/25 04:39, Richard Henderson wrote:
> Expose a routine to be called when no cpus are running.
> Simplify the do_tb_flush run_on_cpu callback, because
> that is explicitly called with start_exclusive; there
> is no need for the mmap_lock as well.
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/exec/tb-flush.h | 13 +++++++++++++
> accel/tcg/tb-maint.c | 33 ++++++++++++++++++++-------------
> 2 files changed, 33 insertions(+), 13 deletions(-)
> diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
> index 0048316f99..71216fa75e 100644
> --- a/accel/tcg/tb-maint.c
> +++ b/accel/tcg/tb-maint.c
> @@ -36,6 +36,9 @@
> #include "internal-common.h"
> #ifdef CONFIG_USER_ONLY
> #include "user/page-protection.h"
> +#define runstate_is_running() true
Hmm, acceptable.
> +#else
> +#include "system/runstate.h"
> #endif
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 05/12] accel/tcg: Move post-load tb_flush to vm_change_state hook
2025-09-23 2:39 ` [PATCH v2 05/12] accel/tcg: Move post-load tb_flush to vm_change_state hook Richard Henderson
@ 2025-09-23 7:22 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 7:22 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Pierrick Bouvier, Peter Xu
On 23/9/25 04:39, Richard Henderson wrote:
> We need not call tb_flush once per cpu, only once per vmload.
>
> By moving the call from cpu_common_post_load to a tcg-specific
> vm_change_state_handler, we do even better than that: we only
> flush when called from HMP triggered loadvm, when we had old
> state to flush.
Nice!
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Peter Xu <peterx@redhat.com>
> ---
> accel/tcg/tcg-all.c | 21 +++++++++++++++++++++
> hw/core/cpu-system.c | 8 --------
> 2 files changed, 21 insertions(+), 8 deletions(-)
> diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c
> index 09c928c1f9..1fd9571017 100644
> --- a/hw/core/cpu-system.c
> +++ b/hw/core/cpu-system.c
> @@ -207,14 +207,6 @@ static int cpu_common_post_load(void *opaque, int version_id)
> cpu_reset_interrupt(cpu, 0x01);
>
> tlb_flush(cpu);
> -
> - /*
> - * loadvm has just updated the content of RAM, bypassing the
> - * usual mechanisms that ensure we flush TBs for writes to
> - * memory we've translated code from. So we must flush all TBs,
> - * which will now be stale.
> - */
> - tb_flush(cpu);
> }
>
To squash:
-- >8 --
--- a/hw/core/cpu-system.c
+++ b/hw/core/cpu-system.c
@@ -25,3 +25,2 @@
#include "system/memory.h"
-#include "exec/tb-flush.h"
#include "qemu/target-info.h"---
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 11/12] accel/tcg: Remove tb_flush
2025-09-23 2:39 ` [PATCH v2 11/12] accel/tcg: Remove tb_flush Richard Henderson
@ 2025-09-23 7:24 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 7:24 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Pierrick Bouvier
On 23/9/25 04:39, Richard Henderson wrote:
> All uses have been replaced with tb_flush__exclusive.
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/exec/tb-flush.h | 15 ---------------
> accel/tcg/tb-maint.c | 22 ----------------------
> 2 files changed, 37 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 03/12] target/alpha: Simplify call_pal implementation
2025-09-23 2:39 ` [PATCH v2 03/12] target/alpha: Simplify call_pal implementation Richard Henderson
@ 2025-09-23 7:30 ` Philippe Mathieu-Daudé
2025-09-23 9:05 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 7:30 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 23/9/25 04:39, Richard Henderson wrote:
> Since 288a5fe980f, we don't link translation blocks
> directly to palcode entry points. If we load palbr
> from env instead of encoding the constant, we avoid
> all need for tb_flush().
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/alpha/helper.h | 1 -
> target/alpha/sys_helper.c | 6 ------
> target/alpha/translate.c | 21 ++++++---------------
> 3 files changed, 6 insertions(+), 22 deletions(-)
>
> diff --git a/target/alpha/helper.h b/target/alpha/helper.h
> index d60f208703..788d2fbf28 100644
> --- a/target/alpha/helper.h
> +++ b/target/alpha/helper.h
> @@ -90,7 +90,6 @@ DEF_HELPER_FLAGS_2(ieee_input_s, TCG_CALL_NO_WG, void, env, i64)
> #if !defined (CONFIG_USER_ONLY)
> DEF_HELPER_FLAGS_1(tbia, TCG_CALL_NO_RWG, void, env)
> DEF_HELPER_FLAGS_2(tbis, TCG_CALL_NO_RWG, void, env, i64)
> -DEF_HELPER_FLAGS_1(tb_flush, TCG_CALL_NO_RWG, void, env)
>
> DEF_HELPER_1(halt, void, i64)
>
> diff --git a/target/alpha/sys_helper.c b/target/alpha/sys_helper.c
> index 51e3254428..87e37605c1 100644
> --- a/target/alpha/sys_helper.c
> +++ b/target/alpha/sys_helper.c
> @@ -20,7 +20,6 @@
> #include "qemu/osdep.h"
> #include "cpu.h"
> #include "exec/cputlb.h"
> -#include "exec/tb-flush.h"
> #include "exec/helper-proto.h"
> #include "system/runstate.h"
> #include "system/system.h"
> @@ -38,11 +37,6 @@ void helper_tbis(CPUAlphaState *env, uint64_t p)
> tlb_flush_page(env_cpu(env), p);
> }
>
> -void helper_tb_flush(CPUAlphaState *env)
> -{
> - tb_flush(env_cpu(env));
> -}
> -
> void helper_halt(uint64_t restart)
> {
> if (restart) {
> diff --git a/target/alpha/translate.c b/target/alpha/translate.c
> index cebab0318c..f11b382438 100644
> --- a/target/alpha/translate.c
> +++ b/target/alpha/translate.c
> @@ -48,8 +48,6 @@ struct DisasContext {
>
> #ifdef CONFIG_USER_ONLY
> MemOp unalign;
> -#else
> - uint64_t palbr;
> #endif
> uint32_t tbflags;
> int mem_idx;
> @@ -1155,7 +1153,6 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
> #else
> {
> TCGv tmp = tcg_temp_new();
> - uint64_t entry;
>
> gen_pc_disp(ctx, tmp, 0);
> if (ctx->tbflags & ENV_FLAG_PAL_MODE) {
> @@ -1165,12 +1162,11 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
> }
> tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUAlphaState, exc_addr));
>
> - entry = ctx->palbr;
> - entry += (palcode & 0x80
> - ? 0x2000 + (palcode - 0x80) * 64
> - : 0x1000 + palcode * 64);
> -
> - tcg_gen_movi_i64(cpu_pc, entry);
> + tcg_gen_ld_i64(cpu_pc, tcg_env, offsetof(CPUAlphaState, palbr));
> + tcg_gen_addi_i64(cpu_pc, cpu_pc,
> + palcode & 0x80
> + ? 0x2000 + (palcode - 0x80) * 64
> + : 0x1000 + palcode * 64);
> return DISAS_PC_UPDATED;
> }
> #endif
> @@ -1292,11 +1288,7 @@ static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
> case 7:
> /* PALBR */
> tcg_gen_st_i64(vb, tcg_env, offsetof(CPUAlphaState, palbr));
> - /* Changing the PAL base register implies un-chaining all of the TBs
> - that ended with a CALL_PAL. Since the base register usually only
> - changes during boot, flushing everything works well. */
> - gen_helper_tb_flush(tcg_env);
> - return DISAS_PC_STALE;
> + break;
>
> case 32 ... 39:
> /* Accessing the "non-shadow" general registers. */
> @@ -2874,7 +2866,6 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
> ctx->ir = cpu_std_ir;
> ctx->unalign = (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
> #else
> - ctx->palbr = env->palbr;
> ctx->ir = (ctx->tbflags & ENV_FLAG_PAL_MODE ? cpu_pal_ir : cpu_std_ir);
> #endif
>
Probably unrelated but still same target, could you also update the
comment added in commit fe57ca82b09 ("target-alpha: Add placeholders
for missing userspace PALcalls")?
case 0x86:
/* IMB */
/* ??? We can probably elide the code using page_unprotect
that is checking for self-modifying code. Instead we
could simply call tb_flush here. Until we work out the
changes required to turn off the extra write protection,
this can be a no-op. */
break;
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 08/12] plugins: Use tb_flush__exclusive
2025-09-23 2:39 ` [PATCH v2 08/12] plugins: Use tb_flush__exclusive Richard Henderson
@ 2025-09-23 7:33 ` Philippe Mathieu-Daudé
2025-09-23 13:35 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 7:33 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier
On 23/9/25 04:39, Richard Henderson wrote:
> In all cases, we are already within start_exclusive.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Alex Bennée" <alex.bennee@linaro.org>
> Cc: Alexandre Iooss <erdnaxe@crans.org>
> Cc: Mahmoud Mandour <ma.mandourr@gmail.com>
> Cc: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
> plugins/core.c | 6 ++----
> plugins/loader.c | 2 +-
> 2 files changed, 3 insertions(+), 5 deletions(-)
To squash:
-- >8 --
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 9920381a84e..24cdb53e137 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -102,8 +102,8 @@ static TCGv_i32 gen_cpu_index(void)
/*
* Optimize when we run with a single vcpu. All values using
cpu_index,
* including scoreboard index, will be optimized out.
- * User-mode calls tb_flush when setting this flag. In system-mode, all
- * vcpus are created before generating code.
+ * User-mode calls tb_flush__exclusive when setting this flag.
+ * In system-mode, all vcpus are created before generating code.
*/
if (!tcg_cflags_has(current_cpu, CF_PARALLEL)) {
return tcg_constant_i32(current_cpu->cpu_index);
---
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v2 07/12] linux-user: Use tb_flush_exclusive to start second thread
2025-09-23 2:39 ` [PATCH v2 07/12] linux-user: Use tb_flush_exclusive to start second thread Richard Henderson
@ 2025-09-23 8:50 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 8:50 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 23/9/25 04:39, Richard Henderson wrote:
> When we start the second thread, we discard all translations
> so that we can re-do them with CF_PARALLEL. Since there is
> as yet only one cpu, and we are processing a syscall, there
> are no live translation blocks and we have exclusivity.
Maybe factor out a helper expressing that? (can be done on top,
of course).
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> linux-user/mmap.c | 4 ++--
> linux-user/syscall.c | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index 002e1e668e..bd2bbaf1f4 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -1010,7 +1010,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
> CPUState *cpu = thread_cpu;
> if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
> tcg_cflags_set(cpu, CF_PARALLEL);
> - tb_flush(cpu);
> + tb_flush__exclusive();
> }
> }
>
> @@ -1450,7 +1450,7 @@ abi_ulong target_shmat(CPUArchState *cpu_env, int shmid,
> */
> if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
> tcg_cflags_set(cpu, CF_PARALLEL);
> - tb_flush(cpu);
> + tb_flush__exclusive();
> }
>
> if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 91360a072c..d9c394856f 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -6633,7 +6633,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
> */
> if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
> tcg_cflags_set(cpu, CF_PARALLEL);
> - tb_flush(cpu);
> + tb_flush__exclusive();
> }
>
> /* we create a new CPU instance. */
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init
2025-09-23 2:39 ` [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init Richard Henderson
2025-09-23 4:49 ` Harsh Prateek Bora
@ 2025-09-23 8:55 ` Philippe Mathieu-Daudé
2025-09-23 9:45 ` Harsh Prateek Bora
2025-09-23 16:59 ` Richard Henderson
1 sibling, 2 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 8:55 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Nicholas Piggin, Harsh Prateek Bora, qemu-ppc
On 23/9/25 04:39, Richard Henderson wrote:
> We only need invalidate tbs from a single page, not flush
> all translations.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Harsh Prateek Bora <harshpb@linux.ibm.com>
> Cc: qemu-ppc@nongnu.org
> ---
> hw/ppc/spapr_hcall.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index c594d4b916..feb31d5dd8 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -8,7 +8,7 @@
> #include "qemu/main-loop.h"
> #include "qemu/module.h"
> #include "qemu/error-report.h"
> -#include "exec/tb-flush.h"
> +#include "exec/translation-block.h"
> #include "exec/target_page.h"
> #include "helper_regs.h"
> #include "hw/ppc/ppc.h"
> @@ -301,7 +301,7 @@ static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
> if (kvm_enabled()) {
> kvmppc_icbi_range(cpu, pdst, len);
> } else if (tcg_enabled()) {
> - tb_flush(CPU(cpu));
> + tb_invalidate_phys_range(CPU(cpu), dst, len);
Shouldn't this be:
tb_invalidate_phys_range(CPU(cpu), dst, dst + len - 1);
?
> } else {
> g_assert_not_reached();
> }
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 03/12] target/alpha: Simplify call_pal implementation
2025-09-23 7:30 ` Philippe Mathieu-Daudé
@ 2025-09-23 9:05 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 9:05 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 23/9/25 09:30, Philippe Mathieu-Daudé wrote:
> On 23/9/25 04:39, Richard Henderson wrote:
>> Since 288a5fe980f, we don't link translation blocks
>> directly to palcode entry points. If we load palbr
>> from env instead of encoding the constant, we avoid
>> all need for tb_flush().
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/alpha/helper.h | 1 -
>> target/alpha/sys_helper.c | 6 ------
>> target/alpha/translate.c | 21 ++++++---------------
>> 3 files changed, 6 insertions(+), 22 deletions(-)
> Probably unrelated but still same target, could you also update the
> comment added in commit fe57ca82b09 ("target-alpha: Add placeholders
> for missing userspace PALcalls")?
>
> case 0x86:
> /* IMB */
> /* ??? We can probably elide the code using page_unprotect
> that is checking for self-modifying code. Instead we
> could simply call tb_flush here. Until we work out the
> changes required to turn off the extra write protection,
> this can be a no-op. */
> break;
>
Otherwise,
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 01/12] gdbstub: Remove tb_flush uses
2025-09-23 2:39 ` [PATCH v2 01/12] gdbstub: Remove tb_flush uses Richard Henderson
@ 2025-09-23 9:11 ` Philippe Mathieu-Daudé
2025-09-23 16:23 ` Richard Henderson
0 siblings, 1 reply; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 9:11 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Pierrick Bouvier, Alex Bennée
On 23/9/25 04:39, Richard Henderson wrote:
> This hasn't been needed since d828b92b8a6
> ("accel/tcg: Introduce CF_BP_PAGE").
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Alex Bennée <alex.bennee@linaro.org>
> Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
> gdbstub/system.c | 4 ----
> gdbstub/user.c | 3 ---
> 2 files changed, 7 deletions(-)
>
> diff --git a/gdbstub/system.c b/gdbstub/system.c
> index 5be0d3c58c..df3514dc74 100644
> --- a/gdbstub/system.c
> +++ b/gdbstub/system.c
> @@ -18,7 +18,6 @@
> #include "gdbstub/syscalls.h"
> #include "gdbstub/commands.h"
> #include "exec/hwaddr.h"
> -#include "exec/tb-flush.h"
> #include "accel/accel-ops.h"
> #include "accel/accel-cpu-ops.h"
> #include "system/cpus.h"
> @@ -174,9 +173,6 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
> } else {
> trace_gdbstub_hit_break();
> }
> - if (tcg_enabled()) {
> - tb_flush(cpu);
> - }
> ret = GDB_SIGNAL_TRAP;
> break;
> case RUN_STATE_PAUSED:
To squash:
-- >8 --
diff --git a/gdbstub/system.c b/gdbstub/system.c
index f31d401e0b3..c139476bf26 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -26,3 +26,2 @@
#include "system/replay.h"
-#include "system/tcg.h"
#include "hw/core/cpu.h"
---
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v2 10/12] accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code
2025-09-23 2:39 ` [PATCH v2 10/12] accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code Richard Henderson
@ 2025-09-23 9:15 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 9:15 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 23/9/25 04:39, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/translate-all.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index d468667b0d..d7cc346414 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -288,11 +288,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s)
> assert_no_pages_locked();
> tb = tcg_tb_alloc(tcg_ctx);
> if (unlikely(!tb)) {
> - /* flush must be done */
> - tb_flush(cpu);
> mmap_unlock();
> - /* Make the execution loop process the flush as soon as possible. */
Maybe keep the comment?
> - cpu->exception_index = EXCP_INTERRUPT;
> + cpu->exception_index = EXCP_TB_FLUSH;
> cpu_loop_exit(cpu);
> }
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive
2025-09-23 2:39 ` [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive Richard Henderson
2025-09-23 7:17 ` Philippe Mathieu-Daudé
@ 2025-09-23 9:16 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 9:16 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Pierrick Bouvier
On 23/9/25 04:39, Richard Henderson wrote:
> Expose a routine to be called when no cpus are running.
> Simplify the do_tb_flush run_on_cpu callback, because
> that is explicitly called with start_exclusive; there
> is no need for the mmap_lock as well.
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/exec/tb-flush.h | 13 +++++++++++++
> accel/tcg/tb-maint.c | 33 ++++++++++++++++++++-------------
> 2 files changed, 33 insertions(+), 13 deletions(-)
>
> diff --git a/include/exec/tb-flush.h b/include/exec/tb-flush.h
> index 142c240d94..5076b13bbd 100644
> --- a/include/exec/tb-flush.h
> +++ b/include/exec/tb-flush.h
> @@ -8,6 +8,19 @@
> #ifndef _TB_FLUSH_H_
> #define _TB_FLUSH_H_
>
> +/**
> + * tb_flush__exclusive() - flush all translation blocks
> + *
> + * Used to flush all the translation blocks in the system.
> + * Sometimes it is simpler to flush everything than work out which
> + * individual translations are now invalid and ensure they are
> + * not called anymore.
> + *
> + * Must be called from an exclusive context, e.g. start_exclusive
> + * or vm_stop.
Worth mentioning it shouldn't be called from target code?
> + */
> +void tb_flush__exclusive(void);
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init
2025-09-23 8:55 ` Philippe Mathieu-Daudé
@ 2025-09-23 9:45 ` Harsh Prateek Bora
2025-09-23 16:59 ` Richard Henderson
1 sibling, 0 replies; 36+ messages in thread
From: Harsh Prateek Bora @ 2025-09-23 9:45 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Richard Henderson, qemu-devel
Cc: Nicholas Piggin, qemu-ppc
On 9/23/25 14:25, Philippe Mathieu-Daudé wrote:
> On 23/9/25 04:39, Richard Henderson wrote:
>> We only need invalidate tbs from a single page, not flush
>> all translations.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> Cc: Nicholas Piggin <npiggin@gmail.com>
>> Cc: Harsh Prateek Bora <harshpb@linux.ibm.com>
>> Cc: qemu-ppc@nongnu.org
>> ---
>> hw/ppc/spapr_hcall.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index c594d4b916..feb31d5dd8 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -8,7 +8,7 @@
>> #include "qemu/main-loop.h"
>> #include "qemu/module.h"
>> #include "qemu/error-report.h"
>> -#include "exec/tb-flush.h"
>> +#include "exec/translation-block.h"
>> #include "exec/target_page.h"
>> #include "helper_regs.h"
>> #include "hw/ppc/ppc.h"
>> @@ -301,7 +301,7 @@ static target_ulong h_page_init(PowerPCCPU *cpu,
>> SpaprMachineState *spapr,
>> if (kvm_enabled()) {
>> kvmppc_icbi_range(cpu, pdst, len);
>> } else if (tcg_enabled()) {
>> - tb_flush(CPU(cpu));
>> + tb_invalidate_phys_range(CPU(cpu), dst, len);
>
> Shouldn't this be:
>
> tb_invalidate_phys_range(CPU(cpu), dst, dst + len - 1);
>
> ?
I think you're right. I overlooked it in my review.
regards,
Harsh
>
>> } else {
>> g_assert_not_reached();
>> }
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 08/12] plugins: Use tb_flush__exclusive
2025-09-23 2:39 ` [PATCH v2 08/12] plugins: Use tb_flush__exclusive Richard Henderson
2025-09-23 7:33 ` Philippe Mathieu-Daudé
@ 2025-09-23 13:35 ` Philippe Mathieu-Daudé
2025-09-23 20:28 ` Richard Henderson
1 sibling, 1 reply; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-23 13:35 UTC (permalink / raw)
To: Richard Henderson, Pierrick Bouvier, Alex Bennée
Cc: Alexandre Iooss, qemu-devel, Mahmoud Mandour
On 23/9/25 04:39, Richard Henderson wrote:
> In all cases, we are already within start_exclusive.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Alex Bennée" <alex.bennee@linaro.org>
> Cc: Alexandre Iooss <erdnaxe@crans.org>
> Cc: Mahmoud Mandour <ma.mandourr@gmail.com>
> Cc: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
> plugins/core.c | 6 ++----
> plugins/loader.c | 2 +-
> 2 files changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/plugins/core.c b/plugins/core.c
> index c6e9ef1478..4ae1a6ae17 100644
> --- a/plugins/core.c
> +++ b/plugins/core.c
> @@ -248,7 +248,7 @@ static void plugin_grow_scoreboards__locked(CPUState *cpu)
> }
> plugin.scoreboard_alloc_size = scoreboard_size;
> /* force all tb to be flushed, as scoreboard pointers were changed. */
> - tb_flush(cpu);
> + tb_flush__exclusive();
> }
> end_exclusive();
> }
> @@ -684,8 +684,6 @@ void qemu_plugin_user_exit(void)
> * with the one in fork_start(). That is:
> * - start_exclusive(), which acquires qemu_cpu_list_lock,
> * must be called before acquiring plugin.lock.
> - * - tb_flush(), which acquires mmap_lock(), must be called
> - * while plugin.lock is not held.
> */
> start_exclusive();
>
> @@ -705,7 +703,7 @@ void qemu_plugin_user_exit(void)
> }
> qemu_rec_mutex_unlock(&plugin.lock);
>
> - tb_flush(current_cpu);
> + tb_flush__exclusive();
> end_exclusive();
>
> /* now it's safe to handle the exit case */
Hmm it seems we are triggering again the issue reported about
TARGET_NR_exit_group in https://linaro.atlassian.net/browse/QEMU-706:
"Under user emulation, threads can exit via pthread_join or at
the end of the process via exit_group syscall.
The current plugin exit hook affects all vcpus (see
qemu_plugin_disable_mem_helpers call in qemu_plugin_user_exit)."
Crash log:
qemu-loongarch64: ../../accel/tcg/tb-maint.c:94: tb_remove_all:
Assertion `have_mmap_lock()' failed.
Thread 1 "qemu-loongarch6" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6,
threadid=140737340860416) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0 __pthread_kill_implementation (no_tid=0, signo=6,
threadid=140737340860416) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=140737340860416) at
./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=140737340860416, signo=signo@entry=6)
at ./nptl/pthread_kill.c:89
#3 0x00007ffff746f476 in __GI_raise (sig=sig@entry=6) at
../sysdeps/posix/raise.c:26
#4 0x00007ffff74557f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff745571b in __assert_fail_base (fmt=0x7ffff760a130
"%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x555555733f0c
"have_mmap_lock()",
file=0x555555733ef1 "../../accel/tcg/tb-maint.c", line=94,
function=<optimized out>) at ./assert/assert.c:94
#6 0x00007ffff7466e96 in __GI___assert_fail
(assertion=assertion@entry=0x555555733f0c "have_mmap_lock()",
file=file@entry=0x555555733ef1 "../../accel/tcg/tb-maint.c",
line=line@entry=94, function=function@entry=0x555555734038
<__PRETTY_FUNCTION__.8> "tb_remove_all")
at ./assert/assert.c:103
#7 0x0000555555612e41 in tb_remove_all () at ../../accel/tcg/tb-maint.c:94
#8 tb_flush__exclusive () at ../../accel/tcg/tb-maint.c:781
#9 0x0000555555623a0c in qemu_plugin_user_exit () at
../../plugins/core.c:706
#10 0x0000555555696e54 in preexit_cleanup (env=<optimized out>,
code=code@entry=0) at ../../linux-user/exit.c:36
#11 0x00005555556b49e7 in do_syscall1 (cpu_env=<optimized out>, num=94,
arg1=0, arg2=0, arg3=-4096, arg4=4832763904, arg5=2, arg6=140737354113832,
arg8=<optimized out>, arg7=<optimized out>) at
../../linux-user/syscall.c:11199
#12 0x00005555556b966a in do_syscall
(cpu_env=cpu_env@entry=0x555555860df0, num=94, arg1=0, arg2=<optimized
out>, arg3=<optimized out>, arg4=<optimized out>,
arg5=2, arg6=140737354113832, arg7=-1, arg8=-1) at
../../linux-user/syscall.c:13929
#13 0x0000555555623d3d in cpu_loop (env=env@entry=0x555555860df0) at
../../linux-user/loongarch64/cpu_loop.c:38
#14 0x000055555558886d in main (argc=<optimized out>, argv=<optimized
out>, envp=<optimized out>) at ../../linux-user/main.c:1033
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 01/12] gdbstub: Remove tb_flush uses
2025-09-23 9:11 ` Philippe Mathieu-Daudé
@ 2025-09-23 16:23 ` Richard Henderson
0 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 16:23 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Pierrick Bouvier, Alex Bennée
On 9/23/25 02:11, Philippe Mathieu-Daudé wrote:
>> @@ -174,9 +173,6 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState
>> state)
>> } else {
>> trace_gdbstub_hit_break();
>> }
>> - if (tcg_enabled()) {
>> - tb_flush(cpu);
>> - }
>> ret = GDB_SIGNAL_TRAP;
>> break;
>> case RUN_STATE_PAUSED:
>
> To squash:
>
> -- >8 --
> diff --git a/gdbstub/system.c b/gdbstub/system.c
> index f31d401e0b3..c139476bf26 100644
> --- a/gdbstub/system.c
> +++ b/gdbstub/system.c
> @@ -26,3 +26,2 @@
> #include "system/replay.h"
> -#include "system/tcg.h"
> #include "hw/core/cpu.h"
> ---
Done, thanks.
r~
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init
2025-09-23 8:55 ` Philippe Mathieu-Daudé
2025-09-23 9:45 ` Harsh Prateek Bora
@ 2025-09-23 16:59 ` Richard Henderson
1 sibling, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 16:59 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Nicholas Piggin, Harsh Prateek Bora, qemu-ppc
On 9/23/25 01:55, Philippe Mathieu-Daudé wrote:
> On 23/9/25 04:39, Richard Henderson wrote:
>> We only need invalidate tbs from a single page, not flush
>> all translations.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> Cc: Nicholas Piggin <npiggin@gmail.com>
>> Cc: Harsh Prateek Bora <harshpb@linux.ibm.com>
>> Cc: qemu-ppc@nongnu.org
>> ---
>> hw/ppc/spapr_hcall.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index c594d4b916..feb31d5dd8 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -8,7 +8,7 @@
>> #include "qemu/main-loop.h"
>> #include "qemu/module.h"
>> #include "qemu/error-report.h"
>> -#include "exec/tb-flush.h"
>> +#include "exec/translation-block.h"
>> #include "exec/target_page.h"
>> #include "helper_regs.h"
>> #include "hw/ppc/ppc.h"
>> @@ -301,7 +301,7 @@ static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState
>> *spapr,
>> if (kvm_enabled()) {
>> kvmppc_icbi_range(cpu, pdst, len);
>> } else if (tcg_enabled()) {
>> - tb_flush(CPU(cpu));
>> + tb_invalidate_phys_range(CPU(cpu), dst, len);
>
> Shouldn't this be:
>
> tb_invalidate_phys_range(CPU(cpu), dst, dst + len - 1);
Yep, good catch.
r~
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH
2025-09-23 7:10 ` Paolo Bonzini
@ 2025-09-23 20:02 ` Richard Henderson
0 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 20:02 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel
On 9/23/25 00:10, Paolo Bonzini wrote:
> On 9/23/25 04:39, Richard Henderson wrote:
>> We are going to disallow tb_flush from within the context
>> of a running cpu. Introduce a tcg-internal exception to
>> return out of the cpu run loop and perform the flush there.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>
> One small difference is that different CPUs can fail tcg_tb_alloc() at the same time and
> flush multiple times.
>
> I think the check on the generation count should remain. Instead of introducing
> EXCP_TB_FLUSH, you can keep the guts of tb_flush() as
>
> void tb_queue_flush(CPUState *cpu)
> {
> unsigned tb_flush_count = qatomic_read(&tb_ctx.tb_flush_count);
> async_safe_run_on_cpu(cpu, do_tb_flush,
> RUN_ON_CPU_HOST_INT(tb_flush_count));
> }
>
> With the unconditional async_safe_run_on_cpu() hidden behind a function, this patch goes
> away while the next one survives as
>
> if (unlikely(!tb)) {
> - /* flush must be done */
> - tb_flush(cpu);
> mmap_unlock();
> - /* Make the execution loop process the flush as soon as possible. */
> - cpu->exception_index = EXCP_INTERRUPT;
> + tb_queue_flush(cpu);
You have a point. It's not even that unlikely a scenario.
r~
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 08/12] plugins: Use tb_flush__exclusive
2025-09-23 13:35 ` Philippe Mathieu-Daudé
@ 2025-09-23 20:28 ` Richard Henderson
2025-09-24 3:18 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2025-09-23 20:28 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Pierrick Bouvier, Alex Bennée
Cc: Alexandre Iooss, qemu-devel, Mahmoud Mandour
On 9/23/25 06:35, Philippe Mathieu-Daudé wrote:
> On 23/9/25 04:39, Richard Henderson wrote:
>> In all cases, we are already within start_exclusive.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> Cc: Alex Bennée" <alex.bennee@linaro.org>
>> Cc: Alexandre Iooss <erdnaxe@crans.org>
>> Cc: Mahmoud Mandour <ma.mandourr@gmail.com>
>> Cc: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>> plugins/core.c | 6 ++----
>> plugins/loader.c | 2 +-
>> 2 files changed, 3 insertions(+), 5 deletions(-)
>>
>> diff --git a/plugins/core.c b/plugins/core.c
>> index c6e9ef1478..4ae1a6ae17 100644
>> --- a/plugins/core.c
>> +++ b/plugins/core.c
>> @@ -248,7 +248,7 @@ static void plugin_grow_scoreboards__locked(CPUState *cpu)
>> }
>> plugin.scoreboard_alloc_size = scoreboard_size;
>> /* force all tb to be flushed, as scoreboard pointers were changed. */
>> - tb_flush(cpu);
>> + tb_flush__exclusive();
>> }
>> end_exclusive();
>> }
>> @@ -684,8 +684,6 @@ void qemu_plugin_user_exit(void)
>> * with the one in fork_start(). That is:
>> * - start_exclusive(), which acquires qemu_cpu_list_lock,
>> * must be called before acquiring plugin.lock.
>> - * - tb_flush(), which acquires mmap_lock(), must be called
>> - * while plugin.lock is not held.
>> */
>> start_exclusive();
>> @@ -705,7 +703,7 @@ void qemu_plugin_user_exit(void)
>> }
>> qemu_rec_mutex_unlock(&plugin.lock);
>> - tb_flush(current_cpu);
>> + tb_flush__exclusive();
>> end_exclusive();
>> /* now it's safe to handle the exit case */
>
> Hmm it seems we are triggering again the issue reported about
> TARGET_NR_exit_group in https://linaro.atlassian.net/browse/QEMU-706:
>
> "Under user emulation, threads can exit via pthread_join or at
> the end of the process via exit_group syscall.
>
> The current plugin exit hook affects all vcpus (see
> qemu_plugin_disable_mem_helpers call in qemu_plugin_user_exit)."
>
> Crash log:
>
> qemu-loongarch64: ../../accel/tcg/tb-maint.c:94: tb_remove_all: Assertion
> `have_mmap_lock()' failed.
>
> Thread 1 "qemu-loongarch6" received signal SIGABRT, Aborted.
> __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737340860416) at ./nptl/
> pthread_kill.c:44
> 44 ./nptl/pthread_kill.c: No such file or directory.
> (gdb) bt
> #0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737340860416) at ./nptl/
> pthread_kill.c:44
> #1 __pthread_kill_internal (signo=6, threadid=140737340860416) at ./nptl/pthread_kill.c:78
> #2 __GI___pthread_kill (threadid=140737340860416, signo=signo@entry=6) at ./nptl/
> pthread_kill.c:89
> #3 0x00007ffff746f476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
> #4 0x00007ffff74557f3 in __GI_abort () at ./stdlib/abort.c:79
> #5 0x00007ffff745571b in __assert_fail_base (fmt=0x7ffff760a130 "%s%s%s:%u: %s%sAssertion
> `%s' failed.\n%n", assertion=0x555555733f0c "have_mmap_lock()",
> file=0x555555733ef1 "../../accel/tcg/tb-maint.c", line=94, function=<optimized out>)
> at ./assert/assert.c:94
> #6 0x00007ffff7466e96 in __GI___assert_fail (assertion=assertion@entry=0x555555733f0c
> "have_mmap_lock()",
> file=file@entry=0x555555733ef1 "../../accel/tcg/tb-maint.c", line=line@entry=94,
> function=function@entry=0x555555734038 <__PRETTY_FUNCTION__.8> "tb_remove_all")
> at ./assert/assert.c:103
> #7 0x0000555555612e41 in tb_remove_all () at ../../accel/tcg/tb-maint.c:94
> #8 tb_flush__exclusive () at ../../accel/tcg/tb-maint.c:781
> #9 0x0000555555623a0c in qemu_plugin_user_exit () at ../../plugins/core.c:706
> #10 0x0000555555696e54 in preexit_cleanup (env=<optimized out>, code=code@entry=0)
> at ../../linux-user/exit.c:36
I fixed this by replacing the assert in the user-only version of tb_remove_all.
r~
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 08/12] plugins: Use tb_flush__exclusive
2025-09-23 20:28 ` Richard Henderson
@ 2025-09-24 3:18 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-24 3:18 UTC (permalink / raw)
To: Richard Henderson, Pierrick Bouvier, Alex Bennée
Cc: Alexandre Iooss, qemu-devel, Mahmoud Mandour
On 23/9/25 22:28, Richard Henderson wrote:
> On 9/23/25 06:35, Philippe Mathieu-Daudé wrote:
>> On 23/9/25 04:39, Richard Henderson wrote:
>>> In all cases, we are already within start_exclusive.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>> Cc: Alex Bennée" <alex.bennee@linaro.org>
>>> Cc: Alexandre Iooss <erdnaxe@crans.org>
>>> Cc: Mahmoud Mandour <ma.mandourr@gmail.com>
>>> Cc: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>>> ---
>>> plugins/core.c | 6 ++----
>>> plugins/loader.c | 2 +-
>>> 2 files changed, 3 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/plugins/core.c b/plugins/core.c
>>> index c6e9ef1478..4ae1a6ae17 100644
>>> --- a/plugins/core.c
>>> +++ b/plugins/core.c
>>> @@ -248,7 +248,7 @@ static void
>>> plugin_grow_scoreboards__locked(CPUState *cpu)
>>> }
>>> plugin.scoreboard_alloc_size = scoreboard_size;
>>> /* force all tb to be flushed, as scoreboard pointers were
>>> changed. */
>>> - tb_flush(cpu);
>>> + tb_flush__exclusive();
>>> }
>>> end_exclusive();
>>> }
>>> @@ -684,8 +684,6 @@ void qemu_plugin_user_exit(void)
>>> * with the one in fork_start(). That is:
>>> * - start_exclusive(), which acquires qemu_cpu_list_lock,
>>> * must be called before acquiring plugin.lock.
>>> - * - tb_flush(), which acquires mmap_lock(), must be called
>>> - * while plugin.lock is not held.
>>> */
>>> start_exclusive();
>>> @@ -705,7 +703,7 @@ void qemu_plugin_user_exit(void)
>>> }
>>> qemu_rec_mutex_unlock(&plugin.lock);
>>> - tb_flush(current_cpu);
>>> + tb_flush__exclusive();
>>> end_exclusive();
>>> /* now it's safe to handle the exit case */
>>
>> Hmm it seems we are triggering again the issue reported about
>> TARGET_NR_exit_group in https://linaro.atlassian.net/browse/QEMU-706:
>>
>> "Under user emulation, threads can exit via pthread_join or at
>> the end of the process via exit_group syscall.
>>
>> The current plugin exit hook affects all vcpus (see
>> qemu_plugin_disable_mem_helpers call in qemu_plugin_user_exit)."
>>
>> Crash log:
>>
>> qemu-loongarch64: ../../accel/tcg/tb-maint.c:94: tb_remove_all:
>> Assertion `have_mmap_lock()' failed.
>>
>> Thread 1 "qemu-loongarch6" received signal SIGABRT, Aborted.
>> __pthread_kill_implementation (no_tid=0, signo=6,
>> threadid=140737340860416) at ./nptl/ pthread_kill.c:44
>> 44 ./nptl/pthread_kill.c: No such file or directory.
>> (gdb) bt
>> #0 __pthread_kill_implementation (no_tid=0, signo=6,
>> threadid=140737340860416) at ./nptl/ pthread_kill.c:44
>> #1 __pthread_kill_internal (signo=6, threadid=140737340860416) at ./
>> nptl/pthread_kill.c:78
>> #2 __GI___pthread_kill (threadid=140737340860416,
>> signo=signo@entry=6) at ./nptl/ pthread_kill.c:89
>> #3 0x00007ffff746f476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/
>> posix/raise.c:26
>> #4 0x00007ffff74557f3 in __GI_abort () at ./stdlib/abort.c:79
>> #5 0x00007ffff745571b in __assert_fail_base (fmt=0x7ffff760a130
>> "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x555555733f0c
>> "have_mmap_lock()",
>> file=0x555555733ef1 "../../accel/tcg/tb-maint.c", line=94,
>> function=<optimized out>) at ./assert/assert.c:94
>> #6 0x00007ffff7466e96 in __GI___assert_fail
>> (assertion=assertion@entry=0x555555733f0c "have_mmap_lock()",
>> file=file@entry=0x555555733ef1 "../../accel/tcg/tb-maint.c",
>> line=line@entry=94, function=function@entry=0x555555734038
>> <__PRETTY_FUNCTION__.8> "tb_remove_all")
>> at ./assert/assert.c:103
>> #7 0x0000555555612e41 in tb_remove_all () at ../../accel/tcg/tb-
>> maint.c:94
>> #8 tb_flush__exclusive () at ../../accel/tcg/tb-maint.c:781
>> #9 0x0000555555623a0c in qemu_plugin_user_exit () at ../../plugins/
>> core.c:706
>> #10 0x0000555555696e54 in preexit_cleanup (env=<optimized out>,
>> code=code@entry=0) at ../../linux-user/exit.c:36
>
> I fixed this by replacing the assert in the user-only version of
> tb_remove_all.
Clever shortcut :)
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base
2025-09-23 2:39 ` [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base Richard Henderson
@ 2025-09-24 6:17 ` LIU Zhiwei
2025-09-24 12:23 ` Daniel Henrique Barboza
2025-09-28 23:10 ` Alistair Francis
2 siblings, 0 replies; 36+ messages in thread
From: LIU Zhiwei @ 2025-09-24 6:17 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Pierrick Bouvier, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, qemu-riscv
On 9/23/25 10:39 AM, Richard Henderson wrote:
> The tb_flush within write_misa was incorrect. It assumed
> that we could adjust the ISA of the current processor and
> discard all TB and all would be well. But MISA is per vcpu,
> so globally flushing TB does not mean that the TB matches
> the MISA of any given vcpu.
>
> By recording misa in the tb state, we ensure that the code
> generated matches the vcpu.
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> Cc: Alistair Francis <alistair.francis@wdc.com>
> Cc: Weiwei Li <liwei1518@gmail.com>
> Cc: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Cc: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
> Cc: qemu-riscv@nongnu.org
> ---
> target/riscv/csr.c | 3 ---
> target/riscv/tcg/tcg-cpu.c | 3 ++-
> 2 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 8842e07a73..3c8989f522 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -25,7 +25,6 @@
> #include "pmu.h"
> #include "time_helper.h"
> #include "exec/cputlb.h"
> -#include "exec/tb-flush.h"
> #include "exec/icount.h"
> #include "accel/tcg/getpc.h"
> #include "qemu/guest-random.h"
> @@ -2173,8 +2172,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
> env->mstatus &= ~MSTATUS_FS;
> }
>
> - /* flush translation cache */
> - tb_flush(env_cpu(env));
> env->xl = riscv_cpu_mxl(env);
> return RISCV_EXCP_NONE;
> }
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 78fb279184..143ab079d4 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -191,7 +191,8 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>
> return (TCGTBCPUState){
> .pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
> - .flags = flags
> + .flags = flags,
> + .cs_base = env->misa_ext,
> };
I hope reserve some tb flags for custom use in the future. As
env->misa_ext is 32 bit and cs_base is 64 bit, I think the other fields
are enough for custom use.
As we have move misa_ext to tb flags, I think we should also modify the
riscv_tr_init_disas_context for ctx->misa_ext assignment.
-ctx->misa_ext = env->misa_ext;
+ctx->misa_ext = (uint32_t)ctx->base.tb->cflags;
to make it explicitly we should not use variable status in env.
Otherwise,
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Zhiwei
> }
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base
2025-09-23 2:39 ` [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base Richard Henderson
2025-09-24 6:17 ` LIU Zhiwei
@ 2025-09-24 12:23 ` Daniel Henrique Barboza
2025-09-28 23:10 ` Alistair Francis
2 siblings, 0 replies; 36+ messages in thread
From: Daniel Henrique Barboza @ 2025-09-24 12:23 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Pierrick Bouvier, Alistair Francis, Weiwei Li, Liu Zhiwei,
qemu-riscv
On 9/22/25 11:39 PM, Richard Henderson wrote:
> The tb_flush within write_misa was incorrect. It assumed
> that we could adjust the ISA of the current processor and
> discard all TB and all would be well. But MISA is per vcpu,
> so globally flushing TB does not mean that the TB matches
> the MISA of any given vcpu.
>
> By recording misa in the tb state, we ensure that the code
> generated matches the vcpu.
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Cc: Alistair Francis <alistair.francis@wdc.com>
> Cc: Weiwei Li <liwei1518@gmail.com>
> Cc: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Cc: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
> Cc: qemu-riscv@nongnu.org
> ---
> target/riscv/csr.c | 3 ---
> target/riscv/tcg/tcg-cpu.c | 3 ++-
> 2 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 8842e07a73..3c8989f522 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -25,7 +25,6 @@
> #include "pmu.h"
> #include "time_helper.h"
> #include "exec/cputlb.h"
> -#include "exec/tb-flush.h"
> #include "exec/icount.h"
> #include "accel/tcg/getpc.h"
> #include "qemu/guest-random.h"
> @@ -2173,8 +2172,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
> env->mstatus &= ~MSTATUS_FS;
> }
>
> - /* flush translation cache */
> - tb_flush(env_cpu(env));
> env->xl = riscv_cpu_mxl(env);
> return RISCV_EXCP_NONE;
> }
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 78fb279184..143ab079d4 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -191,7 +191,8 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>
> return (TCGTBCPUState){
> .pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
> - .flags = flags
> + .flags = flags,
> + .cs_base = env->misa_ext,
> };
> }
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base
2025-09-23 2:39 ` [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base Richard Henderson
2025-09-24 6:17 ` LIU Zhiwei
2025-09-24 12:23 ` Daniel Henrique Barboza
@ 2025-09-28 23:10 ` Alistair Francis
2 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2025-09-28 23:10 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, Pierrick Bouvier, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, qemu-riscv
On Tue, Sep 23, 2025 at 12:43 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The tb_flush within write_misa was incorrect. It assumed
> that we could adjust the ISA of the current processor and
> discard all TB and all would be well. But MISA is per vcpu,
> so globally flushing TB does not mean that the TB matches
> the MISA of any given vcpu.
>
> By recording misa in the tb state, we ensure that the code
> generated matches the vcpu.
>
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> Cc: Alistair Francis <alistair.francis@wdc.com>
> Cc: Weiwei Li <liwei1518@gmail.com>
> Cc: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Cc: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
> Cc: qemu-riscv@nongnu.org
> ---
> target/riscv/csr.c | 3 ---
> target/riscv/tcg/tcg-cpu.c | 3 ++-
> 2 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 8842e07a73..3c8989f522 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -25,7 +25,6 @@
> #include "pmu.h"
> #include "time_helper.h"
> #include "exec/cputlb.h"
> -#include "exec/tb-flush.h"
> #include "exec/icount.h"
> #include "accel/tcg/getpc.h"
> #include "qemu/guest-random.h"
> @@ -2173,8 +2172,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
> env->mstatus &= ~MSTATUS_FS;
> }
>
> - /* flush translation cache */
> - tb_flush(env_cpu(env));
> env->xl = riscv_cpu_mxl(env);
> return RISCV_EXCP_NONE;
> }
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 78fb279184..143ab079d4 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -191,7 +191,8 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>
> return (TCGTBCPUState){
> .pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
> - .flags = flags
> + .flags = flags,
> + .cs_base = env->misa_ext,
> };
> }
>
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2025-09-28 23:13 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-23 2:39 [PATCH v2 00/12] accel/tcg: Improve tb_flush usage Richard Henderson
2025-09-23 2:39 ` [PATCH v2 01/12] gdbstub: Remove tb_flush uses Richard Henderson
2025-09-23 9:11 ` Philippe Mathieu-Daudé
2025-09-23 16:23 ` Richard Henderson
2025-09-23 2:39 ` [PATCH v2 02/12] accel/tcg: Split out tb_flush__exclusive Richard Henderson
2025-09-23 7:17 ` Philippe Mathieu-Daudé
2025-09-23 9:16 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 03/12] target/alpha: Simplify call_pal implementation Richard Henderson
2025-09-23 7:30 ` Philippe Mathieu-Daudé
2025-09-23 9:05 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 04/12] target/riscv: Record misa_ext in TCGTBCPUState.cs_base Richard Henderson
2025-09-24 6:17 ` LIU Zhiwei
2025-09-24 12:23 ` Daniel Henrique Barboza
2025-09-28 23:10 ` Alistair Francis
2025-09-23 2:39 ` [PATCH v2 05/12] accel/tcg: Move post-load tb_flush to vm_change_state hook Richard Henderson
2025-09-23 7:22 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 06/12] hw/ppc/spapr: Use tb_invalidate_phys_range in h_page_init Richard Henderson
2025-09-23 4:49 ` Harsh Prateek Bora
2025-09-23 8:55 ` Philippe Mathieu-Daudé
2025-09-23 9:45 ` Harsh Prateek Bora
2025-09-23 16:59 ` Richard Henderson
2025-09-23 2:39 ` [PATCH v2 07/12] linux-user: Use tb_flush_exclusive to start second thread Richard Henderson
2025-09-23 8:50 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 08/12] plugins: Use tb_flush__exclusive Richard Henderson
2025-09-23 7:33 ` Philippe Mathieu-Daudé
2025-09-23 13:35 ` Philippe Mathieu-Daudé
2025-09-23 20:28 ` Richard Henderson
2025-09-24 3:18 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 09/12] accel/tcg: Introduce EXCP_TB_FLUSH Richard Henderson
2025-09-23 7:10 ` Paolo Bonzini
2025-09-23 20:02 ` Richard Henderson
2025-09-23 2:39 ` [PATCH v2 10/12] accel/tcg: Use EXCP_TB_FLUSH in tb_gen_code Richard Henderson
2025-09-23 9:15 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 11/12] accel/tcg: Remove tb_flush Richard Henderson
2025-09-23 7:24 ` Philippe Mathieu-Daudé
2025-09-23 2:39 ` [PATCH v2 12/12] accel/tcg: Tighten assert in tb_flush__exclusive Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).