File xen-ioemu-hvm-pv-support.diff of Package xen

Index: xen-3.3.1-testing/tools/ioemu-remote/hw/ide.c
===================================================================
--- xen-3.3.1-testing.orig/tools/ioemu-remote/hw/ide.c
+++ xen-3.3.1-testing/tools/ioemu-remote/hw/ide.c
@@ -485,6 +485,9 @@ typedef struct PCIIDEState {
 } PCIIDEState;
 
 
+static PCIIDEState *principal_ide_controller;
+extern FILE *logfile;
+
 #if defined(__ia64__)
 #include <xen/hvm/ioreq.h>
 
@@ -2787,6 +2790,27 @@ static void ide_reset(IDEState *s)
     s->media_changed = 0;
 }
 
+void ide_unplug_harddisks(void)
+{
+    IDEState *s;
+    int i;
+
+    if (!principal_ide_controller) {
+        fprintf(logfile, "No principal controller?\n");
+        return;
+    }
+    for (i = 0; i < 4; i++) {
+        s = principal_ide_controller->ide_if + i;
+        if (!s->bs)
+            continue; /* drive not present */
+        if (s->is_cdrom)
+            continue; /* cdrom */
+        /* Is a hard disk, unplug it. */
+        s->bs = NULL;
+        ide_reset(s);
+    }
+}
+
 struct partition {
 	uint8_t boot_ind;		/* 0x80 - active */
 	uint8_t head;		/* starting head */
@@ -3299,6 +3323,10 @@ void pci_cmd646_ide_init(PCIBus *bus, Bl
                                            sizeof(PCIIDEState),
                                            -1,
                                            NULL, NULL);
+    if (principal_ide_controller)
+        abort();
+    principal_ide_controller = d;
+
     d->type = IDE_TYPE_CMD646;
     pci_conf = d->dev.config;
     pci_conf[0x00] = 0x95; // CMD646
@@ -3430,6 +3458,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
                                            NULL, NULL);
     d->type = IDE_TYPE_PIIX3;
 
+    if (principal_ide_controller)
+        abort();
+    principal_ide_controller = d;
+
     pci_conf = d->dev.config;
     pci_conf[0x00] = 0x86; // Intel
     pci_conf[0x01] = 0x80;
Index: xen-3.3.1-testing/tools/ioemu-remote/hw/pci.c
===================================================================
--- xen-3.3.1-testing.orig/tools/ioemu-remote/hw/pci.c
+++ xen-3.3.1-testing/tools/ioemu-remote/hw/pci.c
@@ -648,6 +648,28 @@ void pci_nic_init(PCIBus *bus, NICInfo *
     }
 }
 
+void pci_unplug_netifs(void)
+{
+    PCIBus *bus;
+    int x;
+
+    /* We only support one PCI bus */
+    for (bus = first_bus; bus; bus = NULL) {
+       for (x = 0; x < 256; x++) {
+           if (bus->devices[x] &&
+               bus->devices[x]->config[0xa] == 0 &&
+               bus->devices[x]->config[0xb] == 2) {
+               /* Found a netif.  Remove it from the bus.  Note that
+                  we don't free it here, since there could still be
+                  references to it floating around.  There are only
+                  ever one or two structures leaked, and it's not
+                  worth finding them all. */
+               bus->devices[x] = NULL;
+           }
+       }
+    }
+}
+
 typedef struct {
     PCIDevice dev;
     PCIBus *bus;
Index: xen-3.3.1-testing/tools/ioemu-remote/hw/xen_platform.c
===================================================================
--- xen-3.3.1-testing.orig/tools/ioemu-remote/hw/xen_platform.c
+++ xen-3.3.1-testing/tools/ioemu-remote/hw/xen_platform.c
@@ -26,6 +26,8 @@
 #include "hw.h"
 #include "pci.h"
 #include "irq.h"
+#include "sysemu.h"
+#include <xc_private.h>
 
 #include <xenguest.h>
 
@@ -71,12 +73,53 @@ static void xen_platform_ioport_writeb(v
     }
 }
 
+static uint32_t ioport_base;
+
+static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    DECLARE_DOMCTL;
+    int rc;
+
+    if (val == 0)
+        qemu_invalidate_map_cache();
+
+    switch (addr - ioport_base) {
+    case 0:
+        fprintf(logfile, "Init hypercall page %x, addr %x.\n", val, addr);
+        domctl.domain = (domid_t)domid;
+        domctl.u.hypercall_init.gmfn = val;
+        domctl.cmd = XEN_DOMCTL_hypercall_init;
+        rc = xc_domctl(xc_handle, &domctl);
+        fprintf(logfile, "result -> %d.\n", rc);
+        break;
+    case 4:
+        fprintf(logfile, "Disconnect IDE hard disk...\n");
+        ide_unplug_harddisks();
+        fprintf(logfile, "Disconnect netifs...\n");
+        pci_unplug_netifs();
+        fprintf(logfile, "Shutdown taps...\n");
+        net_tap_shutdown_all();
+        fprintf(logfile, "Done.\n");
+        break;
+    default:
+        fprintf(logfile, "Write to bad port %x (base %x) on evtchn device.\n",
+            addr, ioport_base);
+        break;
+    }
+}
+
 
 static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type)
 {
+    ioport_base = addr;
+
+    register_ioport_write(addr, 16, 4, platform_ioport_write, NULL);
+/*
     PCIXenPlatformState *d = (PCIXenPlatformState *)pci_dev;
+
     register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
     register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+*/
 }
 
 static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
Index: xen-3.3.1-testing/tools/ioemu-remote/vl.c
===================================================================
--- xen-3.3.1-testing.orig/tools/ioemu-remote/vl.c
+++ xen-3.3.1-testing/tools/ioemu-remote/vl.c
@@ -259,6 +259,20 @@ static int event_pending = 1;
 
 #include "xen-vl-extra.c"
 
+typedef struct IOHandlerRecord {
+    int fd;
+    IOCanRWHandler *fd_read_poll;
+    IOHandler *fd_read;
+    IOHandler *fd_write;
+    int deleted;
+    void *opaque;
+    /* temporary data */
+    struct pollfd *ufd;
+    struct IOHandlerRecord *next;
+} IOHandlerRecord;
+
+static IOHandlerRecord *first_io_handler;
+
 /***********************************************************/
 /* x86 ISA bus support */
 
@@ -4054,6 +4068,7 @@ typedef struct TAPState {
     int fd;
     char down_script[1024];
     char script_arg[1024];
+    struct TAPState *next;
 } TAPState;
 
 static void tap_receive(void *opaque, const uint8_t *buf, int size)
@@ -4089,6 +4104,36 @@ static void tap_send(void *opaque)
     }
 }
 
+static TAPState *head_net_tap;
+
+void net_tap_shutdown_all(void)
+{
+    struct IOHandlerRecord **pioh, *ioh;
+
+    while (head_net_tap) {
+       pioh = &first_io_handler;
+       for (;;) {
+           ioh = *pioh;
+           if (ioh == NULL)
+               break;
+           if (ioh->fd == head_net_tap->fd) {
+               *pioh = ioh->next;
+               qemu_free(ioh);
+               break;
+           }
+           pioh = &ioh->next;
+       }
+       if (!ioh)
+           fprintf(stderr,
+                   "warning: can't find iohandler for %d to close it properly.\n",
+                   head_net_tap->fd);
+       close(head_net_tap->fd);
+       head_net_tap = head_net_tap->next;
+    }
+}
+
+
+
 /* fd support */
 
 static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
@@ -4100,6 +4145,8 @@ static TAPState *net_tap_fd_init(VLANSta
         return NULL;
     s->fd = fd;
     s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
+    s->next = head_net_tap;
+    head_net_tap = s;
     qemu_set_fd_handler(s->fd, tap_send, NULL, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
     return s;
@@ -5680,20 +5727,6 @@ static void dumb_display_init(DisplaySta
 
 #define MAX_IO_HANDLERS 64
 
-typedef struct IOHandlerRecord {
-    int fd;
-    IOCanRWHandler *fd_read_poll;
-    IOHandler *fd_read;
-    IOHandler *fd_write;
-    int deleted;
-    void *opaque;
-    /* temporary data */
-    struct pollfd *ufd;
-    struct IOHandlerRecord *next;
-} IOHandlerRecord;
-
-static IOHandlerRecord *first_io_handler;
-
 /* XXX: fd_read_poll should be suppressed, but an API change is
    necessary in the character devices to suppress fd_can_read(). */
 int qemu_set_fd_handler2(int fd,
Index: xen-3.3.1-testing/tools/ioemu-remote/sysemu.h
===================================================================
--- xen-3.3.1-testing.orig/tools/ioemu-remote/sysemu.h
+++ xen-3.3.1-testing/tools/ioemu-remote/sysemu.h
@@ -49,6 +49,9 @@ void do_loadvm(const char *name);
 void do_delvm(const char *name);
 void do_info_snapshots(void);
 
+void net_tap_shutdown_all(void);
+void pci_unplug_netifs(void);
+
 void main_loop_wait(int timeout);
 
 /* Polling handling */
openSUSE Build Service is sponsored by