Blame SOURCES/kvm-monitor-fix-dangling-CPU-pointer.patch

9bac43
From 062ffad79316d7c3a2ace6d96ffc1f90d61469ec Mon Sep 17 00:00:00 2001
9bac43
From: Serhii Popovych <spopovyc@redhat.com>
9bac43
Date: Wed, 8 Nov 2017 13:35:20 +0100
9bac43
Subject: [PATCH 2/7] monitor: fix dangling CPU pointer
9bac43
9bac43
RH-Author: Serhii Popovych <spopovyc@redhat.com>
9bac43
Message-id: <1510148120-54741-1-git-send-email-spopovyc@redhat.com>
9bac43
Patchwork-id: 77520
9bac43
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2] monitor: fix dangling CPU pointer
9bac43
Bugzilla: 1510001
9bac43
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
9bac43
RH-Acked-by: David Hildenbrand <david@redhat.com>
9bac43
RH-Acked-by: Peter Xu <peterx@redhat.com>
9bac43
9bac43
From: Greg Kurz <groug@kaod.org>
9bac43
9bac43
Test: replay case as described in comment 4 on bz: qemu does not crash
9bac43
9bac43
If a CPU selected with the "cpu" command is hot-unplugged then "info cpus"
9bac43
causes QEMU to exit:
9bac43
9bac43
(qemu) device_del cpu1
9bac43
(qemu) info cpus
9bac43
qemu:qemu_cpu_kick_thread: No such process
9bac43
9bac43
This happens because "cpu" stores the pointer to the selected CPU into
9bac43
the monitor structure. When the CPU is hot-unplugged, we end up with a
9bac43
dangling pointer. The "info cpus" command then does:
9bac43
9bac43
hmp_info_cpus()
9bac43
 monitor_get_cpu_index()
9bac43
  mon_get_cpu()
9bac43
   cpu_synchronize_state() <--- called with dangling pointer
9bac43
9bac43
This could cause a QEMU crash as well.
9bac43
9bac43
This patch switches the monitor to store the QOM path instead of a
9bac43
pointer to the current CPU. The path is then resolved when needed.
9bac43
If the resolution fails, we assume that the CPU was removed and the
9bac43
path is resetted to the default (ie, path of first_cpu).
9bac43
9bac43
Reported-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
9bac43
Suggested-by: Igor Mammedov <imammedo@redhat.com>
9bac43
Signed-off-by: Greg Kurz <groug@kaod.org>
9bac43
Message-Id: <150822818243.26242.12993827911736928961.stgit@bahia.lan>
9bac43
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9bac43
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9bac43
(cherry picked from commit 751f8cfe2a556b3ef49f6af2860e2d1d2a1ec66a)
9bac43
Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
9bac43
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9bac43
---
9bac43
 monitor.c | 23 ++++++++++++++++++-----
9bac43
 1 file changed, 18 insertions(+), 5 deletions(-)
9bac43
9bac43
diff --git a/monitor.c b/monitor.c
9bac43
index bade261..c0a8dbc 100644
9bac43
--- a/monitor.c
9bac43
+++ b/monitor.c
9bac43
@@ -200,7 +200,7 @@ struct Monitor {
9bac43
 
9bac43
     ReadLineState *rs;
9bac43
     MonitorQMP qmp;
9bac43
-    CPUState *mon_cpu;
9bac43
+    gchar *mon_cpu_path;
9bac43
     BlockCompletionFunc *password_completion_cb;
9bac43
     void *password_opaque;
9bac43
     mon_cmd_t *cmd_table;
9bac43
@@ -579,6 +579,7 @@ static void monitor_data_init(Monitor *mon)
9bac43
 
9bac43
 static void monitor_data_destroy(Monitor *mon)
9bac43
 {
9bac43
+    g_free(mon->mon_cpu_path);
9bac43
     qemu_chr_fe_deinit(&mon->chr, false);
9bac43
     if (monitor_is_qmp(mon)) {
9bac43
         json_message_parser_destroy(&mon->qmp.parser);
9bac43
@@ -1065,20 +1066,32 @@ int monitor_set_cpu(int cpu_index)
9bac43
     if (cpu == NULL) {
9bac43
         return -1;
9bac43
     }
9bac43
-    cur_mon->mon_cpu = cpu;
9bac43
+    g_free(cur_mon->mon_cpu_path);
9bac43
+    cur_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
9bac43
     return 0;
9bac43
 }
9bac43
 
9bac43
 CPUState *mon_get_cpu(void)
9bac43
 {
9bac43
-    if (!cur_mon->mon_cpu) {
9bac43
+    CPUState *cpu;
9bac43
+
9bac43
+    if (cur_mon->mon_cpu_path) {
9bac43
+        cpu = (CPUState *) object_resolve_path_type(cur_mon->mon_cpu_path,
9bac43
+                                                    TYPE_CPU, NULL);
9bac43
+        if (!cpu) {
9bac43
+            g_free(cur_mon->mon_cpu_path);
9bac43
+            cur_mon->mon_cpu_path = NULL;
9bac43
+        }
9bac43
+    }
9bac43
+    if (!cur_mon->mon_cpu_path) {
9bac43
         if (!first_cpu) {
9bac43
             return NULL;
9bac43
         }
9bac43
         monitor_set_cpu(first_cpu->cpu_index);
9bac43
+        cpu = first_cpu;
9bac43
     }
9bac43
-    cpu_synchronize_state(cur_mon->mon_cpu);
9bac43
-    return cur_mon->mon_cpu;
9bac43
+    cpu_synchronize_state(cpu);
9bac43
+    return cpu;
9bac43
 }
9bac43
 
9bac43
 CPUArchState *mon_get_cpu_env(void)
9bac43
-- 
9bac43
1.8.3.1
9bac43