Blame SOURCES/kvm-coroutine-win32-use-QEMU_DEFINE_STATIC_CO_TLS.patch

586cba
From 336581e6e9ace3f1ddd24ad0a258db9785f9b0ed Mon Sep 17 00:00:00 2001
586cba
From: Stefan Hajnoczi <stefanha@redhat.com>
586cba
Date: Tue, 17 May 2022 12:08:12 +0100
586cba
Subject: [PATCH 3/6] coroutine-win32: use QEMU_DEFINE_STATIC_CO_TLS()
586cba
MIME-Version: 1.0
586cba
Content-Type: text/plain; charset=UTF-8
586cba
Content-Transfer-Encoding: 8bit
586cba
586cba
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
586cba
RH-MergeRequest: 89: coroutine: use coroutine TLS macros to protect thread-local variables
586cba
RH-Commit: [3/3] 55b35dfdae1bc7d6f614ac9f81a92f5c6431f713 (stefanha/centos-stream-qemu-kvm)
586cba
RH-Bugzilla: 1952483
586cba
RH-Acked-by: Hanna Reitz <hreitz@redhat.com>
586cba
RH-Acked-by: Eric Blake <eblake@redhat.com>
586cba
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
586cba
586cba
Thread-Local Storage variables cannot be used directly from coroutine
586cba
code because the compiler may optimize TLS variable accesses across
586cba
qemu_coroutine_yield() calls. When the coroutine is re-entered from
586cba
another thread the TLS variables from the old thread must no longer be
586cba
used.
586cba
586cba
Use QEMU_DEFINE_STATIC_CO_TLS() for the current and leader variables.
586cba
586cba
I think coroutine-win32.c could get away with __thread because the
586cba
variables are only used in situations where either the stale value is
586cba
correct (current) or outside coroutine context (loading leader when
586cba
current is NULL). Due to the difficulty of being sure that this is
586cba
really safe in all scenarios it seems worth converting it anyway.
586cba
586cba
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
586cba
Message-Id: <20220307153853.602859-4-stefanha@redhat.com>
586cba
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
586cba
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
586cba
(cherry picked from commit c1fe694357a328c807ae3cc6961c19e923448fcc)
586cba
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
586cba
---
586cba
 util/coroutine-win32.c | 18 +++++++++++++-----
586cba
 1 file changed, 13 insertions(+), 5 deletions(-)
586cba
586cba
diff --git a/util/coroutine-win32.c b/util/coroutine-win32.c
586cba
index de6bd4fd3e..c02a62c896 100644
586cba
--- a/util/coroutine-win32.c
586cba
+++ b/util/coroutine-win32.c
586cba
@@ -25,6 +25,7 @@
586cba
 #include "qemu/osdep.h"
586cba
 #include "qemu-common.h"
586cba
 #include "qemu/coroutine_int.h"
586cba
+#include "qemu/coroutine-tls.h"
586cba
 
586cba
 typedef struct
586cba
 {
586cba
@@ -34,8 +35,8 @@ typedef struct
586cba
     CoroutineAction action;
586cba
 } CoroutineWin32;
586cba
 
586cba
-static __thread CoroutineWin32 leader;
586cba
-static __thread Coroutine *current;
586cba
+QEMU_DEFINE_STATIC_CO_TLS(CoroutineWin32, leader);
586cba
+QEMU_DEFINE_STATIC_CO_TLS(Coroutine *, current);
586cba
 
586cba
 /* This function is marked noinline to prevent GCC from inlining it
586cba
  * into coroutine_trampoline(). If we allow it to do that then it
586cba
@@ -52,7 +53,7 @@ qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
586cba
     CoroutineWin32 *from = DO_UPCAST(CoroutineWin32, base, from_);
586cba
     CoroutineWin32 *to = DO_UPCAST(CoroutineWin32, base, to_);
586cba
 
586cba
-    current = to_;
586cba
+    set_current(to_);
586cba
 
586cba
     to->action = action;
586cba
     SwitchToFiber(to->fiber);
586cba
@@ -89,14 +90,21 @@ void qemu_coroutine_delete(Coroutine *co_)
586cba
 
586cba
 Coroutine *qemu_coroutine_self(void)
586cba
 {
586cba
+    Coroutine *current = get_current();
586cba
+
586cba
     if (!current) {
586cba
-        current = &leader.base;
586cba
-        leader.fiber = ConvertThreadToFiber(NULL);
586cba
+        CoroutineWin32 *leader = get_ptr_leader();
586cba
+
586cba
+        current = &leader->base;
586cba
+        set_current(current);
586cba
+        leader->fiber = ConvertThreadToFiber(NULL);
586cba
     }
586cba
     return current;
586cba
 }
586cba
 
586cba
 bool qemu_in_coroutine(void)
586cba
 {
586cba
+    Coroutine *current = get_current();
586cba
+
586cba
     return current && current->caller;
586cba
 }
586cba
-- 
586cba
2.31.1
586cba