From 1cd8c806fbc14a5cd4e9215bbf372fad9bea560a Mon Sep 17 00:00:00 2001
From: Bruce Rogers <brogers@suse.com>
Date: Mon, 22 Jan 2018 15:08:56 -0700
Subject: [PATCH] kvm-qemu-no-hot-unplug-for-certain-devices

---
 hw/acpi.c       | 3 ++-
 hw/cirrus_vga.c | 1 +
 hw/ide/piix.c   | 2 ++
 hw/piix4.c      | 1 +
 hw/piix_pci.c   | 2 ++
 hw/qdev.h       | 2 ++
 hw/vga-pci.c    | 1 +
 hw/vmware_vga.c | 1 +
 8 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index ec049a2e83..5fef25843c 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -720,7 +720,8 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 
     QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
         dev = DO_UPCAST(PCIDevice, qdev, qdev);
-        if (PCI_SLOT(dev->devfn) == slot) {
+        if (PCI_SLOT(dev->devfn) == slot && (qdev->info == NULL ||
+            !qdev->info->no_hotplug)) {
             qdev_free(qdev);
         }
     }
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 571044f64d..dff0a80f21 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3242,6 +3242,7 @@ static PCIDeviceInfo cirrus_vga_info = {
     .qdev.desc    = "Cirrus CLGD 54xx VGA",
     .qdev.size    = sizeof(PCICirrusVGAState),
     .qdev.vmsd    = &vmstate_pci_cirrus_vga,
+    .qdev.no_hotplug = 1,
     .init         = pci_cirrus_vga_initfn,
     .romfile      = VGABIOS_CIRRUS_FILENAME,
     .config_write = pci_cirrus_write_config,
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c486ed9922..7100bb509d 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -216,11 +216,13 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.name    = "piix3-ide",
         .qdev.size    = sizeof(PCIIDEState),
         .qdev.no_user = 1,
+        .qdev.no_hotplug = 1,
         .init         = pci_piix3_ide_initfn,
     },{
         .qdev.name    = "piix4-ide",
         .qdev.size    = sizeof(PCIIDEState),
         .qdev.no_user = 1,
+        .qdev.no_hotplug = 1,
         .init         = pci_piix4_ide_initfn,
     },{
         .qdev.name    = "ICH6 IDE",
diff --git a/hw/piix4.c b/hw/piix4.c
index f75951b3ea..9d6614d65b 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -115,6 +115,7 @@ static PCIDeviceInfo piix4_info[] = {
         .qdev.desc    = "ISA bridge",
         .qdev.size    = sizeof(PCIDevice),
         .qdev.no_user = 1,
+        .qdev.no_hotplug = 1,
         .init         = piix4_initfn,
     },{
         /* end of list */
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 001bc93cd2..c07415db43 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -347,6 +347,7 @@ static PCIDeviceInfo i440fx_info[] = {
         .qdev.size    = sizeof(PCII440FXState),
         .qdev.vmsd    = &vmstate_i440fx,
         .qdev.no_user = 1,
+        .qdev.no_hotplug = 1,
         .init         = i440fx_initfn,
         .config_write = i440fx_write_config,
     },{
@@ -355,6 +356,7 @@ static PCIDeviceInfo i440fx_info[] = {
         .qdev.size    = sizeof(PIIX3State),
         .qdev.vmsd    = &vmstate_piix3,
         .qdev.no_user = 1,
+        .qdev.no_hotplug = 1,
         .init         = piix3_initfn,
     },{
         /* end of list */
diff --git a/hw/qdev.h b/hw/qdev.h
index bbcdba185a..dad5da4341 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -128,6 +128,8 @@ struct DeviceInfo {
     size_t size;
     Property *props;
     int no_user;
+    /* Kludge! for use with hot-unplug unsafe pci devices only: */
+    int no_hotplug;
 
     /* callbacks */
     qdev_resetfn reset;
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 9089c9f5d5..acc3eb1238 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -131,6 +131,7 @@ static PCIDeviceInfo vga_info = {
     .qdev.name    = "VGA",
     .qdev.size    = sizeof(PCIVGAState),
     .qdev.vmsd    = &vmstate_vga_pci,
+    .qdev.no_hotplug = 1,
     .init         = pci_vga_initfn,
     .config_write = pci_vga_write_config,
     .qdev.props   = (Property[]) {
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5e969aedb4..dc31e87211 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1243,6 +1243,7 @@ static PCIDeviceInfo vmsvga_info = {
     .qdev.name    = "vmware-svga",
     .qdev.size    = sizeof(struct pci_vmsvga_state_s),
     .qdev.vmsd    = &vmstate_vmware_vga,
+    .qdev.no_hotplug = 1,
     .init         = pci_vmsvga_initfn,
 };
 
