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

[Xen-devel][PATCH][IOEMU] Dynamic modes support for xenfb (1 of 2)


  • To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Pat Campbell <plc@xxxxxxxxxx>
  • Date: Thu, 13 Mar 2008 13:58:52 -0600
  • Delivery-date: Thu, 13 Mar 2008 13:01:41 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

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.

Please apply to tip of xen-unstable

Signed-off-by: Pat Campbell <plc@xxxxxxxxxx>

diff -r f33328217eee tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Mon Mar 10 22:51:57 2008 +0000
+++ b/tools/ioemu/hw/xenfb.c    Wed Mar 12 06:41:24 2008 -0600
@@ -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 %d 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 f33328217eee tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Mon Mar 10 22:51:57 2008 +0000
+++ b/tools/python/xen/xend/server/vfbif.py     Tue Mar 11 07:05:46 2008 -0600
@@ -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']
 
 class VfbifController(DevController):
diff -r f33328217eee tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Mon Mar 10 22:51:57 2008 +0000
+++ b/tools/python/xen/xm/create.py     Tue Mar 11 17:51:46 2008 -0600
@@ -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?""")
@@ -641,7 +646,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"):
diff -r f33328217eee xen/include/public/io/fbif.h
--- a/xen/include/public/io/fbif.h      Mon Mar 10 22:51:57 2008 +0000
+++ b/xen/include/public/io/fbif.h      Tue Mar 11 07:05:46 2008 -0600
@@ -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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

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