From 3d89e3f7e816b6edbe3a516c754d20288a4e7937 Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Tue, 24 Jan 2017 14:05:45 +0000 Subject: xen-platform: re-structure unplug_disks The current code is poorly structured and potentially leads to multiple config space reads when one is sufficient. Also the UNPLUG_ALL_IDE_DISKS flag is mis-named since it also results in SCSI disks being unplugged. This patch renames the flag and re-structures the code to be more efficient, and readable. Signed-off-by: Paul Durrant Reviewed-by: Stefano Stabellini --- hw/i386/xen/xen_platform.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index 2e1e543881..f50915ffbc 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -88,7 +88,7 @@ static void log_writeb(PCIXenPlatformState *s, char val) } /* Xen Platform, Fixed IOPort */ -#define UNPLUG_ALL_IDE_DISKS 1 +#define UNPLUG_ALL_DISKS 1 #define UNPLUG_ALL_NICS 2 #define UNPLUG_AUX_IDE_DISKS 4 @@ -110,14 +110,21 @@ static void pci_unplug_nics(PCIBus *bus) static void unplug_disks(PCIBus *b, PCIDevice *d, void *o) { /* We have to ignore passthrough devices */ - if (pci_get_word(d->config + PCI_CLASS_DEVICE) == - PCI_CLASS_STORAGE_IDE - && strcmp(d->name, "xen-pci-passthrough") != 0) { + if (!strcmp(d->name, "xen-pci-passthrough")) { + return; + } + + switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) { + case PCI_CLASS_STORAGE_IDE: pci_piix3_xen_ide_unplug(DEVICE(d)); - } else if (pci_get_word(d->config + PCI_CLASS_DEVICE) == - PCI_CLASS_STORAGE_SCSI - && strcmp(d->name, "xen-pci-passthrough") != 0) { + break; + + case PCI_CLASS_STORAGE_SCSI: object_unparent(OBJECT(d)); + break; + + default: + break; } } @@ -134,9 +141,9 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v case 0: { PCIDevice *pci_dev = PCI_DEVICE(s); /* Unplug devices. Value is a bitmask of which devices to - unplug, with bit 0 the IDE devices, bit 1 the network + 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_IDE_DISKS) { + if (val & UNPLUG_ALL_DISKS) { DPRINTF("unplug disks\n"); pci_unplug_disks(pci_dev->bus); } -- cgit v1.2.3-55-g7522 From 090fa1c8c837ebabf8c199031e0f9a9bcdf26814 Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Thu, 26 Jan 2017 09:37:24 +0000 Subject: xen-platform: add support for unplugging NVMe disks... ...not just IDE and SCSI. This patch allows the Xen tool-stack to fully support of NVMe as an emulated disk type. See [1] for the relevant tool-stack patch discussion. [1] https://lists.xen.org/archives/html/xen-devel/2017-01/msg01225.html Signed-off-by: Paul Durrant Reviewed-by: Stefano Stabellini --- hw/i386/xen/xen_platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index f50915ffbc..7d41ebb68b 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -120,6 +120,7 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *o) break; case PCI_CLASS_STORAGE_SCSI: + case PCI_CLASS_STORAGE_EXPRESS: object_unparent(OBJECT(d)); break; -- cgit v1.2.3-55-g7522 From ae4d2eb273b167dad748ea4249720319240b1ac2 Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Tue, 24 Jan 2017 14:05:47 +0000 Subject: 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 Reviewed-by: Stefano Stabellini ---- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: "Michael S. Tsirkin" Cc: John Snow --- hw/i386/xen/xen_platform.c | 27 +++++++++++++++------------ hw/ide/piix.c | 4 ++-- include/hw/ide.h | 2 +- 3 files changed, 18 insertions(+), 15 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); diff --git a/hw/ide/piix.c b/hw/ide/piix.c index d5777fd0b3..7e2d76705d 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -165,7 +165,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp) pci_piix_init_ports(d); } -int pci_piix3_xen_ide_unplug(DeviceState *dev) +int pci_piix3_xen_ide_unplug(DeviceState *dev, bool aux) { PCIIDEState *pci_ide; DriveInfo *di; @@ -174,7 +174,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) pci_ide = PCI_IDE(dev); - for (i = 0; i < 4; i++) { + for (i = aux ? 1 : 0; i < 4; i++) { di = drive_get_by_index(IF_IDE, i); if (di != NULL && !di->media_cd) { BlockBackend *blk = blk_by_legacy_dinfo(di); diff --git a/include/hw/ide.h b/include/hw/ide.h index bc8bd321a2..3ae087c572 100644 --- a/include/hw/ide.h +++ b/include/hw/ide.h @@ -17,7 +17,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); -int pci_piix3_xen_ide_unplug(DeviceState *dev); +int pci_piix3_xen_ide_unplug(DeviceState *dev, bool aux); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-mmio.c */ -- cgit v1.2.3-55-g7522 From 6d06220ad91985f59454c619dc238ebd8a968cd8 Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Fri, 25 Nov 2016 15:30:40 +0000 Subject: MAINTAINERS: Update xen-devel mailing list address Signed-off-by: Anthony PERARD Acked-by: Stefano Stabellini --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a428cb2e23..baea7c7bfb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -323,7 +323,7 @@ Guest CPU Cores (Xen): X86 M: Stefano Stabellini M: Anthony Perard -L: xen-devel@lists.xensource.com +L: xen-devel@lists.xenproject.org S: Supported F: xen-* F: */xen* -- cgit v1.2.3-55-g7522 From e9dcbc86d614018923e26e31319b0a54c9e5abac Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Wed, 1 Feb 2017 07:52:02 +0100 Subject: xen: use qdev_unplug() instead of g_free() in xen_pv_find_xendev() The error exits of xen_pv_find_xendev() free the new xen-device via g_free() which is wrong. As the xen-device has been initialized as qdev it must be removed via qdev_unplug(). This bug has been introduced with commit 3a6c9172ac5951e6dac2b3f6 ("xen: create qdev for each backend device"). Reported-by: Roger Pau Monné Tested-by: Roger Pau Monné Signed-off-by: Juergen Gross Reviewed-by: Stefano Stabellini --- hw/xen/xen_backend.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index d1190041ae..6c21c37d68 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -124,10 +124,11 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, /* init new xendev */ xendev = g_malloc0(ops->size); object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND); - qdev_set_parent_bus(&xendev->qdev, xen_sysbus); - qdev_set_id(&xendev->qdev, g_strdup_printf("xen-%s-%d", type, dev)); - qdev_init_nofail(&xendev->qdev); - object_unref(OBJECT(&xendev->qdev)); + OBJECT(xendev)->free = g_free; + qdev_set_parent_bus(DEVICE(xendev), xen_sysbus); + qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev)); + qdev_init_nofail(DEVICE(xendev)); + object_unref(OBJECT(xendev)); xendev->type = type; xendev->dom = dom; @@ -145,7 +146,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, xendev->evtchndev = xenevtchn_open(NULL, 0); if (xendev->evtchndev == NULL) { xen_pv_printf(NULL, 0, "can't open evtchn device\n"); - g_free(xendev); + qdev_unplug(DEVICE(xendev), NULL); return NULL; } fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC); @@ -155,7 +156,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, if (xendev->gnttabdev == NULL) { xen_pv_printf(NULL, 0, "can't open gnttab device\n"); xenevtchn_close(xendev->evtchndev); - g_free(xendev); + qdev_unplug(DEVICE(xendev), NULL); return NULL; } } else { -- cgit v1.2.3-55-g7522