diff mbox series

[RFC,2/9] accel/tcg: Invalidate TB jump cache with global vCPU queue locked

Message ID 20250128142152.9889-3-philmd@linaro.org (mailing list archive)
State New
Headers show
Series accel: Only include qdev-realized vCPUs in global &cpus_queue | expand

Commit Message

Philippe Mathieu-Daudé Jan. 28, 2025, 2:21 p.m. UTC
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@linaro.org>
---
 accel/tcg/tb-maint.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Richard Henderson Jan. 28, 2025, 8:05 p.m. UTC | #1
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@linaro.org>
> ---
>   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~
diff mbox series

Patch

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;