[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xenfb: Dynamic modes support.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1206522556 0
# Node ID d97e61001d81783d7175b59b8758733573244691
# Parent  f5e6cccfdda5537876d6fc2b87ea1124d6043fc8
xenfb: Dynamic modes support.

Attached patch adds dynamic frame buffer size support to the xenfb PV
backend QEMU xenfb.  Backend sets feature-resize and handles the
resize frame buffer event.

Corresponding frontend LINUX patch is required for functionality but
this patch is not dependent on it, preserving backwards
compatibility.

Signed-off-by: Pat Campbell <plc@xxxxxxxxxx>
---
 tools/ioemu/hw/xenfb.c                |   31 +++++++++++++++++++++++++++++++
 tools/python/xen/xend/server/vfbif.py |    2 +-
 tools/python/xen/xm/create.py         |    8 +++++++-
 xen/include/public/io/fbif.h          |   28 +++++++++++++++++++++++-----
 4 files changed, 62 insertions(+), 7 deletions(-)

diff -r f5e6cccfdda5 -r d97e61001d81 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Tue Mar 25 18:02:00 2008 +0000
+++ b/tools/ioemu/hw/xenfb.c    Wed Mar 26 09:09:16 2008 +0000
@@ -516,6 +516,16 @@ 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_colourdepth(xenfb->ds, xenfb->depth);
+                       dpy_resize(xenfb->ds, xenfb->width, xenfb->height, 
xenfb->row_stride);
+                       if (xenfb->ds->shared_buf)
+                               dpy_setdata(xenfb->ds, xenfb->pixels);
+                       xenfb_invalidate(xenfb);
+                       break;
                }
        }
        xen_mb();               /* ensure we're done with ring contents */
@@ -680,6 +690,7 @@ static int xenfb_read_frontend_fb_config
 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)
@@ -702,10 +713,30 @@ static int xenfb_read_frontend_fb_config
         /* 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 max allowed */
+        if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d",
+                            &videoram) < 0)
+                videoram = 0;
+        videoram = videoram * 1024 * 1024;
+        if (videoram && xenfb->fb_len > videoram) {
+                fprintf(stderr, "Framebuffer requested length of %zd exceeded 
allowed %d\n",
+                        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 pointer the screen geometry */
+        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;
diff -r f5e6cccfdda5 -r d97e61001d81 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Tue Mar 25 18:02:00 2008 +0000
+++ b/tools/python/xen/xend/server/vfbif.py     Wed Mar 26 09:09:16 2008 +0000
@@ -6,7 +6,7 @@ import os
 import os
 
 CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
-                  'display', 'xauthority', 'keymap',
+                  'videoram', 'display', 'xauthority', 'keymap',
                   'uuid', 'location', 'protocol', 'opengl']
 
 class VfbifController(DevController):
diff -r f5e6cccfdda5 -r d97e61001d81 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Mar 25 18:02:00 2008 +0000
+++ b/tools/python/xen/xm/create.py     Wed Mar 26 09:09:16 2008 +0000
@@ -500,6 +500,11 @@ 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="""Maximum 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?""")
@@ -645,7 +650,8 @@ 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', 'opengl' ]:
+                          'videoram', 'xauthority', 'type', 'vncpasswd',
+                          'opengl' ]:
                 err("configuration option %s unknown to vfbs" % k)
             config.append([k,v])
         if not d.has_key("keymap"):
diff -r f5e6cccfdda5 -r d97e61001d81 xen/include/public/io/fbif.h
--- a/xen/include/public/io/fbif.h      Tue Mar 25 18:02:00 2008 +0000
+++ b/xen/include/public/io/fbif.h      Wed Mar 26 09:09:16 2008 +0000
@@ -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

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.