diff mbox series

[RFC,11/26] softmmu: Add pause_all_vcpus_except_aux

Message ID 20210302204822.81901-12-dovmurik@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show
Series Confidential guest live migration | expand

Commit Message

Dov Murik March 2, 2021, 8:48 p.m. UTC
From: Tobin Feldman-Fitzthum <tobin@linux.ibm.com>

Introduce a function to pause all CPUs except the auxiliary CPUs.  This
will be used during migration when a migration handler is running on the
auxiliary CPU.

Co-Author: Dov Murik <dovmurik@linux.vnet.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.vnet.ibm.com>
Signed-off-by: Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
---
 include/sysemu/cpus.h |  1 +
 softmmu/cpus.c        | 53 +++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 52 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index dc24e38254..e668570053 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -34,6 +34,7 @@  bool qemu_in_vcpu_thread(void);
 void qemu_init_cpu_loop(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
+void pause_all_vcpus_except_aux(void);
 void cpu_stop_current(void);
 
 extern int icount_align_option;
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index 68fa4639a7..3028b5d0d4 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -550,6 +550,19 @@  static bool all_vcpus_paused(void)
     return true;
 }
 
+static bool all_vcpus_except_aux_paused(void)
+{
+    CPUState *cpu;
+
+    CPU_FOREACH(cpu) {
+        if (!cpu->aux && !cpu->stopped) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 void pause_all_vcpus(void)
 {
     CPUState *cpu;
@@ -564,15 +577,51 @@  void pause_all_vcpus(void)
         }
     }
 
+    /*
+     * Drop the replay_lock so any vCPU threads woken up can finish their
+     * replay tasks
+     */
+    replay_mutex_unlock();
+
+    while (!all_vcpus_paused()) {
+        qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
+        CPU_FOREACH(cpu) {
+            qemu_cpu_kick(cpu);
+        }
+    }
+
+    qemu_mutex_unlock_iothread();
+    replay_mutex_lock();
+    qemu_mutex_lock_iothread();
+}
+
+void pause_all_vcpus_except_aux(void)
+{
+    CPUState *cpu;
+
+    qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
+    CPU_FOREACH(cpu) {
+        if (!cpu->aux) {
+            if (qemu_cpu_is_self(cpu)) {
+                qemu_cpu_stop(cpu, true);
+            } else {
+                cpu->stop = true;
+                qemu_cpu_kick(cpu);
+            }
+        }
+    }
+
     /* We need to drop the replay_lock so any vCPU threads woken up
      * can finish their replay tasks
      */
     replay_mutex_unlock();
 
-    while (!all_vcpus_paused()) {
+    while (!all_vcpus_except_aux_paused()) {
         qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
         CPU_FOREACH(cpu) {
-            qemu_cpu_kick(cpu);
+            if (!cpu->aux) {
+                qemu_cpu_kick(cpu);
+            }
         }
     }