thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-softmmu-fix-device-deletion-events-with-device-JSON-.patch

495e37
From 005339f7deaee639c38d30e5bf2235c292ce3937 Mon Sep 17 00:00:00 2001
495e37
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
495e37
Date: Wed, 5 Jan 2022 12:38:47 +0000
495e37
Subject: [PATCH 3/3] softmmu: fix device deletion events with -device JSON
495e37
 syntax
495e37
MIME-Version: 1.0
495e37
Content-Type: text/plain; charset=UTF-8
495e37
Content-Transfer-Encoding: 8bit
495e37
495e37
RH-Author: Kevin Wolf <kwolf@redhat.com>
495e37
RH-MergeRequest: 62: Fix hot unplug of devices created with -device JSON syntax
495e37
RH-Commit: [1/1] 980e505ba215b5f9324c107481c5bb257ae03f42 (kmwolf/centos-qemu-kvm)
495e37
RH-Bugzilla: 2036669
495e37
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
495e37
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
495e37
RH-Acked-by: Jano Tomko <None>
495e37
495e37
The -device JSON syntax impl leaks a reference on the created
495e37
DeviceState instance. As a result when you hot-unplug the
495e37
device, the device_finalize method won't be called and thus
495e37
it will fail to emit the required DEVICE_DELETED event.
495e37
495e37
A 'json-cli' feature was previously added against the
495e37
'device_add' QMP command QAPI schema to indicated to mgmt
495e37
apps that -device supported JSON syntax. Given the hotplug
495e37
bug that feature flag is not usable for its purpose, so
495e37
we add a new 'json-cli-hotplug' feature to indicate the
495e37
-device supports JSON without breaking hotplug.
495e37
495e37
Fixes: 5dacda5167560b3af8eadbce5814f60ba44b467e
495e37
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/802
495e37
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
495e37
Message-Id: <20220105123847.4047954-2-berrange@redhat.com>
495e37
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
495e37
Tested-by: Ján Tomko <jtomko@redhat.com>
495e37
Reviewed-by: Thomas Huth <thuth@redhat.com>
495e37
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
495e37
(cherry picked from commit 64b4529a432507ee84a924be69a03432639e87ba)
495e37
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
495e37
---
495e37
 qapi/qdev.json                 |  5 ++++-
495e37
 softmmu/vl.c                   |  4 +++-
495e37
 tests/qtest/device-plug-test.c | 19 +++++++++++++++++++
495e37
 3 files changed, 26 insertions(+), 2 deletions(-)
495e37
495e37
diff --git a/qapi/qdev.json b/qapi/qdev.json
495e37
index 69656b14df..26cd10106b 100644
495e37
--- a/qapi/qdev.json
495e37
+++ b/qapi/qdev.json
495e37
@@ -44,6 +44,9 @@
495e37
 # @json-cli: If present, the "-device" command line option supports JSON
495e37
 #            syntax with a structure identical to the arguments of this
495e37
 #            command.
495e37
+# @json-cli-hotplug: If present, the "-device" command line option supports JSON
495e37
+#                    syntax without the reference counting leak that broke
495e37
+#                    hot-unplug
495e37
 #
495e37
 # Notes:
495e37
 #
495e37
@@ -74,7 +77,7 @@
495e37
 { 'command': 'device_add',
495e37
   'data': {'driver': 'str', '*bus': 'str', '*id': 'str'},
495e37
   'gen': false, # so we can get the additional arguments
495e37
-  'features': ['json-cli'] }
495e37
+  'features': ['json-cli', 'json-cli-hotplug'] }
495e37
 
495e37
 ##
495e37
 # @device_del:
495e37
diff --git a/softmmu/vl.c b/softmmu/vl.c
495e37
index d46b8fb4ab..b3829e2edd 100644
495e37
--- a/softmmu/vl.c
495e37
+++ b/softmmu/vl.c
495e37
@@ -2690,6 +2690,7 @@ static void qemu_create_cli_devices(void)
495e37
     qemu_opts_foreach(qemu_find_opts("device"),
495e37
                       device_init_func, NULL, &error_fatal);
495e37
     QTAILQ_FOREACH(opt, &device_opts, next) {
495e37
+        DeviceState *dev;
495e37
         loc_push_restore(&opt->loc);
495e37
         /*
495e37
          * TODO Eventually we should call qmp_device_add() here to make sure it
495e37
@@ -2698,7 +2699,8 @@ static void qemu_create_cli_devices(void)
495e37
          * from the start, so call qdev_device_add_from_qdict() directly for
495e37
          * now.
495e37
          */
495e37
-        qdev_device_add_from_qdict(opt->opts, true, &error_fatal);
495e37
+        dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal);
495e37
+        object_unref(OBJECT(dev));
495e37
         loc_pop(&opt->loc);
495e37
     }
495e37
     rom_reset_order_override();
495e37
diff --git a/tests/qtest/device-plug-test.c b/tests/qtest/device-plug-test.c
495e37
index 559d47727a..ad79bd4c14 100644
495e37
--- a/tests/qtest/device-plug-test.c
495e37
+++ b/tests/qtest/device-plug-test.c
495e37
@@ -77,6 +77,23 @@ static void test_pci_unplug_request(void)
495e37
     qtest_quit(qtest);
495e37
 }
495e37
 
495e37
+static void test_pci_unplug_json_request(void)
495e37
+{
495e37
+    QTestState *qtest = qtest_initf(
495e37
+        "-device '{\"driver\": \"virtio-mouse-pci\", \"id\": \"dev0\"}'");
495e37
+
495e37
+    /*
495e37
+     * Request device removal. As the guest is not running, the request won't
495e37
+     * be processed. However during system reset, the removal will be
495e37
+     * handled, removing the device.
495e37
+     */
495e37
+    device_del(qtest, "dev0");
495e37
+    system_reset(qtest);
495e37
+    wait_device_deleted_event(qtest, "dev0");
495e37
+
495e37
+    qtest_quit(qtest);
495e37
+}
495e37
+
495e37
 static void test_ccw_unplug(void)
495e37
 {
495e37
     QTestState *qtest = qtest_initf("-device virtio-balloon-ccw,id=dev0");
495e37
@@ -145,6 +162,8 @@ int main(int argc, char **argv)
495e37
      */
495e37
     qtest_add_func("/device-plug/pci-unplug-request",
495e37
                    test_pci_unplug_request);
495e37
+    qtest_add_func("/device-plug/pci-unplug-json-request",
495e37
+                   test_pci_unplug_json_request);
495e37
 
495e37
     if (!strcmp(arch, "s390x")) {
495e37
         qtest_add_func("/device-plug/ccw-unplug",
495e37
-- 
495e37
2.27.0
495e37