xen/xen-fbback-resize.patch

156 lines
6.2 KiB
Diff

Index: xen-3.2-testing/tools/ioemu/hw/xenfb.c
===================================================================
--- xen-3.2-testing.orig/tools/ioemu/hw/xenfb.c
+++ xen-3.2-testing/tools/ioemu/hw/xenfb.c
@@ -510,6 +510,12 @@ static void xenfb_on_fb_event(struct xen
}
xenfb_guest_copy(xenfb, x, y, w, h);
break;
+ case XENFB_TYPE_RESIZE:
+ xenfb->width = event->resize.width;
+ xenfb->height = event->resize.height;
+ xenfb->row_stride = event->resize.stride;
+ dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
+ break;
}
}
mb(); /* ensure we're done with ring contents */
@@ -672,6 +678,7 @@ static void xenfb_dispatch_store(void *o
static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) {
struct xenfb_page *fb_page;
int val;
+ int videoram;
if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update",
"%d", &val) < 0)
@@ -686,19 +693,34 @@ static int xenfb_read_frontend_fb_config
xenfb->protocol[0] = '\0';
xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1");
- /* TODO check for permitted ranges */
+ if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d", &videoram) < 0)
+ videoram = 0;
+ videoram = videoram * 1024 * 1024;
+
fb_page = xenfb->fb.page;
xenfb->depth = fb_page->depth;
xenfb->width = fb_page->width;
xenfb->height = fb_page->height;
- /* TODO check for consistency with the above */
xenfb->fb_len = fb_page->mem_length;
xenfb->row_stride = fb_page->line_length;
+ /* Protect against hostile frontend, limit fb_len to configured */
+ if (videoram && xenfb->fb_len > videoram) {
+ xenfb->fb_len = videoram;
+ if (xenfb->row_stride * xenfb->height > xenfb->fb_len)
+ xenfb->height = xenfb->fb_len / xenfb->row_stride;
+ }
fprintf(stderr, "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;
+ /* Indicate we have the frame buffer resize feature */
+ xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "feature-resize", "1");
+
+ /* Tell kbd the screen res */
+ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "width", "%d", xenfb->width);
+ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "height", "%d", xenfb->height);
+
if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
return -1;
if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
Index: xen-3.2-testing/xen/include/public/io/fbif.h
===================================================================
--- xen-3.2-testing.orig/xen/include/public/io/fbif.h
+++ xen-3.2-testing/xen/include/public/io/fbif.h
@@ -50,12 +50,28 @@ struct xenfb_update
int32_t height; /* rect height */
};
+/*
+ * Framebuffer resize notification event
+ * Capable backend sets feature-resize in xenstore.
+ */
+#define XENFB_TYPE_RESIZE 3
+
+struct xenfb_resize
+{
+ uint8_t type; /* XENFB_TYPE_RESIZE */
+ int32_t width; /* width in pixels */
+ int32_t height; /* height in pixels */
+ int32_t stride; /* stride in bytes */
+ int32_t depth; /* depth in bits */
+};
+
#define XENFB_OUT_EVENT_SIZE 40
union xenfb_out_event
{
uint8_t type;
struct xenfb_update update;
+ struct xenfb_resize resize;
char pad[XENFB_OUT_EVENT_SIZE];
};
@@ -109,15 +125,17 @@ struct xenfb_page
* Each directory page holds PAGE_SIZE / sizeof(*pd)
* framebuffer pages, and can thus map up to PAGE_SIZE *
* PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
- * sizeof(unsigned long) == 4, that's 4 Megs. Two directory
- * pages should be enough for a while.
+ * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2 Megs
+ * 64 bit. 256 directories give enough room for a 512 Meg
+ * framebuffer with a max resolution of 12,800x10,240. Should
+ * be enough for a while with room leftover for expansion.
*/
- unsigned long pd[2];
+ unsigned long pd[256];
};
/*
- * Wart: xenkbd needs to know resolution. Put it here until a better
- * solution is found, but don't leak it to the backend.
+ * Wart: xenkbd needs to know default resolution. Put it here until a
+ * better solution is found, but don't leak it to the backend.
*/
#ifdef __KERNEL__
#define XENFB_WIDTH 800
Index: xen-3.2-testing/tools/python/xen/xend/server/vfbif.py
===================================================================
--- xen-3.2-testing.orig/tools/python/xen/xend/server/vfbif.py
+++ xen-3.2-testing/tools/python/xen/xend/server/vfbif.py
@@ -6,7 +6,7 @@ import xen.xend
import os
CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
- 'display', 'xauthority', 'keymap',
+ 'videoram', 'display', 'xauthority', 'keymap',
'uuid', 'location', 'protocol']
class VfbifController(DevController):
Index: xen-3.2-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-3.2-testing.orig/tools/python/xen/xm/create.py
+++ xen-3.2-testing/tools/python/xen/xm/create.py
@@ -496,6 +496,10 @@ gopts.var('vncunused', val='',
use="""Try to find an unused port for the VNC server.
Only valid when vnc=1.""")
+gopts.var('videoram', val='',
+ fn=set_value, default=None,
+ use="""Amount of videoram PV guest can allocate for frame buffer.""")
+
gopts.var('sdl', val='',
fn=set_value, default=None,
use="""Should the device model use SDL?""")
@@ -631,7 +635,7 @@ def configure_vfbs(config_devs, vals):
d['type'] = 'sdl'
for (k,v) in d.iteritems():
if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
- 'xauthority', 'type', 'vncpasswd' ]:
+ 'videoram', 'xauthority', 'type', 'vncpasswd' ]:
err("configuration option %s unknown to vfbs" % k)
config.append([k,v])
if not d.has_key("keymap"):