summary refs log tree commit diff stats
path: root/hw/i386/xen/xen_platform.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-06-09 08:25:17 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-06-09 08:25:17 -0700
commit9cc1bf1ebca550f8d90f967ccd2b6d2e00e81387 (patch)
tree23366bb8d60c92cb84dbe648fafca55e4885bfb4 /hw/i386/xen/xen_platform.c
parent028f2361d0c2d28d6f918fe618f389228ac22b60 (diff)
parent6a8a8b62bdc8e3d7c5fc0f82ef4583707183b12f (diff)
downloadfocaccia-qemu-9cc1bf1ebca550f8d90f967ccd2b6d2e00e81387.tar.gz
focaccia-qemu-9cc1bf1ebca550f8d90f967ccd2b6d2e00e81387.zip
Merge tag 'pull-xen-20220609' of https://xenbits.xen.org/git-http/people/aperard/qemu-dm into staging
Xen patches

- PIIX3-IDE Xen cleanup

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEE+AwAYwjiLP2KkueYDPVXL9f7Va8FAmKh/A8ACgkQDPVXL9f7
# Va80HAf/RfBfHiHQnZOiixu+drHNcyxHDqeEcd5OqWJssD/uwd/s+DfjUm7q4t3p
# AOOf3kczj+S7LomVi4CU0qW6/edY6Jyq37aIQnCwwG35/U297gyqQGaLftDRspWO
# quBGd/66+3wSttRDY9zuTvAWRX1IBk+7ON67TXQxnNyeE+JsstzkZw86939BO1L/
# Rp1LwwtNPS8rnT1YMSWBaFGjRbxOBzF/cRVLxwv+XBYJw/DGKVeB41I5MnNT+ZlP
# MC2PVr2wZM6ki9xYdivn8d4IKECgeXclK3YSOKlYNbWW8bVvFde9j/DMty7k2geE
# 8JMsdIGTvVbb9zwe85SaguWRWlArpA==
# =cyLu
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 09 Jun 2022 06:56:31 AM PDT
# gpg:                using RSA key F80C006308E22CFD8A92E7980CF5572FD7FB55AF
# gpg: Good signature from "Anthony PERARD <anthony.perard@gmail.com>" [unknown]
# gpg:                 aka "Anthony PERARD <anthony.perard@citrix.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 5379 2F71 024C 600F 778A  7161 D8D5 7199 DF83 42C8
#      Subkey fingerprint: F80C 0063 08E2 2CFD 8A92  E798 0CF5 572F D7FB 55AF

* tag 'pull-xen-20220609' of https://xenbits.xen.org/git-http/people/aperard/qemu-dm:
  include/hw/ide: Unexport pci_piix3_xen_ide_unplug()
  hw/ide/piix: Add some documentation to pci_piix3_xen_ide_unplug()
  hw/ide/piix: Remove redundant "piix3-ide-xen" device class

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/i386/xen/xen_platform.c')
-rw-r--r--hw/i386/xen/xen_platform.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index 72028449ba..a64265cca0 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/ide.h"
+#include "hw/ide/pci.h"
 #include "hw/pci/pci.h"
 #include "hw/xen/xen_common.h"
 #include "migration/vmstate.h"
@@ -134,6 +135,51 @@ static void pci_unplug_nics(PCIBus *bus)
     pci_for_each_device(bus, 0, unplug_nic, NULL);
 }
 
+/*
+ * The Xen HVM unplug protocol [1] specifies a mechanism to allow guests to
+ * request unplug of 'aux' disks (which is stated to mean all IDE disks,
+ * except the primary master).
+ *
+ * NOTE: The semantics of what happens if unplug of all disks and 'aux' disks
+ *       is simultaneously requested is not clear. The implementation assumes
+ *       that an 'all' request overrides an 'aux' request.
+ *
+ * [1] https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/misc/hvm-emulated-unplug.pandoc
+ */
+static void pci_xen_ide_unplug(DeviceState *dev, bool aux)
+{
+    PCIIDEState *pci_ide;
+    int i;
+    IDEDevice *idedev;
+    IDEBus *idebus;
+    BlockBackend *blk;
+
+    pci_ide = PCI_IDE(dev);
+
+    for (i = aux ? 1 : 0; i < 4; i++) {
+        idebus = &pci_ide->bus[i / 2];
+        blk = idebus->ifs[i % 2].blk;
+
+        if (blk && idebus->ifs[i % 2].drive_kind != IDE_CD) {
+            if (!(i % 2)) {
+                idedev = idebus->master;
+            } else {
+                idedev = idebus->slave;
+            }
+
+            blk_drain(blk);
+            blk_flush(blk);
+
+            blk_detach_dev(blk, DEVICE(idedev));
+            idebus->ifs[i % 2].blk = NULL;
+            idedev->conf.blk = NULL;
+            monitor_remove_blk(blk);
+            blk_unref(blk);
+        }
+    }
+    qdev_reset_all(dev);
+}
+
 static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
 {
     uint32_t flags = *(uint32_t *)opaque;
@@ -147,7 +193,7 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
 
     switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) {
     case PCI_CLASS_STORAGE_IDE:
-        pci_piix3_xen_ide_unplug(DEVICE(d), aux);
+        pci_xen_ide_unplug(DEVICE(d), aux);
         break;
 
     case PCI_CLASS_STORAGE_SCSI: