xen/xen-ioemu-hvm-pv-support.diff

257 lines
7.2 KiB
Diff

diff -Nuar ioemu-orig/hw/ide.c ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c 2007-03-01 15:18:35.000000000 -0700
+++ b/tools/ioemu/hw/ide.c 2007-03-01 15:19:15.000000000 -0700
@@ -392,6 +392,9 @@
int type; /* see IDE_TYPE_xxx */
} PCIIDEState;
+static PCIIDEState *principal_ide_controller;
+extern FILE *logfile;
+
#define DMA_MULTI_THREAD
#ifdef DMA_MULTI_THREAD
@@ -2001,6 +2004,27 @@
ide_dummy_transfer_stop(s);
}
+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 */
@@ -2436,6 +2460,9 @@
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
@@ -2493,6 +2520,9 @@
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;
diff -Nuar ioemu-orig/hw/pci.c ioemu/hw/pci.c
--- a/tools/ioemu/hw/pci.c 2007-03-01 15:18:35.000000000 -0700
+++ b/tools/ioemu/hw/pci.c 2007-03-01 15:19:15.000000000 -0700
@@ -514,3 +514,24 @@
}
}
+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;
+ }
+ }
+ }
+}
diff -Nuar ioemu-orig/hw/xen_platform.c ioemu/hw/xen_platform.c
--- a/tools/ioemu/hw/xen_platform.c 2007-03-01 15:18:35.000000000 -0700
+++ b/tools/ioemu/hw/xen_platform.c 2007-03-01 15:19:15.000000000 -0700
@@ -29,9 +29,36 @@
extern FILE *logfile;
+static uint32_t ioport_base;
+
static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
- return;
+ DECLARE_DOMCTL;
+ int rc;
+
+ 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 uint32_t platform_ioport_read(void *opaque, uint32_t addr)
@@ -42,6 +69,8 @@
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);
register_ioport_read(addr, 16, 1, platform_ioport_read, NULL);
}
diff -Nuar ioemu-orig/vl.c ioemu/vl.c
--- a/tools/ioemu/vl.c 2007-03-01 15:18:35.000000000 -0700
+++ b/tools/ioemu/vl.c 2007-03-01 15:19:15.000000000 -0700
@@ -170,6 +170,19 @@
char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
extern int domid;
+typedef struct IOHandlerRecord {
+ int fd;
+ IOCanRWHandler *fd_read_poll;
+ IOHandler *fd_read;
+ IOHandler *fd_write;
+ void *opaque;
+ /* temporary data */
+ struct pollfd *ufd;
+ struct IOHandlerRecord *next;
+} IOHandlerRecord;
+
+static IOHandlerRecord *first_io_handler;
+
char vncpasswd[64];
unsigned char challenge[AUTHCHALLENGESIZE];
@@ -3084,6 +3097,7 @@
typedef struct TAPState {
VLANClientState *vc;
int fd;
+ struct TAPState *next;
} TAPState;
static void tap_receive(void *opaque, const uint8_t *buf, int size)
@@ -3111,6 +3125,36 @@
}
}
+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)
@@ -3122,6 +3166,8 @@
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;
@@ -4047,19 +4093,6 @@
#define MAX_IO_HANDLERS 64
-typedef struct IOHandlerRecord {
- int fd;
- IOCanRWHandler *fd_read_poll;
- IOHandler *fd_read;
- IOHandler *fd_write;
- 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,
diff -Nuar ioemu-orig/vl.h ioemu/vl.h
--- a/tools/ioemu/vl.h 2007-03-01 15:18:35.000000000 -0700
+++ b/tools/ioemu/vl.h 2007-03-01 15:19:15.000000000 -0700
@@ -826,6 +826,7 @@
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
int pmac_ide_init (BlockDriverState **hd_table,
SetIRQFunc *set_irq, void *irq_opaque, int irq);
+void ide_unplug_harddisks(void);
/* cdrom.c */
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
@@ -1268,6 +1269,8 @@
extern char domain_name[];
void destroy_hvm_domain(void);
+void net_tap_shutdown_all(void);
+void pci_unplug_netifs(void);
/* VNC Authentication */
#define AUTHCHALLENGESIZE 16