Patchwork tcg: Reload local variables after return from longjmp

login
register
mail settings
Submitter Paolo Bonzini
Date Aug. 11, 2011, 2:32 p.m.
Message ID <4E43E808.4090100@redhat.com>
Download mbox | patch
Permalink /patch/109615/
State New
Headers show

Comments

Paolo Bonzini - Aug. 11, 2011, 2:32 p.m.
On 08/11/2011 04:24 PM, Peter Maydell wrote:
>> I cannot think off-hand of a reason why thread-local cpu_single_env should
>> not work for iothread under Unix, BTW.  Since cpu_single_env is only
>> set/used by a thread at a time (under the global lock), its users cannot
>> distinguish between a thread-local variable and a global.
>
> Thanks for the clarification. As you say, as long as we don't ever
> try to access it from another thread we're fine...

Yes, and the current usage of the lock should be enough of a guarantee.

>> The only problem would be Windows, which runs cpu_signal in a thread
>> different than the CPU thread.  But that can be fixed easily in
>> qemu_cpu_kick_thread.
>
> ...and we just need to fix this.

Untested (uncompiled) patch follows:

Patch

diff --git a/cpus.c b/cpus.c
index 6bf4e3f..04e52fe 100644
--- a/cpus.c
+++ b/cpus.c
@@ -179,10 +179,10 @@  static void cpu_handle_guest_debug(CPUState *env)
  }

  #ifdef CONFIG_IOTHREAD
-static void cpu_signal(int sig)
+static inline void do_cpu_kick(CPUState *env)
  {
-    if (cpu_single_env) {
-        cpu_exit(cpu_single_env);
+    if (env) {
+        cpu_exit(env);
      }
      exit_request = 1;
  }
@@ -476,6 +476,13 @@  static void qemu_kvm_init_cpu_signals(CPUState *env)
      }
  }

+#ifdef CONFIG_IOTHREAD
+static void cpu_signal(int sig)
+{
+    do_cpu_kick(cpu_single_env);
+}
+#endif
+
  static void qemu_tcg_init_cpu_signals(void)
  {
  #ifdef CONFIG_IOTHREAD
@@ -858,7 +865,7 @@  static void qemu_cpu_kick_thread(CPUState *env)
  #else /* _WIN32 */
      if (!qemu_cpu_is_self(env)) {
          SuspendThread(env->thread->thread);
-        cpu_signal(0);
+        do_cpu_kick(env);
          ResumeThread(env->thread->thread);
      }
  #endif