On 1/28/25 06:21, Philippe Mathieu-Daudé wrote:
Invalidate TB with global vCPU queue locked.
See commit 4731f89b3b9 ("cpu: free cpu->tb_jmp_cache with RCU"):
Fixes the appended use-after-free. The root cause is that
during tb invalidation we use CPU_FOREACH, and therefore
to safely free a vCPU we must wait for an RCU grace period
to elapse.
Signed-off-by: Philippe Mathieu-Daudé <philmd@xxxxxxxxxx>
---
accel/tcg/tb-maint.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 3f1bebf6ab5..64471af439d 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -891,6 +891,8 @@ static void tb_jmp_cache_inval_tb(TranslationBlock *tb)
} else {
uint32_t h = tb_jmp_cache_hash_func(tb->pc);
+ QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
+
CPU_FOREACH(cpu) {
CPUJumpCache *jc = cpu->tb_jmp_cache;
I can see how maybe this can appear to fix the bug, because one can't remove cpus at all
while the lock is held. But if the description is accurate that this is RCU related, then
the proper locking is with rcu_read_lock/rcu_read_unlock.
r~