diff options
author | Paul Durrant <paul.durrant@citrix.com> | 2017-01-24 14:05:47 +0000 |
---|---|---|
committer | Stefano Stabellini <sstabellini@kernel.org> | 2017-01-27 15:23:29 -0800 |
commit | ae4d2eb273b167dad748ea4249720319240b1ac2 (patch) | |
tree | 29daef99af3e9563fd9ad480289e864101bd78af /hw/i386/xen | |
parent | 090fa1c8c837ebabf8c199031e0f9a9bcdf26814 (diff) |
xen-platform: add missing disk unplug option
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). This patch adds support for that unplug request.
NOTE: The semantics of what happens if unplug of all disks and 'aux' disks
is simultaneously requests is not clear. The patch makes that
assumption that an 'all' request overrides an 'aux' request.
[1] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/misc/hvm-emulated-unplug.markdown
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
----
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: John Snow <jsnow@redhat.com>
Diffstat (limited to 'hw/i386/xen')
-rw-r--r-- | hw/i386/xen/xen_platform.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index 7d41ebb68b..6010f35266 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -107,8 +107,12 @@ static void pci_unplug_nics(PCIBus *bus) pci_for_each_device(bus, 0, unplug_nic, NULL); } -static void unplug_disks(PCIBus *b, PCIDevice *d, void *o) +static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque) { + uint32_t flags = *(uint32_t *)opaque; + bool aux = (flags & UNPLUG_AUX_IDE_DISKS) && + !(flags & UNPLUG_ALL_DISKS); + /* We have to ignore passthrough devices */ if (!strcmp(d->name, "xen-pci-passthrough")) { return; @@ -116,12 +120,14 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *o) switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) { case PCI_CLASS_STORAGE_IDE: - pci_piix3_xen_ide_unplug(DEVICE(d)); + pci_piix3_xen_ide_unplug(DEVICE(d), aux); break; case PCI_CLASS_STORAGE_SCSI: case PCI_CLASS_STORAGE_EXPRESS: - object_unparent(OBJECT(d)); + if (!aux) { + object_unparent(OBJECT(d)); + } break; default: @@ -129,9 +135,9 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *o) } } -static void pci_unplug_disks(PCIBus *bus) +static void pci_unplug_disks(PCIBus *bus, uint32_t flags) { - pci_for_each_device(bus, 0, unplug_disks, NULL); + pci_for_each_device(bus, 0, unplug_disks, &flags); } static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val) @@ -144,17 +150,14 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v /* Unplug devices. Value is a bitmask of which devices to unplug, with bit 0 the disk devices, bit 1 the network devices, and bit 2 the non-primary-master IDE devices. */ - if (val & UNPLUG_ALL_DISKS) { + if (val & (UNPLUG_ALL_DISKS | UNPLUG_AUX_IDE_DISKS)) { DPRINTF("unplug disks\n"); - pci_unplug_disks(pci_dev->bus); + pci_unplug_disks(pci_dev->bus, val); } if (val & UNPLUG_ALL_NICS) { DPRINTF("unplug nics\n"); pci_unplug_nics(pci_dev->bus); } - if (val & UNPLUG_AUX_IDE_DISKS) { - DPRINTF("unplug auxiliary disks not supported\n"); - } break; } case 2: @@ -335,14 +338,14 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr, * If VMDP was to control both disk and LAN it would use 4. * If it controlled just disk or just LAN, it would use 8 below. */ - pci_unplug_disks(pci_dev->bus); + pci_unplug_disks(pci_dev->bus, UNPLUG_ALL_DISKS); pci_unplug_nics(pci_dev->bus); } break; case 8: switch (val) { case 1: - pci_unplug_disks(pci_dev->bus); + pci_unplug_disks(pci_dev->bus, UNPLUG_ALL_DISKS); break; case 2: pci_unplug_nics(pci_dev->bus); |