rpms/xen/devel xen-pvfb-04-xenfb-event-handlers.patch, NONE, 1.1.2.1 xen-pvfb-05-xenfb-qemu-console.patch, NONE, 1.1.2.1 xen-pvfb-06-xenfb-pubpriv-merge.patch, NONE, 1.1.2.1 xen-pvfb-07-xenfb-async-startup.patch, NONE, 1.1.2.1 xen-pvfb-08-xen-console-qemu.patch, NONE, 1.1.2.1 xen-pvfb-09-xend-device-model.patch, NONE, 1.1.2.1 xen-pvfb-10-xen-console-ignore.patch, NONE, 1.1.2.1 .cvsignore, 1.34, 1.34.2.1 sources, 1.48, 1.48.2.1 xen-pvfb-01-qemu-fv-machine.patch, 1.1, 1.1.2.1 xen-pvfb-02-qemu-pv-machine.patch, 1.2, 1.2.2.1 xen-pvfb-03-xenfb-remove.patch, 1.1, 1.1.2.1 xen.spec, 1.194, 1.194.2.1 pygrub-dont-exec.patch, 1.1, NONE xen-3.1.0-dev-native-protocol.patch, 1.1, NONE xen-3.1.0-libxc-native-protocol.patch, 1.1, NONE xen-3.1.0-no-xenapi-docs.patch, 1.1, NONE xen-blktap-error-returns.patch, 1.2, NONE xen-blktap-no-aio-epoll.patch, 1.3, NONE xen-clobber-vif-type.patch, 1.1, NONE xen-console-log.patch, 1.2, NONE xen-hvm-save-paths.patch, 1.1, NONE xen-keyboard.patch, 1.1, NONE xen-pvfb-04-compat.patch, 1.4, NONE xen-qemu-ne2000-CVE-2007-1321.patch, 1.1, NONE xen-qemu-rtl8139-checksum.patch, 1.1, NONE xen-qemu-vnc-delete.patch, 1.1, NONE xen-remove-python-path-check.patch, 1.1, NONE xen-start-fail-cleanup.patch, 1.1, NONE xen-tpm-functions.patch, 1.1, NONE xen-vmxassist-irqs.patch, 1.1, NONE

Daniel P. Berrange (berrange) fedora-extras-commits at redhat.com
Fri Oct 19 23:35:42 UTC 2007


Author: berrange

Update of /cvs/pkgs/rpms/xen/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv18460

Modified Files:
      Tag: private-berrange-xen-unstable
	.cvsignore sources xen-pvfb-01-qemu-fv-machine.patch 
	xen-pvfb-02-qemu-pv-machine.patch 
	xen-pvfb-03-xenfb-remove.patch xen.spec 
Added Files:
      Tag: private-berrange-xen-unstable
	xen-pvfb-04-xenfb-event-handlers.patch 
	xen-pvfb-05-xenfb-qemu-console.patch 
	xen-pvfb-06-xenfb-pubpriv-merge.patch 
	xen-pvfb-07-xenfb-async-startup.patch 
	xen-pvfb-08-xen-console-qemu.patch 
	xen-pvfb-09-xend-device-model.patch 
	xen-pvfb-10-xen-console-ignore.patch 
Removed Files:
      Tag: private-berrange-xen-unstable
	pygrub-dont-exec.patch xen-3.1.0-dev-native-protocol.patch 
	xen-3.1.0-libxc-native-protocol.patch 
	xen-3.1.0-no-xenapi-docs.patch xen-blktap-error-returns.patch 
	xen-blktap-no-aio-epoll.patch xen-clobber-vif-type.patch 
	xen-console-log.patch xen-hvm-save-paths.patch 
	xen-keyboard.patch xen-pvfb-04-compat.patch 
	xen-qemu-ne2000-CVE-2007-1321.patch 
	xen-qemu-rtl8139-checksum.patch xen-qemu-vnc-delete.patch 
	xen-remove-python-path-check.patch 
	xen-start-fail-cleanup.patch xen-tpm-functions.patch 
	xen-vmxassist-irqs.patch 
Log Message:
Sync to xen-unstable snapshot release

xen-pvfb-04-xenfb-event-handlers.patch:

--- NEW FILE xen-pvfb-04-xenfb-event-handlers.patch ---
diff -r bd1bddd42929 tools/ioemu/hw/xen_machine_pv.c
--- a/tools/ioemu/hw/xen_machine_pv.c	Tue Aug 14 14:38:28 2007 -0400
+++ b/tools/ioemu/hw/xen_machine_pv.c	Tue Aug 14 15:04:55 2007 -0400
@@ -136,21 +136,6 @@ void xen_pvfb_invalidate(void *opaque)
 /* Screen dump is not used in Xen, so no need to impl this ? */
 void xen_pvfb_screen_dump(void *opaque, const char *name) { }
 
-void xen_pvfb_dispatch_store(void *opaque) {
-    int ret;
-    if ((ret = xenfb_dispatch_store((struct xenfb *)opaque)) < 0) {
-        fprintf(stderr, "Failure while dispatching store: %d\n", ret);
-        exit(1);
-    }
-}
-
-void xen_pvfb_dispatch_channel(void *opaque) {
-    int ret;
-    if ((ret = xenfb_dispatch_channel((struct xenfb *)opaque)) < 0) {
-        fprintf(stderr, "Failure while dispatching store: %d\n", ret);
-        exit(1);
-    }
-}
 
 /* The Xen PV machine currently provides
  *   - a virtual framebuffer
@@ -165,7 +150,6 @@ static void xen_init_pv(uint64_t ram_siz
 {
     struct xenfb *xenfb;
     extern int domid;
-    int fd;
 
     /* Prepare PVFB state */
     xenfb = xenfb_new();
@@ -197,19 +181,6 @@ static void xen_init_pv(uint64_t ram_siz
                                  xenfb->abs_pointer_wanted,
                                  "Xen PVFB Mouse");
 
-    /* Listen for events from xenstore */
-    fd = xenfb_get_store_fd(xenfb);
-    if (qemu_set_fd_handler2(fd, NULL, xen_pvfb_dispatch_store, NULL, xenfb) < 0) {
-        fprintf(stderr, "Could not register event handler (%s)\n",
-                strerror(errno));
-    }
-
-    /* Listen for events from the event channel */
-    fd = xenfb_get_channel_fd(xenfb);
-    if (qemu_set_fd_handler2(fd, NULL, xen_pvfb_dispatch_channel, NULL, xenfb) < 0) {
-        fprintf(stderr, "Could not register event handler (%s)\n",
-                strerror(errno));
-    }
 
     /* Setup QEMU display */
     dpy_resize(ds, xenfb->width, xenfb->height);
diff -r bd1bddd42929 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c	Tue Aug 14 14:38:28 2007 -0400
+++ b/tools/ioemu/hw/xenfb.c	Tue Aug 14 15:10:27 2007 -0400
@@ -8,7 +8,6 @@
 #include <xen/io/fbif.h>
 #include <xen/io/kbdif.h>
 #include <xen/io/protocols.h>
-#include <sys/select.h>
 #include <stdbool.h>
 #include <xen/event_channel.h>
 #include <sys/mman.h>
@@ -18,6 +17,7 @@
 #include <time.h>
 #include <xs.h>
 
+#include "vl.h"
 #include "xenfb.h"
 
 // FIXME defend against malicious frontend?
@@ -511,96 +511,6 @@ static void xenfb_dev_fatal(struct xenfb
 	xenfb_switch_state(dev, XenbusStateClosing);
 }
 
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	struct xs_handle *xsh = xenfb->xsh;
-	int val, serrno;
-	struct xenfb_page *fb_page;
-
-	xenfb_detach_dom(xenfb);
-
-	xenfb_device_set_domain(&xenfb->fb, domid);
-	xenfb_device_set_domain(&xenfb->kbd, domid);
-
-	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
-		goto error;
-	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
-		goto error;
-	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
-		goto error;
-
-	if (xenfb_hotplug(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_hotplug(&xenfb->kbd) < 0)
-		goto error;
-
-	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
-		goto error;
-	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
-		goto error;
-
-	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_bind(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_bind(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
-			    "%d", &val) < 0)
-		val = 0;
-	if (!val) {
-		errno = ENOTSUP;
-		goto error;
-	}
-	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
-			    xenfb->protocol) < 0)
-		xenfb->protocol[0] = '\0';
-	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
-
-	/* TODO check for permitted ranges */
-	fb_page = xenfb->fb.page;
-	xenfb->pub.depth = fb_page->depth;
-	xenfb->pub.width = fb_page->width;
-	xenfb->pub.height = fb_page->height;
-	/* TODO check for consistency with the above */
-	xenfb->fb_len = fb_page->mem_length;
-	xenfb->pub.row_stride = fb_page->line_length;
-
-	if (xenfb_map_fb(xenfb, domid) < 0)
-		goto error;
-
-	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
-		goto error;
-	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
-		goto error;
-
-	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
-		goto error;
-	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
-			    "%d", &val) < 0)
-		val = 0;
-	xenfb->pub.abs_pointer_wanted = val;
-
-	return 0;
-
- error:
-	serrno = errno;
-	xenfb_detach_dom(xenfb);
-	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
-	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
-        errno = serrno;
-        return -1;
-}
 
 static void xenfb_detach_dom(struct xenfb_private *xenfb)
 {
@@ -676,13 +586,13 @@ static int xenfb_on_state_change(struct 
 	return 0;
 }
 
-int xenfb_dispatch_channel(struct xenfb *xenfb_pub)
+static void xenfb_dispatch_channel(void *xenfb_pub)
 {
 	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
 	evtchn_port_t port;
 	port = xc_evtchn_pending(xenfb->evt_xch);
 	if (port == -1)
-		return -1;
+		exit(1);
 
 	if (port == xenfb->fb.port)
 		xenfb_on_fb_event(xenfb);
@@ -690,12 +600,10 @@ int xenfb_dispatch_channel(struct xenfb 
 		xenfb_on_kbd_event(xenfb);
 
 	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
-		return -1;
-
-	return 0;
-}
-
-int xenfb_dispatch_store(struct xenfb *xenfb_pub)
+		exit(1);
+}
+
+static void xenfb_dispatch_store(void *xenfb_pub)
 {
 	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
 	unsigned dummy;
@@ -708,52 +616,107 @@ int xenfb_dispatch_store(struct xenfb *x
 	if (r == 0)
 		r = xenfb_on_state_change(&xenfb->kbd);
 	if (r == -1)
-		return -2;
-
-	return 0;
-}
-
-
-/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
-int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
+		exit(1);
+}
+
+
+int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
 {
 	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	int ret;
-
-	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
-		if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0)
-			return ret;
-	}
-
-	if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
-		if ((ret = xenfb_dispatch_store(xenfb_pub)) < 0)
-			return ret;
-	}
-
-	return 0;
-}
-
-int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	int fd1 = xc_evtchn_fd(xenfb->evt_xch);
-	int fd2 = xs_fileno(xenfb->xsh);
-
-	FD_SET(fd1, readfds);
-	FD_SET(fd2, readfds);
-	return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
-}
-
-int xenfb_get_store_fd(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	return xs_fileno(xenfb->xsh);
-}
-
-int xenfb_get_channel_fd(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	return xc_evtchn_fd(xenfb->evt_xch);
+	struct xs_handle *xsh = xenfb->xsh;
+	int val, serrno;
+	struct xenfb_page *fb_page;
+
+	xenfb_detach_dom(xenfb);
+
+	xenfb_device_set_domain(&xenfb->fb, domid);
+	xenfb_device_set_domain(&xenfb->kbd, domid);
+
+	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
+		goto error;
+
+	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
+		goto error;
+	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
+		goto error;
+	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
+		goto error;
+
+	if (xenfb_hotplug(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_hotplug(&xenfb->kbd) < 0)
+		goto error;
+
+	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
+		goto error;
+	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
+		goto error;
+
+	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
+		goto error;
+
+	if (xenfb_bind(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_bind(&xenfb->kbd) < 0)
+		goto error;
+
+	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
+			    "%d", &val) < 0)
+		val = 0;
+	if (!val) {
+		errno = ENOTSUP;
+		goto error;
+	}
+	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
+			    xenfb->protocol) < 0)
+		xenfb->protocol[0] = '\0';
+	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
+
+	/* TODO check for permitted ranges */
+	fb_page = xenfb->fb.page;
+	xenfb->pub.depth = fb_page->depth;
+	xenfb->pub.width = fb_page->width;
+	xenfb->pub.height = fb_page->height;
+	/* TODO check for consistency with the above */
+	xenfb->fb_len = fb_page->mem_length;
+	xenfb->pub.row_stride = fb_page->line_length;
+
+	if (xenfb_map_fb(xenfb, domid) < 0)
+		goto error;
+
+	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
+		goto error;
+	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
+		goto error;
+
+	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
+		goto error;
+	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
+			    "%d", &val) < 0)
+		val = 0;
+	xenfb->pub.abs_pointer_wanted = val;
+
+	/* Listen for events from xenstore */
+	if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)
+		goto error;
+
+	/* Listen for events from the event channel */
+	if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
+		goto error;
+
+	return 0;
+
+ error:
+	serrno = errno;
+	xenfb_detach_dom(xenfb);
+	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
+	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
+        errno = serrno;
+        return -1;
 }
 
 static int xenfb_kbd_event(struct xenfb_private *xenfb,
diff -r bd1bddd42929 tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h	Tue Aug 14 14:38:28 2007 -0400
+++ b/tools/ioemu/hw/xenfb.h	Tue Aug 14 15:03:42 2007 -0400
@@ -25,13 +25,6 @@ void xenfb_teardown(struct xenfb *xenfb)
 
 int xenfb_attach_dom(struct xenfb *xenfb, int domid);
 
-int xenfb_dispatch_store(struct xenfb *xenfb_pub);
-int xenfb_dispatch_channel(struct xenfb *xenfb_pub);
-int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds);
-int xenfb_poll(struct xenfb *xenfb, fd_set *readfds);
-int xenfb_get_store_fd(struct xenfb *xenfb_pub);
-int xenfb_get_channel_fd(struct xenfb *xenfb_pub);
-
 int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
 int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
 int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);

xen-pvfb-05-xenfb-qemu-console.patch:

--- NEW FILE xen-pvfb-05-xenfb-qemu-console.patch ---
diff -r c2aa6c7965a3 tools/ioemu/hw/xen_machine_pv.c
--- a/tools/ioemu/hw/xen_machine_pv.c	Wed Aug 15 14:17:30 2007 -0400
+++ b/tools/ioemu/hw/xen_machine_pv.c	Tue Aug 21 22:03:27 2007 -0400
@@ -24,117 +24,6 @@
 
 #include "vl.h"
 #include "xenfb.h"
-#include <linux/input.h>
-
-/* A convenient function for munging pixels between different depths */
-#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
-    for (line = y ; line < h ; line++) {                                \
-        SRC_T *src = (SRC_T *)(xenfb->pixels + (line*xenfb->row_stride) + (x*xenfb->depth/8)); \
-        DST_T *dst = (DST_T *)(ds->data + (line*ds->linesize) + (x*ds->depth/8)); \
-        int col;                                                        \
-        for (col = x ; col < w ; col++) {                               \
-            *dst = (((*src >> RRS)&RM) << RLS) |                        \
-                (((*src >> GRS)&GM) << GLS) |                           \
-                (((*src >> GRS)&BM) << BLS);                            \
-            src++;                                                      \
-            dst++;                                                      \
-        }                                                               \
-    }
-
-
-/* This copies data from the guest framebuffer region, into QEMU's copy
- * NB. QEMU's copy is stored in the pixel format of a) the local X server (SDL case)
- * or b) the current VNC client pixel format.
- */
-static void xen_pvfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
-{
-    DisplayState *ds = (DisplayState *)xenfb->user_data;
-    int line;
-
-    if (xenfb->depth == ds->depth) { /* Perfect match can use fast path */
-        for (line = y ; line < (y+h) ; line++) {
-            memcpy(ds->data + (line * ds->linesize) + (x*ds->depth/8),
-                   xenfb->pixels + (line*xenfb->row_stride) + (x*xenfb->depth/8),
-                   w * xenfb->depth/8);
-        }
-    } else { /* Mismatch requires slow pixel munging */
-        if (xenfb->depth == 8) {
-            /* 8 bit source == r:3 g:3 b:2 */
-            if (ds->depth == 16) {
-                BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
-            } else if (ds->depth == 32) {
-                BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
-            }
-        } else if (xenfb->depth == 16) {
-            /* 16 bit source == r:5 g:6 b:5 */
-            if (ds->depth == 8) {
-                BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
-            } else if (ds->depth == 32) {
-                BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
-            }
-        } else if (xenfb->depth == 32) {
-            /* 32 bit source == r:8 g:8 b:8 (padding:8) */
-            if (ds->depth == 8) {
-                BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 255);
-            } else if (ds->depth == 16) {
-                BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 255);
-            }
-        }
-    }
-    dpy_update(ds, x, y, w, h);
-}
-
-
-/* Send a keypress from the client to the guest OS */
-static void xen_pvfb_put_keycode(void *opaque, int keycode)
-{
-    struct xenfb *xenfb = (struct xenfb*)opaque;
-    xenfb_send_key(xenfb, keycode & 0x80 ? 0 : 1, keycode & 0x7f);
-}
-
-/* Send a mouse event from the client to the guest OS */
-static void xen_pvfb_mouse_event(void *opaque,
-                                 int dx, int dy, int dz, int button_state)
-{
-    static int old_state = 0;
-    int i;
-    struct xenfb *xenfb = (struct xenfb*)opaque;
-    DisplayState *ds = (DisplayState *)xenfb->user_data;
-    if (xenfb->abs_pointer_wanted)
-        xenfb_send_position(xenfb,
-                            dx*ds->width/0x7fff,
-                            dy*ds->height/0x7fff);
-    else
-        xenfb_send_motion(xenfb, dx, dy);
-
-	for (i = 0 ; i < 8 ; i++) {
-		int lastDown = old_state & (1 << i);
-		int down = button_state & (1 << i);
-		if (down == lastDown)
-			continue;
-
-		if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
-			return;
-	}
-    old_state = button_state;
-}
-
-/* QEMU display state changed, so refresh the framebuffer copy */
-void xen_pvfb_update(void *opaque)
-{
-    struct xenfb *xenfb = (struct xenfb *)opaque;
-    xen_pvfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
-}
-
-/* QEMU display state changed, so refresh the framebuffer copy */
-void xen_pvfb_invalidate(void *opaque)
-{
-    struct xenfb *xenfb = (struct xenfb *)opaque;
-    xen_pvfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
-}
-
-/* Screen dump is not used in Xen, so no need to impl this ? */
-void xen_pvfb_screen_dump(void *opaque, const char *name) { }
 
 
 /* The Xen PV machine currently provides
@@ -160,30 +49,11 @@ static void xen_init_pv(uint64_t ram_siz
     }
 
     /* Talk to the guest */
-    if (xenfb_attach_dom(xenfb, domid) < 0) {
+    if (xenfb_attach_dom(xenfb, domid, ds) < 0) {
         fprintf(stderr, "Could not connect to domain (%s)\n",
                 strerror(errno));
         exit(1);
     }
-    xenfb->update = xen_pvfb_guest_copy;
-    xenfb->user_data = ds;
-
-    /* Tell QEMU to allocate a graphical console */
-    graphic_console_init(ds,
-                         xen_pvfb_update,
-                         xen_pvfb_invalidate,
-                         xen_pvfb_screen_dump,
-                         xenfb);
-
-    /* Register our keyboard & mouse handlers */
-    qemu_add_kbd_event_handler(xen_pvfb_put_keycode, xenfb);
-    qemu_add_mouse_event_handler(xen_pvfb_mouse_event, xenfb,
-                                 xenfb->abs_pointer_wanted,
-                                 "Xen PVFB Mouse");
-
-
-    /* Setup QEMU display */
-    dpy_resize(ds, xenfb->width, xenfb->height);
 }
 
 QEMUMachine xenpv_machine = {
diff -r c2aa6c7965a3 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c	Wed Aug 15 14:17:30 2007 -0400
+++ b/tools/ioemu/hw/xenfb.c	Tue Aug 21 22:04:25 2007 -0400
@@ -16,8 +16,8 @@
 #include <string.h>
 #include <time.h>
 #include <xs.h>
-
-#include "vl.h"
+#include <linux/input.h>
+
 #include "xenfb.h"
 
 // FIXME defend against malicious frontend?
@@ -586,6 +586,177 @@ static int xenfb_on_state_change(struct 
 	return 0;
 }
 
+static int xenfb_kbd_event(struct xenfb_private *xenfb,
+			   union xenkbd_in_event *event)
+{
+	uint32_t prod;
+	struct xenkbd_page *page = xenfb->kbd.page;
+
+	if (xenfb->kbd.state != XenbusStateConnected)
+		return 0;
+
+	prod = page->in_prod;
+	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
+		errno = EAGAIN;
+		return -1;
+	}
+
+	mb();			/* ensure ring space available */
+	XENKBD_IN_RING_REF(page, prod) = *event;
+	wmb();			/* ensure ring contents visible */
+	page->in_prod = prod + 1;
+	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
+}
+
+static int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	union xenkbd_in_event event;
+
+	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+	event.type = XENKBD_TYPE_KEY;
+	event.key.pressed = down ? 1 : 0;
+	event.key.keycode = keycode;
+
+	return xenfb_kbd_event(xenfb, &event);
+}
+
+static int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	union xenkbd_in_event event;
+
+	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+	event.type = XENKBD_TYPE_MOTION;
+	event.motion.rel_x = rel_x;
+	event.motion.rel_y = rel_y;
+
+	return xenfb_kbd_event(xenfb, &event);
+}
+
+static int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	union xenkbd_in_event event;
+
+	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+	event.type = XENKBD_TYPE_POS;
+	event.pos.abs_x = abs_x;
+	event.pos.abs_y = abs_y;
+
+	return xenfb_kbd_event(xenfb, &event);
+}
+
+/* Send a keypress from the client to the guest OS */
+static void xenfb_put_keycode(void *opaque, int keycode)
+{
+	struct xenfb *xenfb = (struct xenfb*)opaque;
+	xenfb_send_key(xenfb, keycode & 0x80 ? 0 : 1, keycode & 0x7f);
+}
+
+/* Send a mouse event from the client to the guest OS */
+static void xenfb_mouse_event(void *opaque,
+			      int dx, int dy, int dz, int button_state)
+{
+	int i;
+	struct xenfb *xenfb = (struct xenfb*)opaque;
+	DisplayState *ds = (DisplayState *)xenfb->user_data;
+	if (xenfb->abs_pointer_wanted)
+		xenfb_send_position(xenfb,
+				    dx*ds->width/0x7fff,
+				    dy*ds->height/0x7fff);
+	else
+		xenfb_send_motion(xenfb, dx, dy);
+
+	for (i = 0 ; i < 8 ; i++) {
+		int lastDown = xenfb->button_state & (1 << i);
+		int down = button_state & (1 << i);
+		if (down == lastDown)
+			continue;
+
+		if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
+			return;
+	}
+	xenfb->button_state = button_state;
+}
+
+/* A convenient function for munging pixels between different depths */
+#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
+	for (line = y ; line < h ; line++) {				\
+		SRC_T *src = (SRC_T *)(xenfb->pixels + (line*xenfb->row_stride) + (x*xenfb->depth/8)); \
+		DST_T *dst = (DST_T *)(ds->data + (line*ds->linesize) + (x*ds->depth/8)); \
+		int col;						\
+		for (col = x ; col < w ; col++) {			\
+			*dst = (((*src >> RRS)&RM) << RLS) |		\
+				(((*src >> GRS)&GM) << GLS) |		\
+				(((*src >> GRS)&BM) << BLS);		\
+			src++;						\
+			dst++;						\
+		}							\
+	}
+
+
+/* This copies data from the guest framebuffer region, into QEMU's copy
+ * NB. QEMU's copy is stored in the pixel format of a) the local X server (SDL case)
+ * or b) the current VNC client pixel format.
+ */
+static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
+{
+	DisplayState *ds = (DisplayState *)xenfb->user_data;
+	int line;
+
+	if (xenfb->depth == ds->depth) { /* Perfect match can use fast path */
+		for (line = y ; line < (y+h) ; line++) {
+			memcpy(ds->data + (line * ds->linesize) + (x*ds->depth/8),
+			       xenfb->pixels + (line*xenfb->row_stride) + (x*xenfb->depth/8),
+			       w * xenfb->depth/8);
+		}
+	} else { /* Mismatch requires slow pixel munging */
+		if (xenfb->depth == 8) {
+			/* 8 bit source == r:3 g:3 b:2 */
+			if (ds->depth == 16) {
+				BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
+			} else if (ds->depth == 32) {
+				BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
+			}
+		} else if (xenfb->depth == 16) {
+			/* 16 bit source == r:5 g:6 b:5 */
+			if (ds->depth == 8) {
+				BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
+			} else if (ds->depth == 32) {
+				BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
+			}
+		} else if (xenfb->depth == 32) {
+			/* 32 bit source == r:8 g:8 b:8 (padding:8) */
+			if (ds->depth == 8) {
+				BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 255);
+			} else if (ds->depth == 16) {
+				BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 255);
+			}
+		}
+	}
+	dpy_update(ds, x, y, w, h);
+}
+
+/* QEMU display state changed, so refresh the framebuffer copy */
+static void xenfb_update(void *opaque)
+{
+	struct xenfb *xenfb = (struct xenfb *)opaque;
+	xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+}
+
+/* QEMU display state changed, so refresh the framebuffer copy */
+static void xenfb_invalidate(void *opaque)
+{
+	struct xenfb *xenfb = (struct xenfb *)opaque;
+	xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+}
+
+/* Screen dump is not used in Xen, so no need to impl this ? */
+static void xenfb_screen_dump(void *opaque, const char *name) { }
+
+
+
 static void xenfb_dispatch_channel(void *xenfb_pub)
 {
 	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
@@ -620,7 +791,7 @@ static void xenfb_dispatch_store(void *x
 }
 
 
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
+int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid, DisplayState *ds)
 {
 	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
 	struct xs_handle *xsh = xenfb->xsh;
@@ -708,6 +879,23 @@ int xenfb_attach_dom(struct xenfb *xenfb
 	if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
 		goto error;
 
+	/* Register our keyboard & mouse handlers */
+	qemu_add_kbd_event_handler(xenfb_put_keycode, xenfb);
+	qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
+				     xenfb_pub->abs_pointer_wanted,
+				     "Xen PVFB Mouse");
+
+	xenfb_pub->update = xenfb_guest_copy;
+	xenfb_pub->user_data = ds;
+
+	/* Tell QEMU to allocate a graphical console */
+	graphic_console_init(ds,
+			     xenfb_update,
+			     xenfb_invalidate,
+			     xenfb_screen_dump,
+			     xenfb_pub);
+	dpy_resize(ds, xenfb_pub->width, xenfb_pub->height);
+
 	return 0;
 
  error:
@@ -719,66 +907,6 @@ int xenfb_attach_dom(struct xenfb *xenfb
         return -1;
 }
 
-static int xenfb_kbd_event(struct xenfb_private *xenfb,
-			   union xenkbd_in_event *event)
-{
-	uint32_t prod;
-	struct xenkbd_page *page = xenfb->kbd.page;
-
-	if (xenfb->kbd.state != XenbusStateConnected)
-		return 0;
-
-	prod = page->in_prod;
-	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
-		errno = EAGAIN;
-		return -1;
-	}
-
-	mb();			/* ensure ring space available */
-	XENKBD_IN_RING_REF(page, prod) = *event;
-	wmb();			/* ensure ring contents visible */
-	page->in_prod = prod + 1;
-	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	union xenkbd_in_event event;
-
-	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-	event.type = XENKBD_TYPE_KEY;
-	event.key.pressed = down ? 1 : 0;
-	event.key.keycode = keycode;
-
-	return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	union xenkbd_in_event event;
-
-	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-	event.type = XENKBD_TYPE_MOTION;
-	event.motion.rel_x = rel_x;
-	event.motion.rel_y = rel_y;
-
-	return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	union xenkbd_in_event event;
-
-	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-	event.type = XENKBD_TYPE_POS;
-	event.pos.abs_x = abs_x;
-	event.pos.abs_y = abs_y;
-
-	return xenfb_kbd_event(xenfb, &event);
-}
 /*
  * Local variables:
  *  c-indent-level: 8
diff -r c2aa6c7965a3 tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h	Wed Aug 15 14:17:30 2007 -0400
+++ b/tools/ioemu/hw/xenfb.h	Tue Aug 21 22:03:27 2007 -0400
@@ -1,6 +1,7 @@
 #ifndef _XENFB_H_
 #define _XENFB_H_
 
+#include "vl.h"
 #include <stdbool.h>
 #include <sys/types.h>
 
@@ -13,6 +14,7 @@ struct xenfb
 	int width;
 	int height;
 	int abs_pointer_wanted;
+	int button_state;
 
 	void *user_data;
 
@@ -23,10 +25,6 @@ void xenfb_delete(struct xenfb *xenfb);
 void xenfb_delete(struct xenfb *xenfb);
 void xenfb_teardown(struct xenfb *xenfb);
 
-int xenfb_attach_dom(struct xenfb *xenfb, int domid);
-
-int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
-int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
-int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
+int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds);
 
 #endif

xen-pvfb-06-xenfb-pubpriv-merge.patch:

--- NEW FILE xen-pvfb-06-xenfb-pubpriv-merge.patch ---
diff -r 9fcb930c2353 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c	Fri Oct 19 17:42:35 2007 -0400
+++ b/tools/ioemu/hw/xenfb.c	Fri Oct 19 17:43:41 2007 -0400
@@ -22,6 +22,8 @@
 
 // FIXME defend against malicious frontend?
 
+struct xenfb;
+
 struct xenfb_device {
 	const char *devicetype;
 	char nodename[64];	/* backend xenstore dir */
@@ -30,20 +32,33 @@ struct xenfb_device {
 	enum xenbus_state state; /* backend state */
 	void *page;		/* shared page */
 	evtchn_port_t port;
-	struct xenfb_private *xenfb;
+	struct xenfb *xenfb;
 };
 
-struct xenfb_private {
-	struct xenfb pub;
+struct xenfb_data
+{
+	void *pixels;
+	size_t len;
+
+	int row_stride;
+	int depth;
+	int width;
+	int height;
+	int abs_pointer_wanted;
+};
+
+struct xenfb {
+	DisplayState *ds;
 	int evt_xch;		/* event channel driver handle */
 	int xc;			/* hypervisor interface handle */
 	struct xs_handle *xsh;	/* xs daemon handle */
 	struct xenfb_device fb, kbd;
-	size_t fb_len;		/* size of framebuffer */
+	struct xenfb_data data;
 	char protocol[64];	/* frontend protocol */
+	int button_state;
 };
 
-static void xenfb_detach_dom(struct xenfb_private *);
+static void xenfb_detach_dom(struct xenfb *);
 
 static char *xenfb_path_in_dom(struct xs_handle *xsh,
 			       char *buf, size_t size,
@@ -124,7 +139,7 @@ static int xenfb_xs_printf(struct xs_han
 
 static void xenfb_device_init(struct xenfb_device *dev,
 			      const char *type,
-			      struct xenfb_private *xenfb)
+			      struct xenfb *xenfb)
 {
 	dev->devicetype = type;
 	dev->otherend_id = -1;
@@ -132,19 +147,17 @@ static void xenfb_device_init(struct xen
 	dev->xenfb = xenfb;
 }
 
-int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
-{
-	struct xenfb_private *xenfb = dev->xenfb;
-
+static int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
+{
 	dev->otherend_id = domid;
 
-	if (!xenfb_path_in_dom(xenfb->xsh,
+	if (!xenfb_path_in_dom(dev->xenfb->xsh,
 			       dev->otherend, sizeof(dev->otherend),
 			       domid, "device/%s/0", dev->devicetype)) {
 		errno = ENOENT;
 		return -1;
 	}
-	if (!xenfb_path_in_dom(xenfb->xsh,
+	if (!xenfb_path_in_dom(dev->xenfb->xsh,
 			       dev->nodename, sizeof(dev->nodename),
 			       0, "backend/%s/%d/0", dev->devicetype, domid)) {
 		errno = ENOENT;
@@ -156,8 +169,8 @@ int xenfb_device_set_domain(struct xenfb
 
 struct xenfb *xenfb_new(void)
 {
-	struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
 	int serrno;
+	struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
 
 	if (xenfb == NULL)
 		return NULL;
@@ -179,30 +192,26 @@ struct xenfb *xenfb_new(void)
 	if (!xenfb->xsh)
 		goto fail;
 
-	return &xenfb->pub;
+	return xenfb;
 
  fail:
 	serrno = errno;
-	xenfb_delete(&xenfb->pub);
+	xenfb_delete(xenfb);
 	errno = serrno;
 	return NULL;
 }
 
 /* Remove the backend area in xenbus since the framebuffer really is
    going away. */
-void xenfb_teardown(struct xenfb *xenfb_pub)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
+void xenfb_teardown(struct xenfb *xenfb)
+{
        xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
        xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
 }
 
 
-void xenfb_delete(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
+void xenfb_delete(struct xenfb *xenfb)
+{
 	xenfb_detach_dom(xenfb);
 	if (xenfb->xc >= 0)
 		xc_interface_close(xenfb->xc);
@@ -334,7 +343,7 @@ static void xenfb_copy_mfns(int mode, in
 		dst[i] = (mode == 32) ? src32[i] : src64[i];
 }
 
-static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
+static int xenfb_map_fb(struct xenfb *xenfb, int domid)
 {
 	struct xenfb_page *page = xenfb->fb.page;
 	int n_fbmfns;
@@ -389,7 +398,7 @@ static int xenfb_map_fb(struct xenfb_pri
 #endif
 	}
 
-	n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
+	n_fbmfns = (xenfb->data.len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
 	n_fbdirs = n_fbmfns * mode / 8;
 	n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
 
@@ -406,9 +415,9 @@ static int xenfb_map_fb(struct xenfb_pri
 	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
 	munmap(map, n_fbdirs * XC_PAGE_SIZE);
 
-	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
+	xenfb->data.pixels = xc_map_foreign_pages(xenfb->xc, domid,
 				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
-	if (xenfb->pub.pixels == NULL)
+	if (xenfb->data.pixels == NULL)
 		goto out;
 
 	ret = 0; /* all is fine */
@@ -423,7 +432,7 @@ static int xenfb_map_fb(struct xenfb_pri
 
 static int xenfb_bind(struct xenfb_device *dev)
 {
-	struct xenfb_private *xenfb = dev->xenfb;
+	struct xenfb *xenfb = dev->xenfb;
 	unsigned long mfn;
 	evtchn_port_t evtchn;
 
@@ -506,17 +515,74 @@ static void xenfb_dev_fatal(struct xenfb
 }
 
 
-static void xenfb_detach_dom(struct xenfb_private *xenfb)
+static void xenfb_detach_dom(struct xenfb *xenfb)
 {
 	xenfb_unbind(&xenfb->fb);
 	xenfb_unbind(&xenfb->kbd);
-	if (xenfb->pub.pixels) {
-		munmap(xenfb->pub.pixels, xenfb->fb_len);
-		xenfb->pub.pixels = NULL;
-	}
-}
-
-static void xenfb_on_fb_event(struct xenfb_private *xenfb)
+	if (xenfb->data.pixels) {
+		munmap(xenfb->data.pixels, xenfb->data.len);
+		xenfb->data.pixels = NULL;
+	}
+}
+
+/* A convenient function for munging pixels between different depths */
+#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
+	for (line = y ; line < h ; line++) {				\
+		SRC_T *src = (SRC_T *)(xenfb->data.pixels + (line*xenfb->data.row_stride) + (x*xenfb->data.depth/8)); \
+		DST_T *dst = (DST_T *)(xenfb->ds->data + (line*xenfb->ds->linesize) + (x*xenfb->ds->depth/8)); \
+		int col;						\
+		for (col = x ; col < w ; col++) {			\
+			*dst = (((*src >> RRS)&RM) << RLS) |		\
+				(((*src >> GRS)&GM) << GLS) |		\
+				(((*src >> GRS)&BM) << BLS);		\
+			src++;						\
+			dst++;						\
+		}							\
+	}
+
+
+/* This copies data from the guest framebuffer region, into QEMU's copy
+ * NB. QEMU's copy is stored in the pixel format of a) the local X server (SDL case)
+ * or b) the current VNC client pixel format.
+ */
+static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
+{
+	int line;
+
+	if (xenfb->data.depth == xenfb->ds->depth) { /* Perfect match can use fast path */
+		for (line = y ; line < (y+h) ; line++) {
+			memcpy(xenfb->ds->data + (line * xenfb->ds->linesize) + (x*xenfb->ds->depth/8),
+			       xenfb->data.pixels + (line*xenfb->data.row_stride) + (x*xenfb->data.depth/8),
+			       w * xenfb->data.depth/8);
+		}
+	} else { /* Mismatch requires slow pixel munging */
+		if (xenfb->data.depth == 8) {
+			/* 8 bit source == r:3 g:3 b:2 */
+			if (xenfb->ds->depth == 16) {
+				BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
+			} else if (xenfb->ds->depth == 32) {
+				BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
+			}
+		} else if (xenfb->data.depth == 16) {
+			/* 16 bit source == r:5 g:6 b:5 */
+			if (xenfb->ds->depth == 8) {
+				BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
+			} else if (xenfb->ds->depth == 32) {
+				BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
+			}
+		} else if (xenfb->data.depth == 32) {
+			/* 32 bit source == r:8 g:8 b:8 (padding:8) */
+			if (xenfb->ds->depth == 8) {
+				BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 255);
+			} else if (xenfb->ds->depth == 16) {
+				BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 255);
+			}
+		}
+	}
+	dpy_update(xenfb->ds, x, y, w, h);
+}
+
+static void xenfb_on_fb_event(struct xenfb *xenfb)
 {
 	uint32_t prod, cons;
 	struct xenfb_page *page = xenfb->fb.page;
@@ -530,11 +596,10 @@ static void xenfb_on_fb_event(struct xen
 
 		switch (event->type) {
 		case XENFB_TYPE_UPDATE:
-                    if (xenfb->pub.update)
-			xenfb->pub.update(&xenfb->pub,
-					  event->update.x, event->update.y,
-					  event->update.width, event->update.height);
-                    break;
+			xenfb_guest_copy(xenfb,
+					 event->update.x, event->update.y,
+					 event->update.width, event->update.height);
+			break;
 		}
 	}
 	mb();			/* ensure we're done with ring contents */
@@ -542,7 +607,7 @@ static void xenfb_on_fb_event(struct xen
 	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
 }
 
-static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
+static void xenfb_on_kbd_event(struct xenfb *xenfb)
 {
 	struct xenkbd_page *page = xenfb->kbd.page;
 
@@ -580,7 +645,7 @@ static int xenfb_on_state_change(struct 
 	return 0;
 }
 
-static int xenfb_kbd_event(struct xenfb_private *xenfb,
+static int xenfb_kbd_event(struct xenfb *xenfb,
 			   union xenkbd_in_event *event)
 {
 	uint32_t prod;
@@ -602,9 +667,8 @@ static int xenfb_kbd_event(struct xenfb_
 	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
 }
 
-static int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode)
+{
 	union xenkbd_in_event event;
 
 	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
@@ -615,9 +679,8 @@ static int xenfb_send_key(struct xenfb *
 	return xenfb_kbd_event(xenfb, &event);
 }
 
-static int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y)
+{
 	union xenkbd_in_event event;
 
 	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
@@ -628,9 +691,8 @@ static int xenfb_send_motion(struct xenf
 	return xenfb_kbd_event(xenfb, &event);
 }
 
-static int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y)
+{
 	union xenkbd_in_event event;
 
 	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
@@ -654,11 +716,11 @@ static void xenfb_mouse_event(void *opaq
 {
 	int i;
 	struct xenfb *xenfb = (struct xenfb*)opaque;
-	DisplayState *ds = (DisplayState *)xenfb->user_data;
-	if (xenfb->abs_pointer_wanted)
+
+	if (xenfb->data.abs_pointer_wanted)
 		xenfb_send_position(xenfb,
-				    dx*ds->width/0x7fff,
-				    dy*ds->height/0x7fff);
+				    dx*xenfb->ds->width/0x7fff,
+				    dy*xenfb->ds->height/0x7fff);
 	else
 		xenfb_send_motion(xenfb, dx, dy);
 
@@ -674,76 +736,19 @@ static void xenfb_mouse_event(void *opaq
 	xenfb->button_state = button_state;
 }
 
-/* A convenient function for munging pixels between different depths */
-#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
-	for (line = y ; line < h ; line++) {				\
-		SRC_T *src = (SRC_T *)(xenfb->pixels + (line*xenfb->row_stride) + (x*xenfb->depth/8)); \
-		DST_T *dst = (DST_T *)(ds->data + (line*ds->linesize) + (x*ds->depth/8)); \
-		int col;						\
-		for (col = x ; col < w ; col++) {			\
-			*dst = (((*src >> RRS)&RM) << RLS) |		\
-				(((*src >> GRS)&GM) << GLS) |		\
-				(((*src >> GRS)&BM) << BLS);		\
-			src++;						\
-			dst++;						\
-		}							\
-	}
-
-
-/* This copies data from the guest framebuffer region, into QEMU's copy
- * NB. QEMU's copy is stored in the pixel format of a) the local X server (SDL case)
- * or b) the current VNC client pixel format.
- */
-static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
-{
-	DisplayState *ds = (DisplayState *)xenfb->user_data;
-	int line;
-
-	if (xenfb->depth == ds->depth) { /* Perfect match can use fast path */
-		for (line = y ; line < (y+h) ; line++) {
-			memcpy(ds->data + (line * ds->linesize) + (x*ds->depth/8),
-			       xenfb->pixels + (line*xenfb->row_stride) + (x*xenfb->depth/8),
-			       w * xenfb->depth/8);
-		}
-	} else { /* Mismatch requires slow pixel munging */
-		if (xenfb->depth == 8) {
-			/* 8 bit source == r:3 g:3 b:2 */
-			if (ds->depth == 16) {
-				BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
-			} else if (ds->depth == 32) {
-				BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
-			}
-		} else if (xenfb->depth == 16) {
-			/* 16 bit source == r:5 g:6 b:5 */
-			if (ds->depth == 8) {
-				BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
-			} else if (ds->depth == 32) {
-				BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
-			}
-		} else if (xenfb->depth == 32) {
-			/* 32 bit source == r:8 g:8 b:8 (padding:8) */
-			if (ds->depth == 8) {
-				BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 255);
-			} else if (ds->depth == 16) {
-				BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 255);
-			}
-		}
-	}
-	dpy_update(ds, x, y, w, h);
-}
 
 /* QEMU display state changed, so refresh the framebuffer copy */
 static void xenfb_update(void *opaque)
 {
 	struct xenfb *xenfb = (struct xenfb *)opaque;
-	xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+	xenfb_guest_copy(xenfb, 0, 0, xenfb->data.width, xenfb->data.height);
 }
 
 /* QEMU display state changed, so refresh the framebuffer copy */
 static void xenfb_invalidate(void *opaque)
 {
 	struct xenfb *xenfb = (struct xenfb *)opaque;
-	xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+	xenfb_guest_copy(xenfb, 0, 0, xenfb->data.width, xenfb->data.height);
 }
 
 /* Screen dump is not used in Xen, so no need to impl this ? */
@@ -751,9 +756,9 @@ static void xenfb_screen_dump(void *opaq
 
 
 
-static void xenfb_dispatch_channel(void *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static void xenfb_dispatch_channel(void *opaque)
+{
+	struct xenfb *xenfb = (struct xenfb *)opaque;
 	evtchn_port_t port;
 	port = xc_evtchn_pending(xenfb->evt_xch);
 	if (port == -1)
@@ -768,9 +773,9 @@ static void xenfb_dispatch_channel(void 
 		exit(1);
 }
 
-static void xenfb_dispatch_store(void *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static void xenfb_dispatch_store(void *opaque)
+{
+	struct xenfb *xenfb = (struct xenfb *)opaque;
 	unsigned dummy;
 	char **vec;
 	int r;
@@ -785,9 +790,8 @@ static void xenfb_dispatch_store(void *x
 }
 
 
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid, DisplayState *ds)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds)
+{
 	struct xs_handle *xsh = xenfb->xsh;
 	int val, serrno;
 	struct xenfb_page *fb_page;
@@ -843,12 +847,12 @@ int xenfb_attach_dom(struct xenfb *xenfb
 
 	/* TODO check for permitted ranges */
 	fb_page = xenfb->fb.page;
-	xenfb->pub.depth = fb_page->depth;
-	xenfb->pub.width = fb_page->width;
-	xenfb->pub.height = fb_page->height;
+	xenfb->data.depth = fb_page->depth;
+	xenfb->data.width = fb_page->width;
+	xenfb->data.height = fb_page->height;
 	/* TODO check for consistency with the above */
-	xenfb->fb_len = fb_page->mem_length;
-	xenfb->pub.row_stride = fb_page->line_length;
+	xenfb->data.len = fb_page->mem_length;
+	xenfb->data.row_stride = fb_page->line_length;
 
 	if (xenfb_map_fb(xenfb, domid) < 0)
 		goto error;
@@ -863,7 +867,7 @@ int xenfb_attach_dom(struct xenfb *xenfb
 	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
 			    "%d", &val) < 0)
 		val = 0;
-	xenfb->pub.abs_pointer_wanted = val;
+	xenfb->data.abs_pointer_wanted = val;
 
 	/* Listen for events from xenstore */
 	if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)
@@ -876,19 +880,18 @@ int xenfb_attach_dom(struct xenfb *xenfb
 	/* Register our keyboard & mouse handlers */
 	qemu_add_kbd_event_handler(xenfb_put_keycode, xenfb);
 	qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
-				     xenfb_pub->abs_pointer_wanted,
+				     xenfb->data.abs_pointer_wanted,
 				     "Xen PVFB Mouse");
 
-	xenfb_pub->update = xenfb_guest_copy;
-	xenfb_pub->user_data = ds;
+	xenfb->ds = ds;
 
 	/* Tell QEMU to allocate a graphical console */
 	graphic_console_init(ds,
 			     xenfb_update,
 			     xenfb_invalidate,
 			     xenfb_screen_dump,
-			     xenfb_pub);
-	dpy_resize(ds, xenfb_pub->width, xenfb_pub->height);
+			     xenfb);
+	dpy_resize(ds, xenfb->data.width, xenfb->data.height);
 
 	return 0;
 
diff -r 9fcb930c2353 tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h	Fri Oct 19 17:42:35 2007 -0400
+++ b/tools/ioemu/hw/xenfb.h	Fri Oct 19 17:42:36 2007 -0400
@@ -5,21 +5,7 @@
 #include <stdbool.h>
 #include <sys/types.h>
 
-struct xenfb
-{
-	void *pixels;
-
-	int row_stride;
-	int depth;
-	int width;
-	int height;
-	int abs_pointer_wanted;
-	int button_state;
-
-	void *user_data;
-
-	void (*update)(struct xenfb *xenfb, int x, int y, int width, int height);
-};
+struct xenfb;
 
 struct xenfb *xenfb_new(void);
 void xenfb_delete(struct xenfb *xenfb);

xen-pvfb-07-xenfb-async-startup.patch:

--- NEW FILE xen-pvfb-07-xenfb-async-startup.patch ---
diff -r 829464d36542 tools/ioemu/hw/xen_machine_pv.c
--- a/tools/ioemu/hw/xen_machine_pv.c	Tue Aug 21 22:07:47 2007 -0400
+++ b/tools/ioemu/hw/xen_machine_pv.c	Tue Aug 21 22:08:24 2007 -0400
@@ -41,16 +41,9 @@ static void xen_init_pv(uint64_t ram_siz
     extern int domid;
 
     /* Prepare PVFB state */
-    xenfb = xenfb_new();
+    xenfb = xenfb_new(domid, ds);
     if (xenfb == NULL) {
         fprintf(stderr, "Could not create framebuffer (%s)\n",
-                strerror(errno));
-        exit(1);
-    }
-
-    /* Talk to the guest */
-    if (xenfb_attach_dom(xenfb, domid, ds) < 0) {
-        fprintf(stderr, "Could not connect to domain (%s)\n",
                 strerror(errno));
         exit(1);
     }
diff -r 829464d36542 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c	Tue Aug 21 22:07:47 2007 -0400
+++ b/tools/ioemu/hw/xenfb.c	Tue Aug 21 22:14:04 2007 -0400
@@ -19,6 +19,12 @@
 #include <linux/input.h>
 
 #include "xenfb.h"
+#define DEBUG 1
+#if DEBUG
+#define LOGF(msg,...) fprintf(stderr, msg, ## __VA_ARGS__)
+#else
+#define LOGF(msg,...) do { } while (0)
+#endif
 
 // FIXME defend against malicious frontend?
 
@@ -167,60 +173,6 @@ static int xenfb_device_set_domain(struc
 	return 0;
 }
 
-struct xenfb *xenfb_new(void)
-{
-	int serrno;
-	struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
-
-	if (xenfb == NULL)
-		return NULL;
-
-	memset(xenfb, 0, sizeof(*xenfb));
-	xenfb->evt_xch = xenfb->xc = -1;
-	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
-	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
-
-	xenfb->evt_xch = xc_evtchn_open();
-	if (xenfb->evt_xch == -1)
-		goto fail;
-
-	xenfb->xc = xc_interface_open();
-	if (xenfb->xc == -1)
-		goto fail;
-
-	xenfb->xsh = xs_daemon_open();
-	if (!xenfb->xsh)
-		goto fail;
-
-	return xenfb;
-
- fail:
-	serrno = errno;
-	xenfb_delete(xenfb);
-	errno = serrno;
-	return NULL;
-}
-
-/* Remove the backend area in xenbus since the framebuffer really is
-   going away. */
-void xenfb_teardown(struct xenfb *xenfb)
-{
-       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
-       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
-}
-
-
-void xenfb_delete(struct xenfb *xenfb)
-{
-	xenfb_detach_dom(xenfb);
-	if (xenfb->xc >= 0)
-		xc_interface_close(xenfb->xc);
-	if (xenfb->evt_xch >= 0)
-		xc_evtchn_close(xenfb->evt_xch);
-	if (xenfb->xsh)
-		xs_daemon_close(xenfb->xsh);
-	free(xenfb);
-}
 
 static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
 					  const char *dir)
@@ -228,6 +180,7 @@ static enum xenbus_state xenfb_read_stat
 	int ret, state;
 
 	ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
+	LOGF("FB: read state %d %d\n", state, ret);
 	if (ret < 0)
 		return XenbusStateUnknown;
 
@@ -240,65 +193,10 @@ static int xenfb_switch_state(struct xen
 			      enum xenbus_state state)
 {
 	struct xs_handle *xsh = dev->xenfb->xsh;
-
+	/*LOGF("FB: write state %d\n", state);*/
 	if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
 		return -1;
 	dev->state = state;
-	return 0;
-}
-
-static int xenfb_wait_for_state(struct xs_handle *xsh, const char *dir,
-				unsigned awaited)
-{
-	unsigned state, dummy;
-	char **vec;
-
-	awaited |= 1 << XenbusStateUnknown;
-
-	for (;;) {
-		state = xenfb_read_state(xsh, dir);
-		if ((1 << state) & awaited)
-			return state;
-
-		vec = xs_read_watch(xsh, &dummy);
-		if (!vec)
-			return -1;
-		free(vec);
-	}
-}
-
-static int xenfb_wait_for_backend_creation(struct xenfb_device *dev)
-{
-	struct xs_handle *xsh = dev->xenfb->xsh;
-	int state;
-
-	if (!xs_watch(xsh, dev->nodename, ""))
-		return -1;
-	state = xenfb_wait_for_state(xsh, dev->nodename,
-			(1 << XenbusStateInitialising)
-			| (1 << XenbusStateClosed)
-#if 1 /* TODO fudging state to permit restarting; to be removed */
-			| (1 << XenbusStateInitWait)
-			| (1 << XenbusStateConnected)
-			| (1 << XenbusStateClosing)
-#endif
-			);
-	xs_unwatch(xsh, dev->nodename, "");
-
-	switch (state) {
-#if 1
-	case XenbusStateInitWait:
-	case XenbusStateConnected:
-		printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
-#endif
-	case XenbusStateInitialising:
-	case XenbusStateClosing:
-	case XenbusStateClosed:
-		break;
-	default:
-		return -1;
-	}
-
 	return 0;
 }
 
@@ -310,28 +208,6 @@ static int xenfb_hotplug(struct xenfb_de
 	return 0;
 }
 
-static int xenfb_wait_for_frontend_initialised(struct xenfb_device *dev)
-{
-	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
-#if 1 /* TODO fudging state to permit restarting; to be removed */
-			(1 << XenbusStateInitialised)
-			| (1 << XenbusStateConnected)
-#else
-			1 << XenbusStateInitialised,
-#endif
-			)) {
-#if 1
-	case XenbusStateConnected:
-		printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
-#endif
-	case XenbusStateInitialised:
-		break;
-	default:
-		return -1;
-	}
-
-	return 0;
-}
 
 static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
 {
@@ -474,52 +350,6 @@ static void xenfb_unbind(struct xenfb_de
 	}
 }
 
-static int xenfb_wait_for_frontend_connected(struct xenfb_device *dev)
-{
-	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
-				     1 << XenbusStateConnected)) {
-	case XenbusStateConnected:
-		break;
-	default:
-		return -1;
-	}
-
-	return 0;
-}
-
-static void xenfb_dev_fatal(struct xenfb_device *dev, int err,
-			    const char *fmt, ...)
-{
-	struct xs_handle *xsh = dev->xenfb->xsh;
-	va_list ap;
-	char errdir[80];
-	char buf[1024];
-	int n;
-
-	fprintf(stderr, "%s ", dev->nodename); /* somewhat crude */
-	va_start(ap, fmt);
-	vfprintf(stderr, fmt, ap);
-	va_end(ap);
-	if (err)
-		fprintf(stderr, " (%s)", strerror(err));
-	putc('\n', stderr);
-
-	if (!xenfb_path_in_dom(xsh, errdir, sizeof(errdir), 0,
-			       "error/%s", dev->nodename))
-		goto out;	/* FIXME complain */
-
-	va_start(ap, fmt);
-	n = snprintf(buf, sizeof(buf), "%d ", err);
-	snprintf(buf + n, sizeof(buf) - n, fmt, ap);
-	va_end(ap);
-
-	if (xenfb_xs_printf(xsh, buf, "error", "%s", buf) < 0)
-		goto out;	/* FIXME complain */
-
- out:
-	xenfb_switch_state(dev, XenbusStateClosing);
-}
-
 
 static void xenfb_detach_dom(struct xenfb *xenfb)
 {
@@ -673,6 +503,8 @@ static int xenfb_kbd_event(struct xenfb 
 	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
 }
 
+
+/* Send a keyboard (or mouse button) event */
 static int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode)
 {
 	union xenkbd_in_event event;
@@ -685,10 +517,11 @@ static int xenfb_send_key(struct xenfb *
 	return xenfb_kbd_event(xenfb, &event);
 }
 
+/* Send a relative mouse movement event */
 static int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y)
 {
 	union xenkbd_in_event event;
-
+	LOGF("REL %d %d\n", rel_x, rel_y);
 	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
 	event.type = XENKBD_TYPE_MOTION;
 	event.motion.rel_x = rel_x;
@@ -697,10 +530,11 @@ static int xenfb_send_motion(struct xenf
 	return xenfb_kbd_event(xenfb, &event);
 }
 
+/* Send an absolute mouse movement event */
 static int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y)
 {
 	union xenkbd_in_event event;
-
+	LOGF("ABS %d %d\n", abs_x, abs_y);
 	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
 	event.type = XENKBD_TYPE_POS;
 	event.pos.abs_x = abs_x;
@@ -753,161 +587,459 @@ static void xenfb_update(void *opaque)
 /* QEMU display state changed, so refresh the framebuffer copy */
 static void xenfb_invalidate(void *opaque)
 {
-	struct xenfb *xenfb = (struct xenfb *)opaque;
-	xenfb_guest_copy(xenfb, 0, 0, xenfb->data.width, xenfb->data.height);
+	xenfb_update(opaque);
 }
 
 /* Screen dump is not used in Xen, so no need to impl this ? */
 static void xenfb_screen_dump(void *opaque, const char *name) { }
 
 
-
+/* Process events from the frontend event channel */
 static void xenfb_dispatch_channel(void *opaque)
 {
 	struct xenfb *xenfb = (struct xenfb *)opaque;
 	evtchn_port_t port;
 	port = xc_evtchn_pending(xenfb->evt_xch);
-	if (port == -1)
+	if (port == -1) {
+		xenfb_shutdown(xenfb);
 		exit(1);
+	}
 
 	if (port == xenfb->fb.port)
 		xenfb_on_fb_event(xenfb);
 	else if (port == xenfb->kbd.port)
 		xenfb_on_kbd_event(xenfb);
 
-	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
+	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1) {
+		xenfb_shutdown(xenfb);
 		exit(1);
-}
-
-static void xenfb_dispatch_store(void *opaque)
-{
-	struct xenfb *xenfb = (struct xenfb *)opaque;
-	unsigned dummy;
-	char **vec;
-	int r;
-
-	vec = xs_read_watch(xenfb->xsh, &dummy);
-	free(vec);
-	r = xenfb_on_state_change(&xenfb->fb);
-	if (r == 0)
-		r = xenfb_on_state_change(&xenfb->kbd);
-	if (r == -1)
-		exit(1);
-}
-
-
-int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds)
-{
-	struct xs_handle *xsh = xenfb->xsh;
-	int val, serrno;
+	}
+}
+
+
+/* Process ongoing events from the frontend devices */
+static void xenfb_frontend_disconnected_kbd(void *opaque)
+{
+	struct xenfb_device *dev = (struct xenfb_device *)opaque;
+  	unsigned dummy;
+  	char **vec;
+  	int r;
+	vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+  	free(vec);
+
+	r = xenfb_on_state_change(&dev->xenfb->kbd);
+	if (r >= 0)
+		r = xenfb_on_state_change(&dev->xenfb->fb);
+
+	if (r < 0) {
+		xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
+		xenfb_shutdown(dev->xenfb);
+	}
+}
+
+
+/* Register a QEMU console & input handlers */
+static void xenfb_register_console(struct xenfb *xenfb) {
+  	/* Register our keyboard & mouse handlers */
+  	qemu_add_kbd_event_handler(xenfb_put_keycode, xenfb);
+  	qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
+  				     xenfb->data.abs_pointer_wanted,
+  				     "Xen PVFB Mouse");
+  
+	/* Tell QEMU to allocate a graphical console even though
+	 * we're not connected - so user at least has a black screen
+	 * to look at ;-) */
+	graphic_console_init(xenfb->ds,
+  			     xenfb_update,
+  			     xenfb_invalidate,
+  			     xenfb_screen_dump,
+  			     xenfb);
+
+	LOGF("FB: Connected, resizing framebuffer\n");
+	dpy_resize(xenfb->ds, xenfb->data.width, xenfb->data.height);
+}
+
+/* Process the frontend framebuffer config */
+static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) {
 	struct xenfb_page *fb_page;
-
-	xenfb_detach_dom(xenfb);
-
-	xenfb_device_set_domain(&xenfb->fb, domid);
-	xenfb_device_set_domain(&xenfb->kbd, domid);
-
-	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
-		goto error;
-	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
-		goto error;
-	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
-		goto error;
-
-	if (xenfb_hotplug(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_hotplug(&xenfb->kbd) < 0)
-		goto error;
-
-	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
-		goto error;
-	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
-		goto error;
-
-	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_bind(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_bind(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
-			    "%d", &val) < 0)
-		val = 0;
-	if (!val) {
-		errno = ENOTSUP;
-		goto error;
-	}
-	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
-			    xenfb->protocol) < 0)
-		xenfb->protocol[0] = '\0';
-	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
-
-	/* TODO check for permitted ranges */
-	fb_page = xenfb->fb.page;
-	xenfb->data.depth = fb_page->depth;
-	xenfb->data.width = fb_page->width;
-	xenfb->data.height = fb_page->height;
-	/* TODO check for consistency with the above */
-	xenfb->data.len = fb_page->mem_length;
-	xenfb->data.row_stride = fb_page->line_length;
-
-	if (xenfb_map_fb(xenfb, domid) < 0)
-		goto error;
-
-	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
-		goto error;
-	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
-		goto error;
-
-	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
-		goto error;
-	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
+	int val;
+
+        if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update",
+                            "%d", &val) < 0)
+                val = 0;
+        if (!val) {
+                LOGF("feature-update not supported\n");
+                errno = ENOTSUP;
+                return -1;
+        }
+        if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "protocol", "%63s",
+                            xenfb->protocol) < 0)
+                xenfb->protocol[0] = '\0';
+        xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1");
+
+        /* TODO check for permitted ranges */
+        fb_page = xenfb->fb.page;
+        xenfb->data.depth = fb_page->depth;
+        xenfb->data.width = fb_page->width;
+        xenfb->data.height = fb_page->height;
+        /* TODO check for consistency with the above */
+        xenfb->data.len = fb_page->mem_length;
+        xenfb->data.row_stride = fb_page->line_length;
+        LOGF("Framebuffer depth %d width %d height %d line %d\n",
+                fb_page->depth, fb_page->width, fb_page->height, fb_page->line_length);
+        if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0)
+		return -1;
+
+        if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
+                return -1;
+        if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
+                return -1;
+
+	return 0;
+}
+
+/* Process the frontend keyboard config */
+static int xenfb_read_frontend_kbd_config(struct xenfb *xenfb)
+{
+	int val;
+
+	if (xenfb_xs_scanf1(xenfb->xsh, xenfb->kbd.otherend, "request-abs-pointer",
 			    "%d", &val) < 0)
 		val = 0;
 	xenfb->data.abs_pointer_wanted = val;
 
-	/* Listen for events from xenstore */
-	if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)
-		goto error;
-
-	/* Listen for events from the event channel */
-	if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
-		goto error;
-
-	/* Register our keyboard & mouse handlers */
-	qemu_add_kbd_event_handler(xenfb_put_keycode, xenfb);
-	qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
-				     xenfb->data.abs_pointer_wanted,
-				     "Xen PVFB Mouse");
-
+	return 0;
+}
+
+/* Register a watch against a frontend device, and setup
+ * QEMU event loop to poll the xenstore FD for notification */
+static int xenfb_wait_for_frontend(struct xenfb_device *dev, IOHandler *handler)
+{
+        LOGF("Doing frontend watch on %s\n", dev->otherend);
+	if (!xs_watch(dev->xenfb->xsh, dev->otherend, "")) {
+		LOGF("Watch for dev failed\n");
+		return -1;
+	}
+
+	if (qemu_set_fd_handler2(xs_fileno(dev->xenfb->xsh), NULL, handler, NULL, dev) < 0)
+		return -1;
+
+	return 0;
+}
+
+/* Register a watch against a backend device, and setup
+ * QEMU event loop to poll the xenstore FD for notification */
+static int xenfb_wait_for_backend(struct xenfb_device *dev, IOHandler *handler)
+{
+	LOGF("Doing backend watch on %s\n", dev->nodename);
+	if (!xs_watch(dev->xenfb->xsh, dev->nodename, "")) {
+		LOGF("Watch for dev failed\n");
+		return -1;
+	}
+
+	if (qemu_set_fd_handler2(xs_fileno(dev->xenfb->xsh), NULL, handler, NULL, dev) < 0)
+		return -1;
+
+	return 0;
+}
+
+
+/* Helper to determine if a frontend device is in Connected state */
+static int xenfb_frontend_connected(struct xenfb_device *dev)
+{
+	unsigned int state;
+	unsigned int dummy;
+	char **vec;
+	vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+	if (!vec) {
+		xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
+		return -1;
+	}
+	free(vec);
+
+	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
+	if (!((1 <<state) & ((1 << XenbusStateUnknown) |
+			     (1 << XenbusStateConnected)))) {
+		LOGF("FB: Carry on waiting\n");
+		return 1;
+	}
+
+	xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
+
+	switch (state) {
+	case XenbusStateConnected:
+		break;
+	default:
+		return -1;
+	}
+	return 0;
+}
+
+
+/* Helper to determine if a frontend device is in Initialized state */
+static int xenfb_frontend_initialized(struct xenfb_device *dev)
+{
+	unsigned int state;
+	unsigned int dummy;
+	char **vec;
+	vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+	if (!vec) {
+		xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
+		return -1;
+	}
+	free(vec);
+
+	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
+
+	if (!((1 << state) & ((1 << XenbusStateUnknown)
+			      | (1 << XenbusStateInitialised)
+#if 1 /* TODO fudging state to permit restarting; to be removed */
+			      | (1 << XenbusStateConnected)
+#endif
+			      ))) {
+		LOGF("FB: Carry on waiting\n");
+		return 1;
+	}
+
+	xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
+
+	switch (state) {
+#if 1
+	case XenbusStateConnected:
+                LOGF("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
+#endif
+        case XenbusStateInitialised:
+                break;
+        default:
+                return -1;
+        }
+
+	if (xenfb_bind(dev) < 0)
+		return -1;
+
+	return 0;
+}
+
+/* Helper to determine if a backend device is in Created state */
+int xenfb_backend_created(struct xenfb_device *dev)
+{
+	unsigned int state;
+	unsigned int dummy;
+	char **vec;
+	vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+	if (!vec) {
+		xs_unwatch(dev->xenfb->xsh, dev->nodename, "");
+		return -1;
+	}
+	free(vec);
+
+	state = xenfb_read_state(dev->xenfb->xsh, dev->nodename);
+
+	if (!((1 <<state) & ((1 << XenbusStateUnknown)
+			     | (1 << XenbusStateInitialising)
+			     | (1 << XenbusStateClosed)
+#if 1 /* TODO fudging state to permit restarting; to be removed */
+			     | (1 << XenbusStateInitWait)
+			     | (1 << XenbusStateConnected)
+			     | (1 << XenbusStateClosing)
+#endif
+			     ))) {
+		LOGF("FB: Carry on waiting\n");
+		return 1;
+	}
+
+	xs_unwatch(dev->xenfb->xsh, dev->nodename, "");
+
+        switch (state) {
+#if 1
+        case XenbusStateInitWait:
+        case XenbusStateConnected:
+                LOGF("FB: Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
+#endif
+        case XenbusStateInitialising:
+        case XenbusStateClosing:
+        case XenbusStateClosed:
+                break;
+        default:
+                LOGF("FB: Wrong state %d\n", state);
+                return -1;
+        }
+        xenfb_switch_state(dev, XenbusStateInitWait);
+        if (xenfb_hotplug(dev) < 0)
+                return -1;
+
+        return 0;
+}
+
+/* Callback invoked while waiting for KBD frontend to change
+ * to the connected state */
+void xenfb_frontend_connected_kbd(void *opaque)
+{
+	struct xenfb_device *dev = (struct xenfb_device *)opaque;
+	int ret = xenfb_frontend_connected(dev);
+	if (ret < 0) {
+		xenfb_shutdown(dev->xenfb);
+		return;
+	}
+	if (ret)
+		return; /* Still waiting */
+
+	if (xenfb_read_frontend_kbd_config(dev->xenfb) < 0) {
+		xenfb_shutdown(dev->xenfb);
+	        return;
+	}
+
+	xenfb_register_console(dev->xenfb);
+
+        if (qemu_set_fd_handler2(dev->xenfb->evt_xch, NULL, xenfb_dispatch_channel, NULL, dev->xenfb) < 0) {
+		xenfb_shutdown(dev->xenfb);
+                return;
+	}
+
+        LOGF("FB: Waiting for KBD frontend disconnection\n");
+	xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_disconnected_kbd);
+}
+
+/* Callback invoked while waiting for FB frontend to change
+ * to the initialized state */
+void xenfb_frontend_initialized_fb(void *opaque)
+{
+	struct xenfb_device *dev = (struct xenfb_device *)opaque;
+	int ret = xenfb_frontend_initialized(dev);
+	if (ret < 0) {
+		xenfb_shutdown(dev->xenfb);
+		return;
+	}
+	if (ret)
+		return; /* Still waiting */
+
+
+	if (xenfb_read_frontend_fb_config(dev->xenfb)) {
+		xenfb_shutdown(dev->xenfb);
+	        return;
+	}
+
+        LOGF("FB: Waiting for KBD frontend connection\n");
+	xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_connected_kbd);
+}
+
+/* Callback invoked while waiting for KBD frontend to change
+ * to the initialized state */
+void xenfb_frontend_initialized_kbd(void *opaque)
+{
+	struct xenfb_device *dev = (struct xenfb_device *)opaque;
+	int ret = xenfb_frontend_initialized(dev);
+	if (ret < 0) {
+		xenfb_shutdown(dev->xenfb);
+		return;
+	}
+	if (ret)
+		return; /* Still waiting */
+
+
+        LOGF("FB: Waiting for FB frontend initialization\n");
+	xenfb_wait_for_frontend(&dev->xenfb->fb, xenfb_frontend_initialized_fb);
+}
+
+/* Callback invoked while waiting for FB backend to change
+ * to the created state */
+void xenfb_backend_created_fb(void *opaque)
+{
+	struct xenfb_device *dev = (struct xenfb_device *)opaque;
+	int ret = xenfb_backend_created(dev);
+	if (ret < 0) {
+		xenfb_shutdown(dev->xenfb);
+		return;
+	}
+	if (ret)
+		return; /* Still waiting */
+
+	LOGF("FB: Waiting for KBD frontend initialization\n");
+	xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_initialized_kbd);
+}
+
+/* Callback invoked while waiting for KBD backend to change
+ * to the created state */
+void xenfb_backend_created_kbd(void *opaque)
+{
+	struct xenfb_device *dev = (struct xenfb_device *)opaque;
+	int ret = xenfb_backend_created(dev);
+	if (ret < 0) {
+		xenfb_shutdown(dev->xenfb);
+		return;
+	}
+	if (ret)
+		return; /* Still waiting */
+
+	if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename, "feature-abs-pointer", "1")) {
+		xenfb_shutdown(dev->xenfb);
+		return;
+	}
+
+	LOGF("FB: Waiting for FB backend creation\n");
+	xenfb_wait_for_backend(&dev->xenfb->fb, xenfb_backend_created_fb);
+}
+
+
+/* Create a new Xen FB associated with QEMU DisplayState,
+ * wait for domid to appear and connect to its frontend */
+struct xenfb *xenfb_new(int domid, DisplayState *ds)
+{
+	int serrno;
+	struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
+
+	if (xenfb == NULL)
+		return NULL;
+
+	memset(xenfb, 0, sizeof(*xenfb));
 	xenfb->ds = ds;
-
-	/* Tell QEMU to allocate a graphical console */
-	graphic_console_init(ds,
-			     xenfb_update,
-			     xenfb_invalidate,
-			     xenfb_screen_dump,
-			     xenfb);
-	dpy_resize(ds, xenfb->data.width, xenfb->data.height);
-
-	return 0;
-
- error:
-	serrno = errno;
-	xenfb_detach_dom(xenfb);
-	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
-	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
-        errno = serrno;
-        return -1;
+	xenfb->evt_xch = xenfb->xc = -1;
+	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
+	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
+
+	xenfb->evt_xch = xc_evtchn_open();
+	if (xenfb->evt_xch == -1)
+		goto fail;
+
+	xenfb->xc = xc_interface_open();
+	if (xenfb->xc == -1)
+		goto fail;
+
+	xenfb->xsh = xs_daemon_open();
+	if (!xenfb->xsh)
+		goto fail;
+
+	xenfb_device_set_domain(&xenfb->fb, domid);
+	xenfb_device_set_domain(&xenfb->kbd, domid);
+
+        LOGF("FB: Waiting for KBD backend creation\n");
+        xenfb_wait_for_backend(&xenfb->kbd, xenfb_backend_created_kbd);
+
+	return xenfb;
+
+ fail:
+  	serrno = errno;
+	xenfb_shutdown(xenfb);
+	errno = serrno;
+	return NULL;
+}
+
+/* Remove the backend area in xenbus since the framebuffer really is
+   going away. */
+void xenfb_shutdown(struct xenfb *xenfb)
+{
+	LOGF("FB: Shutting down backend\n");
+	xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
+	xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
+
+  	xenfb_detach_dom(xenfb);
+	if (xenfb->xc >= 0)
+		xc_interface_close(xenfb->xc);
+	if (xenfb->evt_xch >= 0)
+		xc_evtchn_close(xenfb->evt_xch);
+	if (xenfb->xsh)
+		xs_daemon_close(xenfb->xsh);
+	free(xenfb);
 }
 
 /*
diff -r 829464d36542 tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h	Tue Aug 21 22:07:47 2007 -0400
+++ b/tools/ioemu/hw/xenfb.h	Tue Aug 21 22:08:24 2007 -0400
@@ -7,10 +7,7 @@
 
 struct xenfb;
 
-struct xenfb *xenfb_new(void);
-void xenfb_delete(struct xenfb *xenfb);
-void xenfb_teardown(struct xenfb *xenfb);
-
-int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds);
+struct xenfb *xenfb_new(int domid, DisplayState *ds);
+void xenfb_shutdown(struct xenfb *xenfb);
 
 #endif

xen-pvfb-08-xen-console-qemu.patch:

--- NEW FILE xen-pvfb-08-xen-console-qemu.patch ---
diff -r e6b8a2d93de9 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target	Fri Oct 19 17:52:43 2007 -0400
+++ b/tools/ioemu/Makefile.target	Fri Oct 19 19:32:55 2007 -0400
@@ -412,6 +412,7 @@ VL_OBJS+= xen_machine_fv.o
 VL_OBJS+= xen_machine_fv.o
 VL_OBJS+= xen_machine_pv.o
 VL_OBJS+= xenfb.o
+VL_OBJS+= xen_console.o
 VL_OBJS+= tpm_tis.o
 CPPFLAGS += -DHAS_AUDIO
 endif
diff -r e6b8a2d93de9 tools/ioemu/hw/xen_console.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xen_console.c	Fri Oct 19 19:32:55 2007 -0400
@@ -0,0 +1,424 @@
+/*
+ *  Copyright (C) International Business Machines  Corp., 2005
+ *  Author(s): Anthony Liguori <aliguori at us.ibm.com>
+ *
+ *  Copyright (C) Red Hat 2007
+ *
+ *  Xen Console
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <malloc.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include <xs.h>
+#include <xen/io/console.h>
+#include <xenctrl.h>
+
+#include "vl.h"
+
+#include "xen_console.h"
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */
+#define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2)
+
+#define dolog(val, fmt, ...) fprintf(stderr, fmt "\n", ## __VA_ARGS__)
+
+struct buffer
+{
+	uint8_t *data;
+	size_t consumed;
+	size_t size;
+	size_t capacity;
+	size_t max_capacity;
+};
+
+struct domain
+{
+	int domid;
+	struct buffer buffer;
+
+	char *conspath;
+	char *serialpath;
+	int use_consolepath;
+	int ring_ref;
+	evtchn_port_t local_port;
+	evtchn_port_t remote_port;
+	int xce_handle;
+	struct xs_handle *xsh;
+	struct xencons_interface *interface;
+	CharDriverState *chr;
+};
+
+
+static void buffer_append(struct domain *dom)
+{
+	struct buffer *buffer = &dom->buffer;
+	XENCONS_RING_IDX cons, prod, size;
+	struct xencons_interface *intf = dom->interface;
+
+	cons = intf->out_cons;
+	prod = intf->out_prod;
+	mb();
+
+	size = prod - cons;
+	if ((size == 0) || (size > sizeof(intf->out)))
+		return;
+
+	if ((buffer->capacity - buffer->size) < size) {
+		buffer->capacity += (size + 1024);
+		buffer->data = realloc(buffer->data, buffer->capacity);
+		if (buffer->data == NULL) {
+			dolog(LOG_ERR, "Memory allocation failed");
+			exit(ENOMEM);
+		}
+	}
+
+	while (cons != prod)
+		buffer->data[buffer->size++] = intf->out[
+			MASK_XENCONS_IDX(cons++, intf->out)];
+
+	mb();
+	intf->out_cons = cons;
+	xc_evtchn_notify(dom->xce_handle, dom->local_port);
+
+	if (buffer->max_capacity &&
+	    buffer->size > buffer->max_capacity) {
+		/* Discard the middle of the data. */
+
+		size_t over = buffer->size - buffer->max_capacity;
+		uint8_t *maxpos = buffer->data + buffer->max_capacity;
+
+		memmove(maxpos - over, maxpos, over);
+		buffer->data = realloc(buffer->data, buffer->max_capacity);
+		buffer->size = buffer->capacity = buffer->max_capacity;
+
+		if (buffer->consumed > buffer->max_capacity - over)
+			buffer->consumed = buffer->max_capacity - over;
+	}
+}
+
+static void buffer_advance(struct buffer *buffer, size_t len)
+{
+	buffer->consumed += len;
+	if (buffer->consumed == buffer->size) {
+		buffer->consumed = 0;
+		buffer->size = 0;
+	}
+}
+
+/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
+int xs_gather(struct xs_handle *xs, const char *dir, ...)
+{
+	va_list ap;
+	const char *name;
+	char *path;
+	int ret = 0;
+
+	va_start(ap, dir);
+	while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
+		const char *fmt = va_arg(ap, char *);
+		void *result = va_arg(ap, void *);
+		char *p;
+
+		if (asprintf(&path, "%s/%s", dir, name) == -1) {
+			ret = ENOMEM;
+			break;
+		}
+		p = xs_read(xs, XBT_NULL, path, NULL);
+		free(path);
+		if (p == NULL) {
+			ret = ENOENT;
+			break;
+		}
+		if (fmt) {
+			if (sscanf(p, fmt, result) == 0)
+				ret = EINVAL;
+			free(p);
+		} else
+			*(char **)result = p;
+	}
+	va_end(ap);
+	return ret;
+}
+
+static int domain_create_ring(struct domain *dom)
+{
+	int err, remote_port, ring_ref, rc;
+
+	err = xs_gather(dom->xsh, dom->serialpath,
+			"ring-ref", "%u", &ring_ref,
+			"port", "%i", &remote_port,
+			NULL);
+	if (err) {
+		err = xs_gather(dom->xsh, dom->conspath,
+				"ring-ref", "%u", &ring_ref,
+				"port", "%i", &remote_port,
+				NULL);
+		if (err) {
+			fprintf(stderr, "Console: failed to find ring-ref/port yet\n");
+			goto out;
+		}
+		dom->use_consolepath = 1;
+	} else
+		dom->use_consolepath = 0;
+	fprintf(stderr, "Console: got ring-ref %d port %d\n", ring_ref, remote_port);
+
+	if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
+		goto out;
+
+	if (ring_ref != dom->ring_ref) {
+		if (dom->interface != NULL)
+			munmap(dom->interface, getpagesize());
+		dom->interface = xc_map_foreign_range(
+			xc_handle, dom->domid, getpagesize(),
+			PROT_READ|PROT_WRITE,
+			(unsigned long)ring_ref);
+		if (dom->interface == NULL) {
+			err = -errno;
+			goto out;
+		}
+		dom->ring_ref = ring_ref;
+	}
+
+	dom->local_port = -1;
+	dom->remote_port = -1;
+
+	dom->xce_handle = xc_evtchn_open();
+	if (dom->xce_handle == -1) {
+		err = -errno;
+		goto out;
+	}
+
+	rc = xc_evtchn_bind_interdomain(dom->xce_handle,
+		dom->domid, remote_port);
+
+	if (rc == -1) {
+		err = -errno;
+		xc_evtchn_close(dom->xce_handle);
+		dom->xce_handle = -1;
+		goto out;
+	}
+	dom->local_port = rc;
+	dom->remote_port = remote_port;
+
+ out:
+	return err;
+}
+
+
+static struct domain *create_domain(int domid, CharDriverState *chr)
+{
+	struct domain *dom;
+	char *s;
+
+	dom = (struct domain *)malloc(sizeof(struct domain));
+	if (dom == NULL) {
+		dolog(LOG_ERR, "Out of memory %s:%s():L%d",
+		      __FILE__, __FUNCTION__, __LINE__);
+		exit(ENOMEM);
+	}
+
+	dom->domid = domid;
+	dom->chr = chr;
+
+	dom->xsh = xs_daemon_open();
+	if (dom->xsh == NULL) {
+		fprintf(logfile, "Could not contact xenstore for console watch\n");
+		goto out;
+	}
+
+	dom->serialpath = xs_get_domain_path(dom->xsh, dom->domid);
+	s = realloc(dom->serialpath, strlen(dom->serialpath) +
+		    strlen("/serial/0") + 1);
+	if (s == NULL)
+		goto out;
+	dom->serialpath = s;
+	strcat(dom->serialpath, "/serial/0");
+
+	dom->conspath = xs_get_domain_path(dom->xsh, dom->domid);
+	s = realloc(dom->conspath, strlen(dom->conspath) +
+		    strlen("/console") + 1);
+	if (s == NULL)
+		goto out;
+	dom->conspath = s;
+	strcat(dom->conspath, "/console");
+
+	dom->buffer.data = 0;
+	dom->buffer.consumed = 0;
+	dom->buffer.size = 0;
+	dom->buffer.capacity = 0;
+	dom->buffer.max_capacity = 0;
+
+	dom->ring_ref = -1;
+	dom->local_port = -1;
+	dom->remote_port = -1;
+	dom->interface = NULL;
+	dom->xce_handle = -1;
+
+
+	return dom;
+ out:
+	free(dom->serialpath);
+	free(dom->conspath);
+	free(dom);
+	return NULL;
+}
+
+
+static int ring_free_bytes(struct domain *dom)
+{
+	struct xencons_interface *intf = dom->interface;
+	XENCONS_RING_IDX cons, prod, space;
+
+	cons = intf->in_cons;
+	prod = intf->in_prod;
+	mb();
+
+	space = prod - cons;
+	if (space > sizeof(intf->in))
+		return 0; /* ring is screwed: ignore it */
+
+	return (sizeof(intf->in) - space);
+}
+
+static int xencons_can_receive(void *opaque)
+{
+	struct domain *dom = (struct domain *)opaque;
+
+	return ring_free_bytes(dom);
+}
+
+static void xencons_receive(void *opaque, const uint8_t *buf, int len)
+{
+	struct domain *dom = (struct domain *)opaque;
+	int i, max;
+	struct xencons_interface *intf = dom->interface;
+	XENCONS_RING_IDX prod;
+
+	max = ring_free_bytes(dom);
+	/* The can_receive() func limits this, but check again anyway */
+	if (max < len)
+		len = max;
+
+	prod = intf->in_prod;
+	for (i = 0; i < len; i++) {
+		intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
+			buf[i];
+	}
+	wmb();
+	intf->in_prod = prod;
+	xc_evtchn_notify(dom->xce_handle, dom->local_port);
+}
+
+static void xencons_send(struct domain *dom)
+{
+	ssize_t len;
+	len = qemu_chr_write(dom->chr, dom->buffer.data + dom->buffer.consumed,
+			     dom->buffer.size - dom->buffer.consumed);
+ 	if (len < 1) {
+		/*
+		 * Disable log because if we're redirecting to /dev/pts/N we
+		 * don't want to flood logs when no client has the PTY open
+		 */
+		/*
+		dolog(LOG_DEBUG, "Write failed on domain %d: %zd, %d\n",
+		      dom->domid, len, errno);
+		*/
+	} else {
+		buffer_advance(&dom->buffer, len);
+	}
+}
+
+static void xencons_ring_read(void *opaque)
+{
+	evtchn_port_t port;
+	struct domain *dom = (struct domain *)opaque;
+
+	if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
+		return;
+
+	buffer_append(dom);
+
+	(void)xc_evtchn_unmask(dom->xce_handle, port);
+
+	if (dom->buffer.size - dom->buffer.consumed)
+		xencons_send(dom);
+}
+
+static void xencons_startup(void *opaque)
+{
+	struct domain *dom = (struct domain *)opaque;
+	unsigned dummy;
+	char **vec;
+	int err;
+	vec = xs_read_watch(dom->xsh, &dummy);
+	if (vec)
+		free(vec);
+	fprintf(stderr, "Console: got watch\n");
+	err = domain_create_ring(dom);
+	if (err)
+		return;
+
+	xs_unwatch(dom->xsh, dom->conspath, "");
+	xs_unwatch(dom->xsh, dom->serialpath, "");
+	qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, NULL, NULL, NULL);
+
+	fprintf(stderr, "Console: connected to guest frontend\n");
+	if (qemu_set_fd_handler2(dom->xce_handle, NULL, xencons_ring_read, NULL, dom) < 0)
+		return;
+
+	qemu_chr_add_handlers(dom->chr, xencons_can_receive, xencons_receive,
+			      NULL, dom);
+}
+
+
+int xencons_init(int domid, CharDriverState *chr)
+{
+	struct domain *dom = create_domain(domid, chr);
+
+	if (!dom)
+		return -1;
+
+	/* Setup watches so we asynchronously connect to serial console */
+	xs_watch(dom->xsh, dom->conspath, "");
+	xs_watch(dom->xsh, dom->serialpath, "");
+	qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, xencons_startup, NULL, dom);
+	fprintf(stderr, "Console: prepared domain, waiting for ringref at %s or %s\n",
+		dom->conspath, dom->serialpath);
+
+	return 0;
+}
+
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r e6b8a2d93de9 tools/ioemu/hw/xen_console.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xen_console.h	Fri Oct 19 19:32:55 2007 -0400
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (C) International Business Machines  Corp., 2005
+ *  Author(s): Anthony Liguori <aliguori at us.ibm.com>
+ *
+ *  Copyright (C) Red Hat 2007
+ *
+ *  Xen Console
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "vl.h"
+
+extern int xencons_init(int domid, CharDriverState *chr);
diff -r e6b8a2d93de9 tools/ioemu/hw/xen_machine_pv.c
--- a/tools/ioemu/hw/xen_machine_pv.c	Fri Oct 19 17:52:43 2007 -0400
+++ b/tools/ioemu/hw/xen_machine_pv.c	Fri Oct 19 19:32:55 2007 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "vl.h"
+#include "xen_console.h"
 #include "xenfb.h"
 
 
@@ -39,6 +40,14 @@ static void xen_init_pv(uint64_t ram_siz
 {
     struct xenfb *xenfb;
     extern int domid;
+
+    /* Connect to text console */
+    if (serial_hds[0]) {
+        if (xencons_init(domid, serial_hds[0]) < 0) {
+            fprintf(stderr, "Could not connect to domain console\n");
+            exit(1);
+        }
+    }
 
     /* Prepare PVFB state */
     xenfb = xenfb_new(domid, ds);
diff -r e6b8a2d93de9 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c	Fri Oct 19 17:52:43 2007 -0400
+++ b/tools/ioemu/xenstore.c	Fri Oct 19 19:32:55 2007 -0400
@@ -17,7 +17,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
-static struct xs_handle *xsh = NULL;
+struct xs_handle *xsh = NULL;
 static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS];
 static QEMUTimer *insert_timer = NULL;
 

xen-pvfb-09-xend-device-model.patch:

--- NEW FILE xen-pvfb-09-xend-device-model.patch ---
diff -r a3ce4d76dd36 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py	Fri Oct 19 17:44:06 2007 -0400
+++ b/tools/python/xen/xend/XendCheckpoint.py	Fri Oct 19 17:44:08 2007 -0400
@@ -6,6 +6,7 @@
 # this archive for more details.
 
 import os
+import os.path
 import re
 import string
 import threading
@@ -108,7 +109,7 @@ def save(fd, dominfo, network, live, dst
         forkHelper(cmd, fd, saveInputHandler, False)
 
         # put qemu device model state
-        if hvm:
+        if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()):
             write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature")
             qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(),
                               os.O_RDONLY)
@@ -245,6 +246,8 @@ def restore(xd, fd, dominfo = None, paus
             raise XendError('Could not read console MFN')        
 
         # get qemu state and create a tmp file for dm restore
+        # Even PV guests may have QEMU stat, but its not currently
+        # used so only bother with HVM currently.
         if is_hvm:
             qemu_signature = read_exact(fd, len(QEMU_SIGNATURE),
                                         "invalid device model signature read")
diff -r a3ce4d76dd36 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py	Fri Oct 19 17:44:06 2007 -0400
+++ b/tools/python/xen/xend/XendConfig.py	Fri Oct 19 17:44:08 2007 -0400
@@ -32,6 +32,7 @@ from xen.xend.server.netif import random
 from xen.xend.server.netif import randomMAC
 from xen.util.blkif import blkdev_name_to_number
 from xen.util import xsconstants
+import xen.util.auxbin
 
 log = logging.getLogger("xend.XendConfig")
 log.setLevel(logging.WARN)
@@ -233,8 +234,6 @@ LEGACY_XENSTORE_VM_PARAMS = [
     'on_xend_start',
     'on_xend_stop',
 ]
-
-DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm'
 
 ##
 ## Config Choices
@@ -393,13 +392,14 @@ class XendConfig(dict):
             self['name_label'] = 'Domain-' + self['uuid']
 
     def _platform_sanity_check(self):
+        if 'keymap' not in self['platform'] and XendOptions.instance().get_keymap():
+            self['platform']['keymap'] = XendOptions.instance().get_keymap()
+
+        if self.is_hvm() or self.has_rfb():
+            if 'device_model' not in self['platform']:
+                self['platform']['device_model'] = xen.util.auxbin.pathTo("qemu-dm")
+
         if self.is_hvm():
-            if 'keymap' not in self['platform'] and XendOptions.instance().get_keymap():
-                self['platform']['keymap'] = XendOptions.instance().get_keymap()
-
-            if 'device_model' not in self['platform']:
-                self['platform']['device_model'] = DEFAULT_DM
-
             # Compatibility hack, can go away soon.
             if 'soundhw' not in self['platform'] and \
                self['platform'].get('enable_audio'):
@@ -744,16 +744,7 @@ class XendConfig(dict):
         # coalesce hvm vnc frame buffer with vfb config
         if self.is_hvm() and int(self['platform'].get('vnc', 0)) != 0:
             # add vfb device if it isn't there already
-            has_rfb = False
-            for console_uuid in self['console_refs']:
-                if self['devices'][console_uuid][1].get('protocol') == 'rfb':
-                    has_rfb = True
-                    break
-                if self['devices'][console_uuid][0] == 'vfb':
-                    has_rfb = True
-                    break
-
-            if not has_rfb:
+            if not self.has_rfb():
                 dev_config = ['vfb']
                 dev_config.append(['type', 'vnc'])
                 # copy VNC related params from platform config to vfb dev conf
@@ -764,6 +755,14 @@ class XendConfig(dict):
 
                 self.device_add('vfb', cfg_sxp = dev_config)
 
+
+    def has_rfb(self):
+        for console_uuid in self['console_refs']:
+            if self['devices'][console_uuid][1].get('protocol') == 'rfb':
+                return True
+            if self['devices'][console_uuid][0] == 'vfb':
+                return True
+        return False
 
     def _sxp_to_xapi_unsupported(self, sxp_cfg):
         """Read in an SXP configuration object and populate
diff -r a3ce4d76dd36 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Fri Oct 19 17:44:06 2007 -0400
+++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Oct 19 17:44:08 2007 -0400
@@ -1455,10 +1455,16 @@ class XendDomainInfo:
 
     def _releaseDevices(self, suspend = False):
         """Release all domain's devices.  Nothrow guarantee."""
-        if suspend and self.image:
-            self.image.destroy(suspend)
-            return
-
+        if self.image:
+            try:
+                log.debug("Destroying device model")
+                self.image.destroyDeviceModel()
+            except Exception, e:
+                log.exception("Device model destroy failed %s" % str(e))
+        else:
+            log.debug("No device model")
+
+        log.debug("Releasing devices")
         t = xstransact("%s/device" % self.dompath)
         for devclass in XendDevices.valid_devices():
             for dev in t.list(devclass):
@@ -1468,8 +1474,8 @@ class XendDomainInfo:
                 except:
                     # Log and swallow any exceptions in removal --
                     # there's nothing more we can do.
-                        log.exception("Device release failed: %s; %s; %s",
-                                      self.info['name_label'], devclass, dev)
+                    log.exception("Device release failed: %s; %s; %s",
+                                  self.info['name_label'], devclass, dev)
 
             
 
@@ -1695,11 +1701,6 @@ class XendDomainInfo:
             bootloader_tidy(self)
 
             if self.image:
-                try:
-                    self.image.destroy()
-                except:
-                    log.exception(
-                        "XendDomainInfo.cleanup: image.destroy() failed.")
                 self.image = None
 
             try:
@@ -1747,10 +1748,9 @@ class XendDomainInfo:
         self.console_mfn = console_mfn
 
         self._introduceDomain()
-        if self.info.is_hvm():
-            self.image = image.create(self, self.info)
-            if self.image:
-                self.image.createDeviceModel(True)
+        self.image = image.create(self, self.info)
+        if self.image:
+            self.image.createDeviceModel(True)
         self._storeDomDetails()
         self._registerWatches()
         self.refreshShutdown()
@@ -1868,8 +1868,8 @@ class XendDomainInfo:
             ResumeDomain(self.domid)
         except:
             log.exception("XendDomainInfo.resume: xc.domain_resume failed on domain %s." % (str(self.domid)))
-        if self.is_hvm():
-            self.image.resumeDeviceModel()
+        self.image.resumeDeviceModel()
+        log.debug("XendDomainInfo.resumeDomain: completed")
 
 
     #
diff -r a3ce4d76dd36 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py	Fri Oct 19 17:44:06 2007 -0400
+++ b/tools/python/xen/xend/image.py	Fri Oct 19 17:46:43 2007 -0400
@@ -56,10 +56,9 @@ class ImageHandler:
     defining in a subclass.
 
     The method createDeviceModel() is called to create the domain device
-    model if it needs one.  The default is to do nothing.
-
-    The method destroy() is called when the domain is destroyed.
-    The default is to do nothing.
+    model.
+
+    The method destroyDeviceModel() is called to reap the device model
     """
 
     ostype = None
@@ -91,6 +90,15 @@ class ImageHandler:
                         ("image/cmdline", self.cmdline),
                         ("image/ramdisk", self.ramdisk))
 
+        self.dmargs = self.parseDeviceModelArgs(vmConfig)
+        self.device_model = vmConfig['platform'].get('device_model')
+
+        self.display = vmConfig['platform'].get('display')
+        self.xauthority = vmConfig['platform'].get('xauthority')
+        self.vncconsole = vmConfig['platform'].get('vncconsole')
+        self.pid = None
+
+
 
     def cleanupBootloading(self):
         if self.bootloader:
@@ -173,25 +181,145 @@ class ImageHandler:
         """Build the domain. Define in subclass."""
         raise NotImplementedError()
 
+    # Return a list of cmd line args to the device models based on the
+    # xm config file
+    def parseDeviceModelArgs(self, vmConfig):
+        ret = ["-domain-name", str(self.vm.info['name_label'])]
+
+        # Find RFB console device, and if it exists, make QEMU enable
+        # the VNC console.
+        if int(vmConfig['platform'].get('nographic', 0)) != 0:
+            # skip vnc init if nographic is set
+            ret.append('-nographic')
+            return ret
+
+        vnc_config = {}
+        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
+        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
+        for dev_uuid in vmConfig['console_refs']:
+            dev_type, dev_info = vmConfig['devices'][dev_uuid]
+            if dev_type == 'vfb':
+                vnc_config = dev_info.get('other_config', {})
+                has_vnc = True
+                break
+
+        keymap = vmConfig['platform'].get("keymap")
+        if keymap:
+            ret.append("-k")
+            ret.append(keymap)
+
+        if has_vnc:
+            if not vnc_config:
+                for key in ('vncunused', 'vnclisten', 'vncdisplay',
+                            'vncpasswd'):
+                    if key in vmConfig['platform']:
+                        vnc_config[key] = vmConfig['platform'][key]
+
+            vnclisten = vnc_config.get('vnclisten',
+                                       xenopts().get_vnclisten_address())
+            vncdisplay = vnc_config.get('vncdisplay', 0)
+            ret.append('-vnc')
+            ret.append("%s:%d" % (vnclisten, vncdisplay))
+            
+            if vnc_config.get('vncunused', 0):
+                ret.append('-vncunused')
+
+            # Store vncpassword in xenstore
+            vncpasswd = vnc_config.get('vncpasswd')
+            if not vncpasswd:
+                vncpasswd = xenopts().get_vncpasswd_default()
+
+            if vncpasswd is None:
+                raise VmError('vncpasswd is not setup in vmconfig or '
+                              'xend-config.sxp')
+
+            if vncpasswd != '':
+                self.vm.storeVm('vncpasswd', vncpasswd)
+        elif has_sdl:
+            # SDL is default in QEMU.
+            pass
+        else:
+            ret.append('-nographic')
+
+        if int(vmConfig['platform'].get('monitor', 0)) != 0:
+            ret = ret + ['-monitor', 'vc']
+        return ret
+
+    def getDeviceModelArgs(self, restore = False):
+        args = [self.device_model]
+        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])
+        args = args + self.dmargs
+        return args
+
     def createDeviceModel(self, restore = False):
-        """Create device model for the domain (define in subclass if needed)."""
-        pass
-    
+        if self.device_model is None:
+            return
+        if self.pid:
+            return
+        # Execute device model.
+        #todo: Error handling
+        args = self.getDeviceModelArgs(restore)
+        env = dict(os.environ)
+        if self.display:
+            env['DISPLAY'] = self.display
+        if self.xauthority:
+            env['XAUTHORITY'] = self.xauthority
+        if self.vncconsole:
+            args = args + ([ "-vncviewer" ])
+        log.info("spawning device models: %s %s", self.device_model, args)
+        # keep track of pid and spawned options to kill it later
+        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
+        self.vm.storeDom("image/device-model-pid", self.pid)
+        log.info("device model pid: %d", self.pid)
+
     def saveDeviceModel(self):
-        """Save device model for the domain (define in subclass if needed)."""
-        pass
+        if self.device_model is None:
+            return
+        # Signal the device model to pause itself and save its state
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('command', 'save'))
+        # Wait for confirmation.  Could do this with a watch but we'd
+        # still end up spinning here waiting for the watch to fire. 
+        state = ''
+        count = 0
+        while state != 'paused':
+            state = xstransact.Read("/local/domain/0/device-model/%i/state"
+                                    % self.vm.getDomid())
+            time.sleep(0.1)
+            count += 1
+            if count > 100:
+                raise VmError('Timed out waiting for device model to save')
 
     def resumeDeviceModel(self):
-        """Unpause device model for the domain (define in subclass if needed)."""
-        pass
-
-    def destroy(self):
-        """Extra cleanup on domain destroy (define in subclass if needed)."""
-        pass
-
+        if self.device_model is None:
+            return
+        # Signal the device model to resume activity after pausing to save.
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('command', 'continue'))
 
     def recreate(self):
-        pass
+        if self.device_model is None:
+            return
+        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
+
+    def destroyDeviceModel(self):
+        if self.device_model is None:
+            return
+        if self.pid:
+            try:
+                os.kill(self.pid, signal.SIGKILL)
+            except OSError, exn:
+                log.exception(exn)
+            try:
+                os.waitpid(self.pid, 0)
+            except OSError, exn:
+                # This is expected if Xend has been restarted within the
+                # life of this domain.  In this case, we can kill the process,
+                # but we can't wait for it because it's not our child.
+                pass
+            self.pid = None
+            state = xstransact.Remove("/local/domain/0/device-model/%i"
+                                      % self.vm.getDomid())
 
 
 class LinuxImageHandler(ImageHandler):
@@ -223,6 +351,19 @@ class LinuxImageHandler(ImageHandler):
                               ramdisk        = self.ramdisk,
                               features       = self.vm.getFeatures())
 
+    def parseDeviceModelArgs(self, vmConfig):
+        ret = ImageHandler.parseDeviceModelArgs(self, vmConfig)
+        # Equivalent to old xenconsoled behaviour. Should make
+        # it configurable in future
+        ret = ret + ["-serial", "pty"]
+        return ret
+
+    def getDeviceModelArgs(self, restore = False):
+        args = ImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-M", "xenpv"])
+        return args
+
+
 class PPC_LinuxImageHandler(LinuxImageHandler):
 
     ostype = "linux"
@@ -256,15 +397,6 @@ class HVMImageHandler(ImageHandler):
         if 'hvm' not in info['xen_caps']:
             raise HVMRequired()
 
-        self.dmargs = self.parseDeviceModelArgs(vmConfig)
-        self.device_model = vmConfig['platform'].get('device_model')
-        if not self.device_model:
-            raise VmError("hvm: missing device model")
-        
-        self.display = vmConfig['platform'].get('display')
-        self.xauthority = vmConfig['platform'].get('xauthority')
-        self.vncconsole = vmConfig['platform'].get('vncconsole')
-
         rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
 
         self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
@@ -272,49 +404,18 @@ class HVMImageHandler(ImageHandler):
                         ("image/display", self.display))
         self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset))
 
-        self.pid = None
-
         self.apic = int(vmConfig['platform'].get('apic', 0))
         self.acpi = int(vmConfig['platform'].get('acpi', 0))
-        
-
-    def buildDomain(self):
-        store_evtchn = self.vm.getStorePort()
-
-        mem_mb = self.getRequiredInitialReservation() / 1024
-
-        log.debug("domid          = %d", self.vm.getDomid())
-        log.debug("image          = %s", self.kernel)
-        log.debug("store_evtchn   = %d", store_evtchn)
-        log.debug("memsize        = %d", mem_mb)
-        log.debug("vcpus          = %d", self.vm.getVCpuCount())
-        log.debug("acpi           = %d", self.acpi)
-        log.debug("apic           = %d", self.apic)
-
-        rc = xc.hvm_build(domid          = self.vm.getDomid(),
-                          image          = self.kernel,
-                          memsize        = mem_mb,
-                          vcpus          = self.vm.getVCpuCount(),
-                          acpi           = self.acpi,
-                          apic           = self.apic)
-
-        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
-
-        rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
-                                           HVM_PARAM_STORE_PFN)
-        xc.hvm_set_param(self.vm.getDomid(), HVM_PARAM_STORE_EVTCHN,
-                         store_evtchn)
-
-        return rc
 
     # Return a list of cmd line args to the device models based on the
     # xm config file
     def parseDeviceModelArgs(self, vmConfig):
+        ret = ImageHandler.parseDeviceModelArgs(self, vmConfig)
+        ret = ret + ['-vcpus', str(self.vm.getVCpuCount())]
+
         dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
                    'localtime', 'serial', 'stdvga', 'isa',
-                   'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ]
-        
-        ret = ['-vcpus', str(self.vm.getVCpuCount())]
+                   'acpi', 'usb', 'usbdevice', 'pci' ]
 
         for a in dmargs:
             v = vmConfig['platform'].get(a)
@@ -343,7 +444,6 @@ class HVMImageHandler(ImageHandler):
 
         # Handle disk/network related options
         mac = None
-        ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
         nics = 0
         
         for devuuid in vmConfig['vbd_refs']:
@@ -372,130 +472,41 @@ class HVMImageHandler(ImageHandler):
             ret.append("-net")
             ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
 
-
-        #
-        # Find RFB console device, and if it exists, make QEMU enable
-        # the VNC console.
-        #
-        if int(vmConfig['platform'].get('nographic', 0)) != 0:
-            # skip vnc init if nographic is set
-            ret.append('-nographic')
-            return ret
-
-        vnc_config = {}
-        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
-        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
-        for dev_uuid in vmConfig['console_refs']:
-            dev_type, dev_info = vmConfig['devices'][dev_uuid]
-            if dev_type == 'vfb':
-                vnc_config = dev_info.get('other_config', {})
-                has_vnc = True
-                break
-
-        if has_vnc:
-            if not vnc_config:
-                for key in ('vncunused', 'vnclisten', 'vncdisplay',
-                            'vncpasswd'):
-                    if key in vmConfig['platform']:
-                        vnc_config[key] = vmConfig['platform'][key]
-
-            vnclisten = vnc_config.get('vnclisten',
-                                       xenopts().get_vnclisten_address())
-            vncdisplay = vnc_config.get('vncdisplay', 0)
-            ret.append('-vnc')
-            ret.append("%s:%d" % (vnclisten, vncdisplay))
-            
-            if vnc_config.get('vncunused', 0):
-                ret.append('-vncunused')
-
-            # Store vncpassword in xenstore
-            vncpasswd = vnc_config.get('vncpasswd')
-            if not vncpasswd:
-                vncpasswd = xenopts().get_vncpasswd_default()
-
-            if vncpasswd is None:
-                raise VmError('vncpasswd is not setup in vmconfig or '
-                              'xend-config.sxp')
-
-            if vncpasswd != '':
-                self.vm.storeVm('vncpasswd', vncpasswd)
-        elif has_sdl:
-            # SDL is default in QEMU.
-            pass
-        else:
-            ret.append('-nographic')
-
-        if int(vmConfig['platform'].get('monitor', 0)) != 0:
-            ret = ret + ['-monitor', 'vc']
         return ret
 
-    def createDeviceModel(self, restore = False):
-        if self.pid:
-            return
-        # Execute device model.
-        #todo: Error handling
-        args = [self.device_model]
-        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])
-        if arch.type == "ia64":
-            args = args + ([ "-m", "%s" %
-                             (self.getRequiredInitialReservation() / 1024) ])
-        args = args + self.dmargs
+    def getDeviceModelArgs(self, restore = False):
+        args = ImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-M", "xenfv"])
         if restore:
             args = args + ([ "-loadvm", "/var/lib/xen/qemu-save.%d" %
                              self.vm.getDomid() ])
-        env = dict(os.environ)
-        if self.display:
-            env['DISPLAY'] = self.display
-        if self.xauthority:
-            env['XAUTHORITY'] = self.xauthority
-        if self.vncconsole:
-            args = args + ([ "-vncviewer" ])
-        log.info("spawning device models: %s %s", self.device_model, args)
-        # keep track of pid and spawned options to kill it later
-        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
-        self.vm.storeDom("image/device-model-pid", self.pid)
-        log.info("device model pid: %d", self.pid)
-
-    def saveDeviceModel(self):
-        # Signal the device model to pause itself and save its state
-        xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'save'))
-        # Wait for confirmation.  Could do this with a watch but we'd
-        # still end up spinning here waiting for the watch to fire. 
-        state = ''
-        count = 0
-        while state != 'paused':
-            state = xstransact.Read("/local/domain/0/device-model/%i/state"
-                                    % self.vm.getDomid())
-            time.sleep(0.1)
-            count += 1
-            if count > 100:
-                raise VmError('Timed out waiting for device model to save')
-
-    def resumeDeviceModel(self):
-        # Signal the device model to resume activity after pausing to save.
-        xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'continue'))
-
-    def recreate(self):
-        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
-
-    def destroy(self, suspend = False):
-        if self.pid and not suspend:
-            try:
-                os.kill(self.pid, signal.SIGKILL)
-            except OSError, exn:
-                log.exception(exn)
-            try:
-                os.waitpid(self.pid, 0)
-            except OSError, exn:
-                # This is expected if Xend has been restarted within the
-                # life of this domain.  In this case, we can kill the process,
-                # but we can't wait for it because it's not our child.
-                pass
-            self.pid = None
-            state = xstransact.Remove("/local/domain/0/device-model/%i"
-                                      % self.vm.getDomid())
+        return args
+
+    def buildDomain(self):
+        store_evtchn = self.vm.getStorePort()
+
+        mem_mb = self.getRequiredInitialReservation() / 1024
+
+        log.debug("domid          = %d", self.vm.getDomid())
+        log.debug("image          = %s", self.kernel)
+        log.debug("store_evtchn   = %d", store_evtchn)
+        log.debug("memsize        = %d", mem_mb)
+        log.debug("vcpus          = %d", self.vm.getVCpuCount())
+        log.debug("acpi           = %d", self.acpi)
+        log.debug("apic           = %d", self.apic)
+
+        rc = xc.hvm_build(domid          = self.vm.getDomid(),
+                          image          = self.kernel,
+                          memsize        = mem_mb,
+                          vcpus          = self.vm.getVCpuCount(),
+                          acpi           = self.acpi,
+                          apic           = self.apic)
+        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
+        rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
+                                           HVM_PARAM_STORE_PFN)
+        xc.hvm_set_param(self.vm.getDomid(), HVM_PARAM_STORE_EVTCHN,
+                         store_evtchn)
+        return rc
 
 
 class IA64_HVM_ImageHandler(HVMImageHandler):
@@ -517,6 +528,13 @@ class IA64_HVM_ImageHandler(HVMImageHand
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         # Explicit shadow memory is not a concept 
         return 0
+
+    def getDeviceModelArgs(self, restore = False):
+        args = HVMImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-m", "%s" %
+                         (self.getRequiredInitialReservation() / 1024) ])
+        return args
+
 
 class X86_HVM_ImageHandler(HVMImageHandler):
 
diff -r a3ce4d76dd36 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py	Fri Oct 19 17:44:06 2007 -0400
+++ b/tools/python/xen/xend/server/vfbif.py	Fri Oct 19 17:44:08 2007 -0400
@@ -5,14 +5,6 @@ import xen.xend
 import xen.xend
 import os
 
-def spawn_detached(path, args, env):
-    p = os.fork()
-    if p == 0:
-        os.spawnve(os.P_NOWAIT, path, args, env)
-        os._exit(0)
-    else:
-        os.waitpid(p, 0)
-        
 CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
                   'display', 'xauthority', 'keymap',
                   'uuid', 'location', 'protocol']
@@ -43,65 +35,9 @@ class VfbifController(DevController):
                      for i in range(len(CONFIG_ENTRIES))
                      if devinfo[i] is not None])
 
-
-    def createDevice(self, config):
-        DevController.createDevice(self, config)
-        if self.vm.info.is_hvm():
-            # is HVM, so qemu-dm will handle the vfb.
-            return
-        
-        args = [ xen.util.auxbin.pathTo("qemu-dm"),
-                 "-M", "xenpv",
-                 "-d", "%d" % self.vm.getDomid(),
-                 "-domain-name", self.vm.getName() ]
-        t = config.get("type", None)
-        if t == "vnc":
-            passwd = None
-            if config.has_key("vncpasswd"):
-                passwd = config["vncpasswd"]
-            else:
-                passwd = xen.xend.XendOptions.instance().get_vncpasswd_default()
-            if passwd:
-                self.vm.storeVm("vncpasswd", passwd)
-                log.debug("Stored a VNC password for vfb access")
-            else:
-                log.debug("No VNC passwd configured for vfb access")
-
-            vnclisten = config.get('vnclisten',
-                                   xen.xend.XendOptions.instance().get_vnclisten_address())
-            vncdisplay = config.get('vncdisplay', 0)
-            args += ['-vnc', "%s:%d" % (vnclisten, vncdisplay)]
-
-            if config.get('vncunused', 0):
-                args += ['-vncunused']
-
-            if config.has_key("keymap"):
-                args += ["-k", "%s" % config["keymap"]]
-            else:
-                xoptions = xen.xend.XendOptions.instance()
-                if xoptions.get_keymap():
-                    args += ["-k", "%s" % xoptions.get_keymap()]
-
-            spawn_detached(args[0], args, os.environ)
-        elif t == "sdl":
-            env = dict(os.environ)
-            if config.has_key("display"):
-                env['DISPLAY'] = config["display"]
-            if config.has_key("xauthority"):
-                env['XAUTHORITY'] = config["xauthority"]
-            spawn_detached(args[0], args, env)
-        else:
-            raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
-
-
     def waitForDevice(self, devid):
-        if self.vm.info.get('HVM_boot_policy'):
-            log.debug('skip waiting for HVM vfb')
-            # is a qemu-dm managed device, don't wait for hotplug for these.
-            return
-
-        DevController.waitForDevice(self, devid)
-
+        # is a qemu-dm managed device, don't wait for hotplug for these.
+        return
 
     def reconfigureDevice(self, _, config):
         """ Only allow appending location information of vnc port into
@@ -115,20 +51,15 @@ class VfbifController(DevController):
         raise VmError('Refusing to reconfigure device vfb:%d' % devid)
 
     def destroyDevice(self, devid, force):
-        if self.vm.info.get('HVM_boot_policy'):
-            # remove the backend xenstore entries for HVM guests no matter
-            # what
-            DevController.destroyDevice(self, devid, True)
-        else:
-            DevController.destroyDevice(self, devid, force)
-
+        # remove the backend xenstore entries no matter what
+        # because we kill qemu-dm with extreme prejudice
+        # not giving it a chance to remove them itself
+        DevController.destroyDevice(self, devid, True)
 
     def migrate(self, deviceConfig, network, dst, step, domName):
-        if self.vm.info.get('HVM_boot_policy'):        
-            return 0
-        return DevController.migrate(self, deviceConfig, network, dst, step,
-                                     domName)
-    
+        # Handled by qemu-dm so no action needed
+        return 0
+
 class VkbdifController(DevController):
     """Virtual keyboard controller. Handles all vkbd devices for a domain.
     """
@@ -141,22 +72,15 @@ class VkbdifController(DevController):
         return (devid, back, front)
 
     def waitForDevice(self, config):
-        if self.vm.info.get('HVM_boot_policy'):
-            # is a qemu-dm managed device, don't wait for hotplug for these.
-            return
-
-        DevController.waitForDevice(self, config)
+        # is a qemu-dm managed device, don't wait for hotplug for these.
+        return
 
     def destroyDevice(self, devid, force):
-        if self.vm.info.get('HVM_boot_policy'):
-            # remove the backend xenstore entries for HVM guests no matter
-            # what
-            DevController.destroyDevice(self, devid, True)
-        else:
-            DevController.destroyDevice(self, devid, force)
+        # remove the backend xenstore entries no matter what
+        # because we kill qemu-dm with extreme prejudice
+        # not giving it a chance to remove them itself
+        DevController.destroyDevice(self, devid, True)
 
     def migrate(self, deviceConfig, network, dst, step, domName):
-        if self.vm.info.get('HVM_boot_policy'):        
-            return 0
-        return DevController.migrate(self, deviceConfig, network, dst, step,
-                                     domName)        
+        # Handled by qemu-dm so no action needed
+        return 0

xen-pvfb-10-xen-console-ignore.patch:

--- NEW FILE xen-pvfb-10-xen-console-ignore.patch ---
diff -r 4559faae3790 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c	Wed Aug 22 16:24:48 2007 -0400
+++ b/tools/console/daemon/io.c	Wed Aug 22 18:48:05 2007 -0400
@@ -327,6 +327,7 @@ static int domain_create_ring(struct dom
 static int domain_create_ring(struct domain *dom)
 {
 	int err, remote_port, ring_ref, rc;
+	char *type, path[PATH_MAX];
 
 	err = xs_gather(xs, dom->serialpath,
 			"ring-ref", "%u", &ring_ref,
@@ -343,6 +344,14 @@ static int domain_create_ring(struct dom
 	} else
 		dom->use_consolepath = 0;
 
+	sprintf(path, "%s/type", dom->use_consolepath ? dom->conspath: dom->serialpath);
+	type = xs_read(xs, XBT_NULL, path, NULL);
+	if (type && strcmp(type, "xenconsoled") != 0) {
+		free(type);
+		return 0;
+	}
+	free(type);
+
 	if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
 		goto out;
 
diff -r 4559faae3790 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Wed Aug 22 16:24:48 2007 -0400
+++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Aug 22 18:36:15 2007 -0400
@@ -883,8 +883,15 @@ class XendDomainInfo:
                 else:
                     to_store[n] = str(v)
 
+        # Figure out if we need to tell xenconsoled to ignore this guest's
+        # console - device model will handle console if it is running
+        constype = "ioemu"
+        if 'device_model' not in self.info['platform']:
+            constype = "xenconsoled"
+
         f('console/port',     self.console_port)
         f('console/ring-ref', self.console_mfn)
+        f('console/type',     constype)
         f('store/port',       self.store_port)
         f('store/ring-ref',   self.store_mfn)
 


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/.cvsignore,v
retrieving revision 1.34
retrieving revision 1.34.2.1
diff -u -r1.34 -r1.34.2.1
--- .cvsignore	24 Sep 2007 20:03:10 -0000	1.34
+++ .cvsignore	19 Oct 2007 23:35:08 -0000	1.34.2.1
@@ -1,3 +1,4 @@
 xen-3.1.0-src.tgz
 *.rpm
 .build*.log
+xen-unstable.hg-16125.tar.gz


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/sources,v
retrieving revision 1.48
retrieving revision 1.48.2.1
diff -u -r1.48 -r1.48.2.1
--- sources	28 Aug 2007 21:49:31 -0000	1.48
+++ sources	19 Oct 2007 23:35:08 -0000	1.48.2.1
@@ -1 +1,2 @@
 b7ae1f652b071862ae4c90b72d549627  xen-3.1.0-src.tgz
+af3195e979c055b878bef986f7d60bde  xen-unstable.hg-16125.tar.gz

xen-pvfb-01-qemu-fv-machine.patch:

Index: xen-pvfb-01-qemu-fv-machine.patch
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/xen-pvfb-01-qemu-fv-machine.patch,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
--- xen-pvfb-01-qemu-fv-machine.patch	28 Aug 2007 21:50:58 -0000	1.1
+++ xen-pvfb-01-qemu-fv-machine.patch	19 Oct 2007 23:35:08 -0000	1.1.2.1
@@ -1,6 +1,17 @@
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/hw/xen_machine_fv.c xen-3.1.0-src.new/tools/ioemu/hw/xen_machine_fv.c
---- xen-3.1.0-src.orig/tools/ioemu/hw/xen_machine_fv.c	1969-12-31 19:00:00.000000000 -0500
-+++ xen-3.1.0-src.new/tools/ioemu/hw/xen_machine_fv.c	2007-08-23 10:42:55.000000000 -0400
+diff -r b4278beaf354 tools/ioemu/Makefile.target
+--- a/tools/ioemu/Makefile.target	Wed Oct 17 13:12:03 2007 +0100
++++ b/tools/ioemu/Makefile.target	Fri Oct 19 17:32:05 2007 -0400
+@@ -409,6 +409,7 @@ VL_OBJS+= piix4acpi.o
+ VL_OBJS+= piix4acpi.o
+ VL_OBJS+= xenstore.o
+ VL_OBJS+= xen_platform.o
++VL_OBJS+= xen_machine_fv.o
+ VL_OBJS+= tpm_tis.o
+ CPPFLAGS += -DHAS_AUDIO
+ endif
+diff -r b4278beaf354 tools/ioemu/hw/xen_machine_fv.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/tools/ioemu/hw/xen_machine_fv.c	Fri Oct 19 17:38:27 2007 -0400
 @@ -0,0 +1,286 @@
 +/*
 + * QEMU Xen FV Machine
@@ -71,7 +82,6 @@
 +    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
 +                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
 +                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
-+    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
 +
 +    /*
 +     * Use mmap() directly: lets us allocate a big hash table with no up-front
@@ -80,8 +90,9 @@
 +     */
 +    size = nr_buckets * sizeof(struct map_cache);
 +    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
++    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", nr_buckets, size);
 +    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
-+                          MAP_SHARED|MAP_ANONYMOUS, 0, 0);
++                          MAP_SHARED|MAP_ANON, -1, 0);
 +    if (mapcache_entry == MAP_FAILED) {
 +        errno = ENOMEM;
 +        return -1;
@@ -123,7 +134,7 @@
 +        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
 +            (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
 +        while (j > 0)
-+            word = (word << 1) | !(pfns[i + --j] & 0xF0000000UL);
++            word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
 +        entry->valid_mapping[i / BITS_PER_LONG] = word;
 +    }
 +}
@@ -182,14 +193,13 @@
 +
 +#endif /* defined(MAPCACHE) */
 +
-+
 +static void xen_init_fv(uint64_t ram_size, int vga_ram_size, char *boot_device,
-+			DisplayState *ds, const char **fd_filename,
-+			int snapshot,
-+			const char *kernel_filename,
-+			const char *kernel_cmdline,
-+			const char *initrd_filename, time_t timeoffset)
-+{
++                        DisplayState *ds, const char **fd_filename,
++                        int snapshot,
++                        const char *kernel_filename,
++                        const char *kernel_cmdline,
++                        const char *initrd_filename,
++                        const char *direct_pci){
 +    unsigned long ioreq_pfn;
 +    extern void *shared_page;
 +    extern void *buffered_io_page;
@@ -271,7 +281,8 @@
 +
 +
 +    pc_machine.init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
-+                    snapshot, kernel_filename, kernel_cmdline, initrd_filename, timeoffset);
++                    snapshot, kernel_filename, kernel_cmdline, initrd_filename,
++                    direct_pci);
 +}
 +
 +QEMUMachine xenfv_machine = {
@@ -288,29 +299,18 @@
 + *  tab-width: 4
 + * End:
 + */
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/Makefile.target xen-3.1.0-src.new/tools/ioemu/Makefile.target
---- xen-3.1.0-src.orig/tools/ioemu/Makefile.target	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/Makefile.target	2007-08-23 10:42:55.000000000 -0400
-@@ -369,6 +369,7 @@ VL_OBJS+= usb-uhci.o
- VL_OBJS+= piix4acpi.o
- VL_OBJS+= xenstore.o
- VL_OBJS+= xen_platform.o
-+VL_OBJS+= xen_machine_fv.o
- VL_OBJS+= tpm_tis.o
- DEFINES += -DHAS_AUDIO
- endif
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/vl.c xen-3.1.0-src.new/tools/ioemu/vl.c
---- xen-3.1.0-src.orig/tools/ioemu/vl.c	2007-08-23 10:41:10.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/vl.c	2007-08-23 10:45:27.000000000 -0400
-@@ -88,7 +88,6 @@
+diff -r b4278beaf354 tools/ioemu/vl.c
+--- a/tools/ioemu/vl.c	Wed Oct 17 13:12:03 2007 +0100
++++ b/tools/ioemu/vl.c	Fri Oct 19 17:33:52 2007 -0400
+@@ -96,7 +96,6 @@
  
  #include "exec-all.h"
  
 -#include <xen/hvm/params.h>
  #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
- #define DEFAULT_BRIDGE "xenbr0"
- 
-@@ -5694,8 +5693,12 @@ static void read_passwords(void)
+ #ifdef _BSD
+ #define DEFAULT_BRIDGE "bridge0"
+@@ -6696,8 +6695,12 @@ void register_machines(void)
  void register_machines(void)
  {
  #if defined(TARGET_I386)
@@ -323,8 +323,8 @@
  #elif defined(TARGET_PPC)
      qemu_register_machine(&heathrow_machine);
      qemu_register_machine(&core99_machine);
-@@ -5910,156 +5913,6 @@ void suspend(int sig)
-     suspend_requested = 1;
+@@ -6905,156 +6908,6 @@ int set_mm_mapping(int xc_handle, uint32
+     return 0;
  }
  
 -#if defined(MAPCACHE)
@@ -367,7 +367,6 @@
 -    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
 -                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
 -                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
--    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
 -
 -    /*
 -     * Use mmap() directly: lets us allocate a big hash table with no up-front
@@ -376,8 +375,9 @@
 -     */
 -    size = nr_buckets * sizeof(struct map_cache);
 -    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+-    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", nr_buckets, size);
 -    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
--                          MAP_SHARED|MAP_ANONYMOUS, 0, 0);
+-                          MAP_SHARED|MAP_ANON, -1, 0);
 -    if (mapcache_entry == MAP_FAILED) {
 -        errno = ENOMEM;
 -        return -1;
@@ -419,7 +419,7 @@
 -        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
 -            (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
 -        while (j > 0)
--            word = (word << 1) | !(pfns[i + --j] & 0xF0000000UL);
+-            word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
 -        entry->valid_mapping[i / BITS_PER_LONG] = word;
 -    }
 -}
@@ -480,22 +480,23 @@
  
  int main(int argc, char **argv)
  {
-@@ -6094,14 +5947,6 @@ int main(int argc, char **argv)
-     QEMUMachine *machine;
+@@ -7089,15 +6942,7 @@ int main(int argc, char **argv)
      char usb_devices[MAX_USB_CMDLINE][128];
      int usb_devices_index;
+     int fds[2];
 -    unsigned long ioreq_pfn;
 -    extern void *shared_page;
 -    extern void *buffered_io_page;
+     struct rlimit rl;
 -#ifdef __ia64__
 -    unsigned long nr_pages;
 -    xen_pfn_t *page_array;
 -    extern void *buffered_pio_page;
 -#endif
- 
-     char qemu_dm_logfilename[64];
- 
-@@ -6586,6 +6431,7 @@ int main(int argc, char **argv)
+     sigset_t set;
+     char qemu_dm_logfilename[128];
+     const char *direct_pci = NULL;
+@@ -7681,6 +7526,7 @@ int main(int argc, char **argv)
  
  #ifdef CONFIG_DM
      bdrv_init();
@@ -503,18 +504,12 @@
      xenstore_parse_domain_config(domid);
  #endif /* CONFIG_DM */
  
-@@ -6639,99 +6485,17 @@ int main(int argc, char **argv)
-             exit(1);
+@@ -7774,83 +7620,6 @@ int main(int argc, char **argv)
+ 	}
+ 	phys_ram_size += ret;
      }
- 
--#if defined (__ia64__)
--    if (ram_size > MMIO_START)
--        ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
--#endif
- 
-     /* init the memory */
-     phys_ram_size = ram_size + vga_ram_size + bios_size;
- 
+-#endif /* !CONFIG_DM */
+-
 -#ifdef CONFIG_DM
 -
 -    xc_handle = xc_interface_open();
@@ -590,11 +585,10 @@
 -    timeoffset_get();
 -
 -#else  /* !CONFIG_DM */
--
-+#ifndef CONFIG_DM
+ 
      phys_ram_base = qemu_vmalloc(phys_ram_size);
      if (!phys_ram_base) {
-         fprintf(stderr, "Could not allocate physical memory\n");
+@@ -7858,9 +7627,6 @@ int main(int argc, char **argv)
          exit(1);
      }
  
@@ -604,10 +598,10 @@
      /* we always create the cdrom drive, even if no disk is there */
      bdrv_init();
      if (cdrom_index >= 0) {
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/vl.h xen-3.1.0-src.new/tools/ioemu/vl.h
---- xen-3.1.0-src.orig/tools/ioemu/vl.h	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/vl.h	2007-08-23 10:42:55.000000000 -0400
-@@ -966,6 +966,9 @@ extern void pci_piix4_acpi_init(PCIBus *
+diff -r b4278beaf354 tools/ioemu/vl.h
+--- a/tools/ioemu/vl.h	Wed Oct 17 13:12:03 2007 +0100
++++ b/tools/ioemu/vl.h	Fri Oct 19 17:32:05 2007 -0400
+@@ -1108,6 +1108,9 @@ extern void pci_piix4_acpi_init(PCIBus *
  /* pc.c */
  extern QEMUMachine pc_machine;
  extern QEMUMachine isapc_machine;

xen-pvfb-02-qemu-pv-machine.patch:

Index: xen-pvfb-02-qemu-pv-machine.patch
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/xen-pvfb-02-qemu-pv-machine.patch,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -u -r1.2 -r1.2.2.1
--- xen-pvfb-02-qemu-pv-machine.patch	24 Sep 2007 20:01:25 -0000	1.2
+++ xen-pvfb-02-qemu-pv-machine.patch	19 Oct 2007 23:35:08 -0000	1.2.2.1
@@ -1,6 +1,18 @@
-diff -ruNp xen-3.1.0-src.orig/tools/ioemu/hw/xen_machine_pv.c xen-3.1.0-src.new/tools/ioemu/hw/xen_machine_pv.c
---- xen-3.1.0-src.orig/tools/ioemu/hw/xen_machine_pv.c	1969-12-31 19:00:00.000000000 -0500
-+++ xen-3.1.0-src.new/tools/ioemu/hw/xen_machine_pv.c	2007-09-24 13:22:06.000000000 -0400
+diff -r 327024163186 tools/ioemu/Makefile.target
+--- a/tools/ioemu/Makefile.target	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/ioemu/Makefile.target	Tue Aug 14 13:26:18 2007 -0400
+@@ -401,6 +401,8 @@ VL_OBJS+= xenstore.o
+ VL_OBJS+= xenstore.o
+ VL_OBJS+= xen_platform.o
+ VL_OBJS+= xen_machine_fv.o
++VL_OBJS+= xen_machine_pv.o
++VL_OBJS+= ../../xenfb/xenfb.o
+ VL_OBJS+= tpm_tis.o
+ CPPFLAGS += -DHAS_AUDIO
+ endif
+diff -r 327024163186 tools/ioemu/hw/xen_machine_pv.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/tools/ioemu/hw/xen_machine_pv.c	Tue Aug 14 14:21:29 2007 -0400
 @@ -0,0 +1,231 @@
 +/*
 + * QEMU Xen PV Machine
@@ -165,7 +177,7 @@
 +			int snapshot,
 +			const char *kernel_filename,
 +			const char *kernel_cmdline,
-+			const char *initrd_filename, time_t timeoffset)
++			const char *initrd_filename)
 +{
 +    struct xenfb *xenfb;
 +    extern int domid;
@@ -198,8 +210,8 @@
 +    /* Register our keyboard & mouse handlers */
 +    qemu_add_kbd_event_handler(xen_pvfb_put_keycode, xenfb);
 +    qemu_add_mouse_event_handler(xen_pvfb_mouse_event, xenfb,
-+                                 xenfb->abs_pointer_wanted
-+                                 );
++                                 xenfb->abs_pointer_wanted,
++                                 "Xen PVFB Mouse");
 +
 +    /* Listen for events from xenstore */
 +    fd = xenfb_get_store_fd(xenfb);
@@ -233,30 +245,19 @@
 + *  tab-width: 4
 + * End:
 + */
-diff -ruNp xen-3.1.0-src.orig/tools/ioemu/Makefile.target xen-3.1.0-src.new/tools/ioemu/Makefile.target
---- xen-3.1.0-src.orig/tools/ioemu/Makefile.target	2007-09-24 13:21:38.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/Makefile.target	2007-09-24 13:22:06.000000000 -0400
-@@ -370,6 +370,8 @@ VL_OBJS+= piix4acpi.o
- VL_OBJS+= xenstore.o
- VL_OBJS+= xen_platform.o
- VL_OBJS+= xen_machine_fv.o
-+VL_OBJS+= xen_machine_pv.o
-+VL_OBJS+= ../../xenfb/xenfb.o
- VL_OBJS+= tpm_tis.o
- DEFINES += -DHAS_AUDIO
- endif
-diff -ruNp xen-3.1.0-src.orig/tools/ioemu/target-i386-dm/helper2.c xen-3.1.0-src.new/tools/ioemu/target-i386-dm/helper2.c
---- xen-3.1.0-src.orig/tools/ioemu/target-i386-dm/helper2.c	2007-09-24 13:21:38.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/target-i386-dm/helper2.c	2007-09-24 13:22:06.000000000 -0400
-@@ -614,14 +614,15 @@ int main_loop(void)
+diff -r 327024163186 tools/ioemu/target-i386-dm/helper2.c
+--- a/tools/ioemu/target-i386-dm/helper2.c	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/ioemu/target-i386-dm/helper2.c	Tue Aug 14 12:58:46 2007 -0400
+@@ -616,7 +616,7 @@ int main_loop(void)
      extern int shutdown_requested;
      extern int suspend_requested;
      CPUState *env = cpu_single_env;
 -    int evtchn_fd = xc_evtchn_fd(xce_handle);
 +    int evtchn_fd = xce_handle == -1 ? -1 : xc_evtchn_fd(xce_handle);
      char qemu_file[PATH_MAX];
+     fd_set fds;
  
-     buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io,
+@@ -624,7 +624,8 @@ int main_loop(void)
  				       cpu_single_env);
      qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock));
  
@@ -264,21 +265,21 @@
 +    if (evtchn_fd != -1)
 +        qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
  
-     while (!(vm_running && suspend_requested))
-         /* Wait up to 10 msec. */
-diff -ruNp xen-3.1.0-src.orig/tools/ioemu/vl.c xen-3.1.0-src.new/tools/ioemu/vl.c
---- xen-3.1.0-src.orig/tools/ioemu/vl.c	2007-09-24 13:21:38.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/vl.c	2007-09-24 13:22:06.000000000 -0400
-@@ -168,7 +168,7 @@ int xc_handle;
+     xenstore_record_dm_state("running");
+     while (1) {
+diff -r 327024163186 tools/ioemu/vl.c
+--- a/tools/ioemu/vl.c	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/ioemu/vl.c	Tue Aug 14 13:50:44 2007 -0400
+@@ -182,7 +182,7 @@ extern int vcpus;
  
- time_t timeoffset = 0;
+ int xc_handle;
  
--char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
-+char domain_name[1024] = "Xen-no-name";
+-char domain_name[64] = "Xen-HVM-no-name";
++char domain_name[64] = "Xen-no-name";
  extern int domid;
  
  char vncpasswd[64];
-@@ -5698,6 +5698,7 @@ void register_machines(void)
+@@ -6651,6 +6651,7 @@ void register_machines(void)
      qemu_register_machine(&isapc_machine);
  #else
      qemu_register_machine(&xenfv_machine);
@@ -286,20 +287,19 @@
  #endif
  #elif defined(TARGET_PPC)
      qemu_register_machine(&heathrow_machine);
-@@ -6398,7 +6399,8 @@ int main(int argc, char **argv)
-                 acpi_enabled = 0;
+@@ -7370,7 +7371,7 @@ int main(int argc, char **argv)
                  break;
              case QEMU_OPTION_domainname:
--                strncat(domain_name, optarg, sizeof(domain_name) - 20);
-+                snprintf(domain_name, sizeof(domain_name),
+                 snprintf(domain_name, sizeof(domain_name),
+-                         "Xen-HVM-%s", optarg);
 +                         "Xen-%s", optarg);
                  break;
              case QEMU_OPTION_d:
                  domid = atoi(optarg);
-diff -ruNp xen-3.1.0-src.orig/tools/ioemu/vl.h xen-3.1.0-src.new/tools/ioemu/vl.h
---- xen-3.1.0-src.orig/tools/ioemu/vl.h	2007-09-24 13:21:38.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/vl.h	2007-09-24 13:22:06.000000000 -0400
-@@ -968,6 +968,7 @@ extern QEMUMachine pc_machine;
+diff -r 327024163186 tools/ioemu/vl.h
+--- a/tools/ioemu/vl.h	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/ioemu/vl.h	Tue Aug 14 12:55:35 2007 -0400
+@@ -1120,6 +1120,7 @@ extern QEMUMachine isapc_machine;
  extern QEMUMachine isapc_machine;
  #ifdef CONFIG_DM
  extern QEMUMachine xenfv_machine;
@@ -307,18 +307,10 @@
  #endif
  extern int fd_bootchk;
  
-diff -ruNp xen-3.1.0-src.orig/tools/python/xen/xend/server/vfbif.py xen-3.1.0-src.new/tools/python/xen/xend/server/vfbif.py
---- xen-3.1.0-src.orig/tools/python/xen/xend/server/vfbif.py	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/python/xen/xend/server/vfbif.py	2007-09-24 13:22:54.000000000 -0400
-@@ -6,6 +6,7 @@ import xen.xend
- import os
- 
- def spawn_detached(path, args, env):
-+    log.debug("Spawn: " + str(args))
-     p = os.fork()
-     if p == 0:
-         os.spawnve(os.P_NOWAIT, path, args, env)
-@@ -50,8 +51,10 @@ class VfbifController(DevController):
+diff -r 327024163186 tools/python/xen/xend/server/vfbif.py
+--- a/tools/python/xen/xend/server/vfbif.py	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/python/xen/xend/server/vfbif.py	Tue Aug 14 14:15:52 2007 -0400
+@@ -50,8 +50,10 @@ class VfbifController(DevController):
              # is HVM, so qemu-dm will handle the vfb.
              return
          
@@ -331,7 +323,7 @@
          t = config.get("type", None)
          if t == "vnc":
              passwd = None
-@@ -65,26 +68,24 @@ class VfbifController(DevController):
+@@ -65,15 +67,14 @@ class VfbifController(DevController):
              else:
                  log.debug("No VNC passwd configured for vfb access")
  
@@ -346,13 +338,18 @@
                                     xen.xend.XendOptions.instance().get_vnclisten_address())
 -            args += [ "--listen", vnclisten ]
 +            vncdisplay = config.get('vncdisplay', 0)
-+            args += ['-vnc', "%s:%d" % (vnclisten, int(vncdisplay))]
++            args += ['-vnc', "%s:%d" % (vnclisten, vncdisplay)]
 +
 +            if config.get('vncunused', 0):
 +                args += ['-vncunused']
 +
              if config.has_key("keymap"):
                  args += ["-k", "%s" % config["keymap"]]
+             else:
+@@ -81,15 +82,14 @@ class VfbifController(DevController):
+                 if xoptions.get_keymap():
+                     args += ["-k", "%s" % xoptions.get_keymap()]
+ 
 -            spawn_detached(args[0], args + std_args, os.environ)
 +            spawn_detached(args[0], args, os.environ)
          elif t == "sdl":
@@ -367,10 +364,10 @@
          else:
              raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
  
-diff -ruNp xen-3.1.0-src.orig/tools/xenfb/xenfb.c xen-3.1.0-src.new/tools/xenfb/xenfb.c
---- xen-3.1.0-src.orig/tools/xenfb/xenfb.c	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/xenfb.c	2007-09-24 13:22:06.000000000 -0400
-@@ -677,37 +677,58 @@ static int xenfb_on_state_change(struct 
+diff -r 327024163186 tools/xenfb/xenfb.c
+--- a/tools/xenfb/xenfb.c	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/xenfb/xenfb.c	Tue Aug 14 13:41:54 2007 -0400
+@@ -676,37 +676,58 @@ static int xenfb_on_state_change(struct 
  	return 0;
  }
  
@@ -402,15 +399,6 @@
  	char **vec;
  	int r;
  
--	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
--		port = xc_evtchn_pending(xenfb->evt_xch);
--		if (port == -1)
--			return -1;
--
--		if (port == xenfb->fb.port)
--			xenfb_on_fb_event(xenfb);
--		else if (port == xenfb->kbd.port)
--			xenfb_on_kbd_event(xenfb);
 +	vec = xs_read_watch(xenfb->xsh, &dummy);
 +	free(vec);
 +	r = xenfb_on_state_change(&xenfb->fb);
@@ -421,9 +409,7 @@
 +
 +	return 0;
 +}
- 
--		if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
--			return -1;
++
 +
 +/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
 +int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
@@ -431,7 +417,18 @@
 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
 +	int ret;
 +
-+	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
+ 	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
+-		port = xc_evtchn_pending(xenfb->evt_xch);
+-		if (port == -1)
+-			return -1;
+-
+-		if (port == xenfb->fb.port)
+-			xenfb_on_fb_event(xenfb);
+-		else if (port == xenfb->kbd.port)
+-			xenfb_on_kbd_event(xenfb);
+-
+-		if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
+-			return -1;
 +		if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0)
 +			return ret;
  	}
@@ -449,10 +446,12 @@
  	}
  
  	return 0;
-@@ -724,6 +745,18 @@ int xenfb_select_fds(struct xenfb *xenfb
+@@ -721,6 +742,18 @@ int xenfb_select_fds(struct xenfb *xenfb
+ 	FD_SET(fd1, readfds);
+ 	FD_SET(fd2, readfds);
  	return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
- }
- 
++}
++
 +int xenfb_get_store_fd(struct xenfb *xenfb_pub)
 +{
 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
@@ -463,12 +462,10 @@
 +{
 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
 +	return xc_evtchn_fd(xenfb->evt_xch);
-+}
-+
+ }
+ 
  static int xenfb_kbd_event(struct xenfb_private *xenfb,
- 			   union xenkbd_in_event *event)
- {
-@@ -784,3 +817,10 @@ int xenfb_send_position(struct xenfb *xe
+@@ -783,3 +816,10 @@ int xenfb_send_position(struct xenfb *xe
  
  	return xenfb_kbd_event(xenfb, &event);
  }
@@ -479,9 +476,9 @@
 + *  tab-width: 8
 + * End:
 + */
-diff -ruNp xen-3.1.0-src.orig/tools/xenfb/xenfb.h xen-3.1.0-src.new/tools/xenfb/xenfb.h
---- xen-3.1.0-src.orig/tools/xenfb/xenfb.h	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/xenfb.h	2007-09-24 13:22:06.000000000 -0400
+diff -r 327024163186 tools/xenfb/xenfb.h
+--- a/tools/xenfb/xenfb.h	Tue Aug 14 12:52:54 2007 -0400
++++ b/tools/xenfb/xenfb.h	Tue Aug 14 13:42:04 2007 -0400
 @@ -25,8 +25,12 @@ void xenfb_teardown(struct xenfb *xenfb)
  
  int xenfb_attach_dom(struct xenfb *xenfb, int domid);

xen-pvfb-03-xenfb-remove.patch:

Index: xen-pvfb-03-xenfb-remove.patch
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/xen-pvfb-03-xenfb-remove.patch,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
--- xen-pvfb-03-xenfb-remove.patch	28 Aug 2007 21:50:58 -0000	1.1
+++ xen-pvfb-03-xenfb-remove.patch	19 Oct 2007 23:35:08 -0000	1.1.2.1
@@ -1,7 +1,7 @@
-diff -rupN xen-3.1.0-src.orig/Config.mk xen-3.1.0-src.new/Config.mk
---- xen-3.1.0-src.orig/Config.mk	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/Config.mk	2007-08-23 11:05:41.000000000 -0400
-@@ -90,7 +90,6 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_
+diff -r 0e5281845f71 Config.mk
+--- a/Config.mk	Fri Oct 19 17:38:47 2007 -0400
++++ b/Config.mk	Fri Oct 19 17:38:49 2007 -0400
+@@ -88,7 +88,6 @@ XENSTAT_XENTOP     ?= y
  XENSTAT_XENTOP     ?= y
  VTPM_TOOLS         ?= n
  LIBXENAPI_BINDINGS ?= n
@@ -9,10 +9,42 @@
  PYTHON_TOOLS       ?= y
  
  -include $(XEN_ROOT)/.config
-diff -rupN xen-3.1.0-src.orig/tools/check/check_libvncserver xen-3.1.0-src.new/tools/check/check_libvncserver
---- xen-3.1.0-src.orig/tools/check/check_libvncserver	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/check/check_libvncserver	1969-12-31 19:00:00.000000000 -0500
-@@ -1,27 +0,0 @@
+diff -r 0e5281845f71 tools/Makefile
+--- a/tools/Makefile	Fri Oct 19 17:38:47 2007 -0400
++++ b/tools/Makefile	Fri Oct 19 17:38:49 2007 -0400
+@@ -20,7 +20,6 @@ SUBDIRS-y += libaio
+ SUBDIRS-y += libaio
+ SUBDIRS-y += blktap
+ SUBDIRS-y += libfsimage
+-SUBDIRS-$(XENFB_TOOLS) += xenfb
+ SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
+ 
+ # These don't cross-compile
+diff -r 0e5281845f71 tools/check/Makefile
+--- a/tools/check/Makefile	Fri Oct 19 17:38:47 2007 -0400
++++ b/tools/check/Makefile	Fri Oct 19 17:39:15 2007 -0400
+@@ -7,7 +7,7 @@ all: build
+ # Check this machine is OK for building on.
+ .PHONY: build
+ build:
+-	XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk build
++	LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk build
+ 
+ # Check this machine is OK for installing on.
+ # DO NOT use this check from 'make install' in the parent
+@@ -15,7 +15,7 @@ build:
+ # copy rather than actually installing.
+ .PHONY: install
+ install:
+-	XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk install
++	LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk install
+ 
+ .PHONY: clean
+ clean:
+diff -r 0e5281845f71 tools/check/check_libvncserver
+--- a/tools/check/check_libvncserver	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,38 +0,0 @@
 -#!/bin/sh
 -# CHECK-BUILD CHECK-INSTALL
 -
@@ -25,6 +57,7 @@
 -RC=0
 -
 -LIBVNCSERVER_CONFIG="$(which libvncserver-config)"
+-tmpfile=$(mktemp)
 -
 -if test -z ${LIBVNCSERVER_CONFIG}; then 
 -    RC=1
@@ -37,12 +70,22 @@
 -    echo "FAILED"
 -	echo " *** libvncserver-config is missing. "
 -    echo " *** Please install libvncserver."
+-elif ! ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile >/dev/null 2>&1; then
+-    echo "FAILED"
+-    echo " *** dependency libraries for libvncserver are missing: "
+-    RC=1
+-    for i in $(ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile 2>&1 >/dev/null); do
+-        case $i in
+-        -l*) echo lib${i#-l}
+-        esac
+-    done
 -fi
+-rm -f $tmpfile
 -
 -exit $RC
-diff -rupN xen-3.1.0-src.orig/tools/check/check_sdl xen-3.1.0-src.new/tools/check/check_sdl
---- xen-3.1.0-src.orig/tools/check/check_sdl	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/check/check_sdl	1969-12-31 19:00:00.000000000 -0500
+diff -r 0e5281845f71 tools/check/check_sdl
+--- a/tools/check/check_sdl	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
 @@ -1,27 +0,0 @@
 -#!/bin/sh
 -# CHECK-BUILD CHECK-INSTALL
@@ -71,31 +114,34 @@
 -fi
 -
 -exit $RC
-diff -rupN xen-3.1.0-src.orig/tools/check/Makefile xen-3.1.0-src.new/tools/check/Makefile
---- xen-3.1.0-src.orig/tools/check/Makefile	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/check/Makefile	2007-08-23 11:06:47.000000000 -0400
-@@ -7,7 +7,7 @@ all: build
- # Check this machine is OK for building on.
- .PHONY: build
- build:
--	XENFB_TOOLS=$(XENFB_TOOLS) ./chk build
-+	./chk build
+diff -r 0e5281845f71 tools/ioemu/Makefile.target
+--- a/tools/ioemu/Makefile.target	Fri Oct 19 17:38:47 2007 -0400
++++ b/tools/ioemu/Makefile.target	Fri Oct 19 17:38:49 2007 -0400
+@@ -411,7 +411,7 @@ VL_OBJS+= xen_platform.o
+ VL_OBJS+= xen_platform.o
+ VL_OBJS+= xen_machine_fv.o
+ VL_OBJS+= xen_machine_pv.o
+-VL_OBJS+= ../../xenfb/xenfb.o
++VL_OBJS+= xenfb.o
+ VL_OBJS+= tpm_tis.o
+ CPPFLAGS += -DHAS_AUDIO
+ endif
+diff -r 0e5281845f71 tools/ioemu/hw/xen_machine_pv.c
+--- a/tools/ioemu/hw/xen_machine_pv.c	Fri Oct 19 17:38:47 2007 -0400
++++ b/tools/ioemu/hw/xen_machine_pv.c	Fri Oct 19 17:38:49 2007 -0400
+@@ -23,7 +23,7 @@
+  */
  
- # Check this machine is OK for installing on.
- # DO NOT use this check from 'make install' in the parent
-@@ -15,7 +15,7 @@ build:
- # copy rather than actually installing.
- .PHONY: install
- install:
--	XENFB_TOOLS=$(XENFB_TOOLS) ./chk install
-+	./chk install
+ #include "vl.h"
+-#include "../../xenfb/xenfb.h"
++#include "xenfb.h"
+ #include <linux/input.h>
  
- .PHONY: clean
- clean:
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/hw/xenfb.c xen-3.1.0-src.new/tools/ioemu/hw/xenfb.c
---- xen-3.1.0-src.orig/tools/ioemu/hw/xenfb.c	1969-12-31 19:00:00.000000000 -0500
-+++ xen-3.1.0-src.new/tools/ioemu/hw/xenfb.c	2007-08-23 11:05:47.000000000 -0400
-@@ -0,0 +1,825 @@
+ /* A convenient function for munging pixels between different depths */
+diff -r 0e5281845f71 tools/ioemu/hw/xenfb.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/tools/ioemu/hw/xenfb.c	Fri Oct 19 17:41:45 2007 -0400
+@@ -0,0 +1,819 @@
 +#include <stdarg.h>
 +#include <stdlib.h>
 +#include <sys/types.h>
@@ -496,21 +542,15 @@
 +	if (!pgmfns || !fbmfns)
 +		goto out;
 +
-+	/*
-+	 * Bug alert: xc_map_foreign_batch() can fail partly and
-+	 * return a non-null value.  This is a design flaw.  When it
-+	 * happens, we happily continue here, and later crash on
-+	 * access.
-+	 */
 +	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
-+	map = xc_map_foreign_batch(xenfb->xc, domid,
++	map = xc_map_foreign_pages(xenfb->xc, domid,
 +				   PROT_READ, pgmfns, n_fbdirs);
 +	if (map == NULL)
 +		goto out;
 +	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
 +	munmap(map, n_fbdirs * XC_PAGE_SIZE);
 +
-+	xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
++	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
 +				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
 +	if (xenfb->pub.pixels == NULL)
 +		goto out;
@@ -921,9 +961,9 @@
 + *  tab-width: 8
 + * End:
 + */
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/hw/xenfb.h xen-3.1.0-src.new/tools/ioemu/hw/xenfb.h
---- xen-3.1.0-src.orig/tools/ioemu/hw/xenfb.h	1969-12-31 19:00:00.000000000 -0500
-+++ xen-3.1.0-src.new/tools/ioemu/hw/xenfb.h	2007-08-23 11:05:47.000000000 -0400
+diff -r 0e5281845f71 tools/ioemu/hw/xenfb.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/tools/ioemu/hw/xenfb.h	Fri Oct 19 17:38:49 2007 -0400
 @@ -0,0 +1,39 @@
 +#ifndef _XENFB_H_
 +#define _XENFB_H_
@@ -964,50 +1004,15 @@
 +int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
 +
 +#endif
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/hw/xen_machine_pv.c xen-3.1.0-src.new/tools/ioemu/hw/xen_machine_pv.c
---- xen-3.1.0-src.orig/tools/ioemu/hw/xen_machine_pv.c	2007-08-23 11:05:27.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/hw/xen_machine_pv.c	2007-08-23 11:05:47.000000000 -0400
-@@ -23,7 +23,7 @@
-  */
- 
- #include "vl.h"
--#include "../../xenfb/xenfb.h"
-+#include "xenfb.h"
- #include <linux/input.h>
- 
- /* A convenient function for munging pixels between different depths */
-diff -rupN xen-3.1.0-src.orig/tools/ioemu/Makefile.target xen-3.1.0-src.new/tools/ioemu/Makefile.target
---- xen-3.1.0-src.orig/tools/ioemu/Makefile.target	2007-08-23 11:05:27.000000000 -0400
-+++ xen-3.1.0-src.new/tools/ioemu/Makefile.target	2007-08-23 11:05:47.000000000 -0400
-@@ -371,7 +371,7 @@ VL_OBJS+= xenstore.o
- VL_OBJS+= xen_platform.o
- VL_OBJS+= xen_machine_fv.o
- VL_OBJS+= xen_machine_pv.o
--VL_OBJS+= ../../xenfb/xenfb.o
-+VL_OBJS+= xenfb.o
- VL_OBJS+= tpm_tis.o
- DEFINES += -DHAS_AUDIO
- endif
-diff -rupN xen-3.1.0-src.orig/tools/Makefile xen-3.1.0-src.new/tools/Makefile
---- xen-3.1.0-src.orig/tools/Makefile	2007-08-23 11:05:27.000000000 -0400
-+++ xen-3.1.0-src.new/tools/Makefile	2007-08-23 11:05:41.000000000 -0400
-@@ -19,7 +19,6 @@ SUBDIRS-y += xenstat
- SUBDIRS-y += libaio
- SUBDIRS-y += blktap
- SUBDIRS-y += libfsimage
--SUBDIRS-$(XENFB_TOOLS) += xenfb
- SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
- 
- # These don't cross-compile
-diff -rupN xen-3.1.0-src.orig/tools/xenfb/Makefile xen-3.1.0-src.new/tools/xenfb/Makefile
---- xen-3.1.0-src.orig/tools/xenfb/Makefile	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/Makefile	1969-12-31 19:00:00.000000000 -0500
+diff -r 0e5281845f71 tools/xenfb/Makefile
+--- a/tools/xenfb/Makefile	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
 @@ -1,32 +0,0 @@
 -XEN_ROOT=../..
 -include $(XEN_ROOT)/tools/Rules.mk
 -
 -CFLAGS  += -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
--CFLAGS  += -I$(XEN_ROOT)/linux-2.6-xen-sparse/include -I$(XEN_ROOT)/tools/ioemu
+-CFLAGS  += -I$(XEN_ROOT)/tools/ioemu
 -LDFLAGS += -L$(XEN_LIBXC) -L$(XEN_XENSTORE)
 -
 -.PHONY: all
@@ -1035,9 +1040,9 @@
 -vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore
 -
 -sdlfb.o xenfb.o vncfb.o: xenfb.h
-diff -rupN xen-3.1.0-src.orig/tools/xenfb/sdlfb.c xen-3.1.0-src.new/tools/xenfb/sdlfb.c
---- xen-3.1.0-src.orig/tools/xenfb/sdlfb.c	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/sdlfb.c	1969-12-31 19:00:00.000000000 -0500
+diff -r 0e5281845f71 tools/xenfb/sdlfb.c
+--- a/tools/xenfb/sdlfb.c	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
 @@ -1,342 +0,0 @@
 -#include <SDL.h>
 -#include <errno.h>
@@ -1381,10 +1386,10 @@
 -
 -	return 0;
 -}
-diff -rupN xen-3.1.0-src.orig/tools/xenfb/vncfb.c xen-3.1.0-src.new/tools/xenfb/vncfb.c
---- xen-3.1.0-src.orig/tools/xenfb/vncfb.c	2007-05-18 10:45:21.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/vncfb.c	1969-12-31 19:00:00.000000000 -0500
-@@ -1,422 +0,0 @@
+diff -r 0e5281845f71 tools/xenfb/vncfb.c
+--- a/tools/xenfb/vncfb.c	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,522 +0,0 @@
 -#define _GNU_SOURCE
 -#include <errno.h>
 -#include <getopt.h>
@@ -1442,12 +1447,47 @@
 -unsigned char keycode_table[512];
 -
 -static void *kbd_layout;
+-uint8_t modifiers_state[256];
 -
 -static int btnmap[] = {
 -	BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
 -	BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
 -};
 -
+-static void press_key_shift_down(struct xenfb* xenfb, int down, int scancode)
+-{
+-	if (down)
+-		xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
+-
+-	if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
+-		fprintf(stderr, "Key %d %s lost (%s)\n",
+-			scancode, "down", strerror(errno));
+-
+-	if (!down)
+-		xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
+-}
+-
+-static void press_key_shift_up(struct xenfb* xenfb, int down, int scancode)
+-{
+-	if (down) {
+-		if (modifiers_state[0x2a])
+-			xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
+-		if (modifiers_state[0x36])
+-			xenfb_send_key(xenfb, 0, keycode_table[0x36]);
+-	}
+-
+-	if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
+-		fprintf(stderr, "Key %d %s lost (%s)\n",
+-			scancode, "down", strerror(errno));
+-
+-	if (!down) {
+-		if (modifiers_state[0x2a])
+-			xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
+-		if (modifiers_state[0x36])
+-			xenfb_send_key(xenfb, 1, keycode_table[0x36]);
+-	}
+-}
+-
 -static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
 -{
 -	/*
@@ -1462,14 +1502,75 @@
 -	rfbScreenInfoPtr server = cl->screen;
 -	struct xenfb *xenfb = server->screenData;
 -	int scancode;
+-	int shift = 0;
+-	int shift_keys = 0;
 -
--	if (keycode >= 'A' && keycode <= 'Z')
+-	if (keycode >= 'A' && keycode <= 'Z') {
 -		keycode += 'a' - 'A';
+-		shift = 1;
+-	}
+-	else {
+-		shift = keysymIsShift(kbd_layout, keycode);
+-	}
+-	shift_keys = modifiers_state[0x2a] | modifiers_state[0x36];	
 -
--	scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
+-	scancode = keysym2scancode(kbd_layout, keycode);
 -	if (scancode == 0)
 -		return;
--	if (xenfb_send_key(xenfb, down, scancode) < 0)
+-
+-	switch(scancode) {
+-	case 0x2a:			/* Left Shift */
+-	case 0x36:			/* Right Shift */
+-	case 0x1d:			/* Left CTRL */
+-	case 0x9d:			/* Right CTRL */
+-	case 0x38:			/* Left ALT */
+-	case 0xb8:			/* Right ALT */
+-		if (down)
+-			modifiers_state[scancode] = 1;
+-		else
+-			modifiers_state[scancode] = 0;
+-		xenfb_send_key(xenfb, down, keycode_table[scancode]); 
+-		return;
+-	case 0x45:			/* NumLock */
+-		if (!down)
+-			modifiers_state[scancode] ^= 1;
+-		xenfb_send_key(xenfb, down, keycode_table[scancode]);
+-		return;
+-	}
+-
+-	if (keycodeIsKeypad(kbd_layout, scancode)) {
+-	/* If the numlock state needs to change then simulate an additional
+-	   keypress before sending this one.  This will happen if the user
+-	   toggles numlock away from the VNC window.
+-	*/
+-		if (keysymIsNumlock(kbd_layout, keycode)) {
+-			if (!modifiers_state[0x45]) {
+-				modifiers_state[0x45] = 1;
+-				xenfb_send_key(xenfb, 1, keycode_table[0x45]);
+-				xenfb_send_key(xenfb, 0, keycode_table[0x45]);
+-			}
+-		} else {
+-			if (modifiers_state[0x45]) {
+-				modifiers_state[0x45] = 0;
+-				xenfb_send_key(xenfb, 1, keycode_table[0x45]);
+-				xenfb_send_key(xenfb, 0, keycode_table[0x45]);
+-			}
+-		}
+-	}
+-
+-	/* If the shift state needs to change then simulate an additional
+-	   keypress before sending this one.
+-	*/
+-	if (shift && !shift_keys) {
+-		press_key_shift_down(xenfb, down, scancode);
+-		return;
+-	}
+-	else if (!shift && shift_keys) {
+-		press_key_shift_up(xenfb, down, scancode);
+-		return;
+-	}
+-
+-	if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
 -		fprintf(stderr, "Key %d %s lost (%s)\n",
 -			scancode, down ? "down" : "up",
 -			strerror(errno));
@@ -1701,6 +1802,10 @@
 -			atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
 -	}
 -
+-	for (i = 0; i < 256; i++ ) {
+-		modifiers_state[i] = 0;
+-	}
+-
 -	fake_argv[2] = portstr;
 -
 -        if (title != NULL)
@@ -1807,10 +1912,10 @@
 -
 -	return 0;
 -}
-diff -rupN xen-3.1.0-src.orig/tools/xenfb/xenfb.c xen-3.1.0-src.new/tools/xenfb/xenfb.c
---- xen-3.1.0-src.orig/tools/xenfb/xenfb.c	2007-08-23 11:05:27.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/xenfb.c	1969-12-31 19:00:00.000000000 -0500
-@@ -1,826 +0,0 @@
+diff -r 0e5281845f71 tools/xenfb/xenfb.c
+--- a/tools/xenfb/xenfb.c	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,819 +0,0 @@
 -#include <stdarg.h>
 -#include <stdlib.h>
 -#include <sys/types.h>
@@ -1823,7 +1928,6 @@
 -#include <xen/io/protocols.h>
 -#include <sys/select.h>
 -#include <stdbool.h>
--#include <xen/linux/evtchn.h>
 -#include <xen/event_channel.h>
 -#include <sys/mman.h>
 -#include <errno.h>
@@ -2212,21 +2316,15 @@
 -	if (!pgmfns || !fbmfns)
 -		goto out;
 -
--	/*
--	 * Bug alert: xc_map_foreign_batch() can fail partly and
--	 * return a non-null value.  This is a design flaw.  When it
--	 * happens, we happily continue here, and later crash on
--	 * access.
--	 */
 -	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
--	map = xc_map_foreign_batch(xenfb->xc, domid,
+-	map = xc_map_foreign_pages(xenfb->xc, domid,
 -				   PROT_READ, pgmfns, n_fbdirs);
 -	if (map == NULL)
 -		goto out;
 -	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
 -	munmap(map, n_fbdirs * XC_PAGE_SIZE);
 -
--	xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
+-	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
 -				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
 -	if (xenfb->pub.pixels == NULL)
 -		goto out;
@@ -2637,9 +2735,9 @@
 - *  tab-width: 8
 - * End:
 - */
-diff -rupN xen-3.1.0-src.orig/tools/xenfb/xenfb.h xen-3.1.0-src.new/tools/xenfb/xenfb.h
---- xen-3.1.0-src.orig/tools/xenfb/xenfb.h	2007-08-23 11:05:27.000000000 -0400
-+++ xen-3.1.0-src.new/tools/xenfb/xenfb.h	1969-12-31 19:00:00.000000000 -0500
+diff -r 0e5281845f71 tools/xenfb/xenfb.h
+--- a/tools/xenfb/xenfb.h	Fri Oct 19 17:38:47 2007 -0400
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
 @@ -1,39 +0,0 @@
 -#ifndef _XENFB_H_
 -#define _XENFB_H_


Index: xen.spec
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/xen.spec,v
retrieving revision 1.194
retrieving revision 1.194.2.1
diff -u -r1.194 -r1.194.2.1
--- xen.spec	11 Oct 2007 00:47:59 -0000	1.194
+++ xen.spec	19 Oct 2007 23:35:08 -0000	1.194.2.1
@@ -1,13 +1,15 @@
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
 
+%define changeset 16125
+
 Summary: Xen is a virtual machine monitor
 Name:    xen
-Version: 3.1.0
-Release: 12%{?dist}
+Version: 3.1.1
+Release: 0%{?dist}.2unstable
 Group:   Development/Libraries
 License: GPL
 URL:     http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html
-Source0: %{name}-%{version}-src.tgz
+Source0: %{name}-unstable.hg-%{changeset}.tar.gz
 Source2: %{name}.modules
 Source3: %{name}.sysconfig
 Source4: %{name}.logrotate
@@ -16,21 +18,7 @@
 Patch6: xen-net-bridge.patch
 Patch13: xen-dumpdir.patch
 Patch18: xen-block-readonly.patch
-Patch19: xen-start-fail-cleanup.patch
 
-Patch20: xen-blktap-no-aio-epoll.patch
-Patch21: xen-blktap-error-returns.patch
-Patch25: xen-qemu-vnc-delete.patch
-Patch26: xen-hvm-save-paths.patch
-Patch27: xen-console-log.patch
-Patch28: xen-keyboard.patch
-Patch29: xen-3.1.0-libxc-native-protocol.patch
-Patch30: xen-3.1.0-dev-native-protocol.patch
-Patch31: xen-tpm-functions.patch
-Patch32: xen-clobber-vif-type.patch
-Patch33: xen-vmxassist-irqs.patch
-Patch34: xen-3.1.0-no-xenapi-docs.patch
-Patch35: xen-qemu-rtl8139-checksum.patch
 Patch36: xen-qemu-bootmenu.patch
 
 # Patches to modify the default config of xend
@@ -41,24 +29,25 @@
 Patch160: xen-pvfb-01-qemu-fv-machine.patch
 Patch161: xen-pvfb-02-qemu-pv-machine.patch
 Patch162: xen-pvfb-03-xenfb-remove.patch
-Patch163: xen-pvfb-04-compat.patch
-
-Patch164: xen-qemu-vnc-revert-password.patch
-
-Patch165: xen-qemu-iohandler-delete.patch
-Patch166: xen-qemu-vnc-authentication.patch
-Patch167: xen-qemu-vnc-x509-certs.patch
+Patch163: xen-pvfb-04-xenfb-event-handlers.patch
+Patch164: xen-pvfb-05-xenfb-qemu-console.patch
+Patch165: xen-pvfb-06-xenfb-pubpriv-merge.patch
+Patch166: xen-pvfb-07-xenfb-async-startup.patch
+Patch167: xen-pvfb-08-xen-console-qemu.patch
+Patch168: xen-pvfb-09-xend-device-model.patch
+Patch169: xen-pvfb-10-xen-console-ignore.patch
+
+Patch170: xen-qemu-vnc-revert-password.patch
+
+Patch171: xen-qemu-iohandler-delete.patch
+Patch172: xen-qemu-vnc-authentication.patch
+Patch173: xen-qemu-vnc-x509-certs.patch
 
 Patch251: pygrub-manykernels.patch
 
 # Performance fix for listing domains
 Patch280: xen-xs-transactions.patch
 
-# CVE-2007-1321
-Patch600: xen-qemu-ne2000-CVE-2007-1321.patch
-# CVE-2007-4993
-Patch601: pygrub-dont-exec.patch
-
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 BuildRequires: transfig libidn-devel zlib-devel texi2html SDL-devel curl-devel
 BuildRequires: libX11-devel python-devel ghostscript tetex-latex 
@@ -120,28 +109,13 @@
 virtual machines. 
 
 %prep
-%setup -q -n %{name}-%{version}-src
+%setup -q -n %{name}-unstable.hg-%{changeset}
 %patch1 -p1 -b .init
 %patch3 -p1 -b .compile
-%patch6 -p1
+#patch6 -p1
 %patch13 -p1
 %patch18 -p1
-%patch19 -p1
 
-%patch20 -p1
-%patch21 -p1
-%patch25 -p1
-%patch26 -p1
-%patch27 -p1
-%patch28 -p1
-%patch29 -p1
-%patch30 -p1
-
-%patch31 -p1
-%patch32 -p1
-%patch33 -p1
-%patch34 -p1
-%patch35 -p1
 %patch36 -p1
 
 # config patches
@@ -154,24 +128,26 @@
 %patch161 -p1
 %patch162 -p1
 %patch163 -p1
-
-# Remove old VNC password code
 %patch164 -p1
-
-# Add new TLS code
 %patch165 -p1
 %patch166 -p1
 %patch167 -p1
+%patch168 -p1
+%patch169 -p1
+
+# Remove old VNC password code
+#patch170 -p1
+
+# Add new TLS code
+#patch171 -p1
+#patch172 -p1
+#patch173 -p1
 
 # upstream patches
 %patch251 -p1
 
 # performance patch
-%patch280 -p1
-
-# CVE patches
-%patch600 -p1
-%patch601 -p1
+#patch280 -p1
 
 %build
 CFLAGS="$RPM_OPT_FLAGS" %{__make} XENFB_TOOLS=y XEN_PYTHON_NATIVE_INSTALL=1 DESTDIR=%{buildroot} tools docs


--- pygrub-dont-exec.patch DELETED ---


--- xen-3.1.0-dev-native-protocol.patch DELETED ---


--- xen-3.1.0-libxc-native-protocol.patch DELETED ---


--- xen-3.1.0-no-xenapi-docs.patch DELETED ---


--- xen-blktap-error-returns.patch DELETED ---


--- xen-blktap-no-aio-epoll.patch DELETED ---


--- xen-clobber-vif-type.patch DELETED ---


--- xen-console-log.patch DELETED ---


--- xen-hvm-save-paths.patch DELETED ---


--- xen-keyboard.patch DELETED ---


--- xen-pvfb-04-compat.patch DELETED ---


--- xen-qemu-ne2000-CVE-2007-1321.patch DELETED ---


--- xen-qemu-rtl8139-checksum.patch DELETED ---


--- xen-qemu-vnc-delete.patch DELETED ---


--- xen-remove-python-path-check.patch DELETED ---


--- xen-start-fail-cleanup.patch DELETED ---


--- xen-tpm-functions.patch DELETED ---


--- xen-vmxassist-irqs.patch DELETED ---




More information about the fedora-extras-commits mailing list