aboutsummaryrefslogtreecommitdiff
path: root/hw/i386/xen
diff options
context:
space:
mode:
authorOlaf Hering <olaf@aepfle.de>2016-10-21 14:37:07 +0200
committerStefano Stabellini <sstabellini@kernel.org>2016-10-21 12:11:38 -0700
commit35132016dc1c27de2b1354b161df6cc22f3ac5bf (patch)
treea0cf4005a503f0c8120d645cc028ec74f1a8fc5c /hw/i386/xen
parent78f66897ddf58d1ffe5e0b95f7c1a1dad103a8da (diff)
xen_platform: SUSE xenlinux unplug for emulated PCI
Implement SUSE specific unplug protocol for emulated PCI devices in PVonHVM guests. Its a simple 'outl(1, (ioaddr + 4));'. This protocol was implemented and used since Xen 3.0.4. It is used in all SUSE/SLES/openSUSE releases up to SLES11SP3 and openSUSE 12.3. In addition old (pre-2011) VMDP versions are handled as well. Signed-off-by: Olaf Hering <olaf@aepfle.de> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
Diffstat (limited to 'hw/i386/xen')
-rw-r--r--hw/i386/xen/xen_platform.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index 91d8a7a2f0..2e1e543881 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -311,13 +311,38 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
uint64_t val, unsigned int size)
{
PCIXenPlatformState *s = opaque;
+ PCIDevice *pci_dev = PCI_DEVICE(s);
switch (addr) {
case 0: /* Platform flags */
platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);
break;
+ case 4:
+ if (val == 1) {
+ /*
+ * SUSE unplug for Xenlinux
+ * xen-kmp used this since xen-3.0.4, instead the official protocol
+ * from xen-3.3+ It did an unconditional "outl(1, (ioaddr + 4));"
+ * Pre VMDP 1.7 used 4 and 8 depending on how VMDP was configured.
+ * 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_nics(pci_dev->bus);
+ }
+ break;
case 8:
- log_writeb(s, (uint32_t)val);
+ switch (val) {
+ case 1:
+ pci_unplug_disks(pci_dev->bus);
+ break;
+ case 2:
+ pci_unplug_nics(pci_dev->bus);
+ break;
+ default:
+ log_writeb(s, (uint32_t)val);
+ break;
+ }
break;
default:
break;