WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel][PATCH][IOEMU] Dynamic modes support for PV xenfb (2 of 2

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [Xen-devel][PATCH][IOEMU] Dynamic modes support for PV xenfb (2 of 2)
From: "Pat Campbell" <plc@xxxxxxxxxx>
Date: Fri, 11 Jan 2008 08:15:22 -0700
Delivery-date: Fri, 11 Jan 2008 07:15:54 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
>>> On Thu, Jan 10, 2008 at  3:18 AM, in message
<87ejcqhtku.fsf@xxxxxxxxxxxxxxxxx>, Markus Armbruster <armbru@xxxxxxxxxx>
wrote: 
> "Pat Campbell" <plc@xxxxxxxxxx> writes:
> 
>> Attached patch adds multiple 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 2491691e3e69 tools/ioemu/hw/xenfb.c
>> ---      a/tools/ioemu/hw/xenfb.c    Sat Dec 29 17:57:47 2007 +0000
>> +++ b/tools/ioemu/hw/xenfb.c Mon Jan 07 12:38:25 2008 -     0700
>> @@ -     53,6 +53,7 @@ struct xenfb {
>>      int abs_pointer_wanted; /* Whether guest supports absolute pointer */
>>      int button_state;       /* Last seen pointer button state */
>>      char protocol[64];      /* frontend protocol */
>> +    int fixevdev_abs;       /* Descale abs pos so evdev scales properly */
>>  };
>>  
>>  /* Functions for frontend/backend state machine*/
>> @@ -     233,6 +234,7 @@ struct xenfb *xenfb_new(int domid, Displ
>>      struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
>>      int serrno;
>>      int i;
>> +    int val;
>>  
>>      if (xenfb == NULL)
>>              return NULL;
>> @@ -     264,6 +266,19 @@ struct xenfb *xenfb_new(int domid, Displ
>>      xenfb-     >ds = ds;
>>      xenfb_device_set_domain(&xenfb-     >fb, domid);
>>      xenfb_device_set_domain(&xenfb-     >kbd, domid);
>> +
>> +    /* See if we need to fix abs ptr for guests evdev */
>> +    if (xenfb_xs_scanf1(xenfb-     >xsh, xenfb-     >fb.nodename, "vnc-     
>> fixevdev-     abs",
>> +                        "%d", &val) < 0)
>> +            val = 0;
>> +    xenfb-     >fixevdev_abs = val;
>> +
>> +    /* Indicate we have the frame buffer resize feature if resizable 
>> allowed */
>> +    if (xenfb_xs_scanf1(xenfb-     >xsh, xenfb-     >fb.nodename, 
>> "vncresizable-     pvfb",
>> +                        "%d", &val) < 0)
>> +            val = 0;
>> +    if (val)
>> +            xenfb_xs_printf(xenfb-     >xsh, xenfb-     >fb.nodename, 
>> "xenfb-     feature-     resize", "1");
> 
> You pass configuration parameters vnc-     fixevdev-     abs and
> vncresizable-     pvfb through xenstore.  The others are on the qemu
> command line.  I'm not fond of configuring qemu through xenstore, but
> I guess it's the simplest solution here.

Dan suggested I use kernel parameters for these instead of xenstore.
Going to remove these and go that route.  Also solves the init/connect
problem you pointed out below.

> 
> The name xenfb-     feature-     resize doesn't match existing names
> request-     update, feature-     update, request-     abs-     pointer,
> feature-     abs-     pointer.  Suggest to call it feature-     resize.

Ok

> 
> How's the transmission of feature-     resize synchronized?  The backend
> writes it right when it initializes.  The frontend reads it on device
> probe.  What ensures that the backend completes initialization before
> the frontend starts probing?

I guess it wasn't.  

feature-resize is now set in state 'Connected' like request-update.   kernel 
parameter 'xenfb.dynamicModes' is tested in the probe function to determine 
framebuffer memory allocation size.

> 
> Have a look at the device initialization event diagram at
> http://wiki.xensource.com/xenwiki/XenSplitDrivers:
> 
>                   Xenbus                       Xenbus
>     Hotplug       Backend                     Frontend
>     -------            -------                          --------
> 
>                 Initialising                Initialising
>                      |                           |
>        |<---     start----     +                           |
>        |             |                           |
>        |          InitWait                       |
>        |             |                         write
>        |             |                         ring/
>      write           |                        channel
>     physdets--------     >|                        details
>                      |                           |
>                      |<---------------------     Initialised
>                      |                           |
>                    write                         |
>                   physdets                       |
>                      |                           |
>                  Connected----------------------     >|
>                      |                           |
>                      |                       Connected
>                      |                           |
> 
> For xenfb, this becomes:
> 
>                    xenfb                       xenfb
>                   Backend                     Frontend
>                   -------                          --------
> 
>                 Initialising                Initialising
>                      |                           |
>                      |                           |
>                      |                           |
>                   InitWait                       |
>                      |                         write
>                      |                      page-     ref, event-     channel
>                      |                      protocol, feature-     update
>                      |                           |
>                      |<---------------------     Initialised
>                      |                           |
>                    read                          |
>           page-     ref, event-     channel                |
>           protocol, feature-     update               |
>                    write                         |
>                request-     update                    |
>                      |                           |
>                  Connected----------------------     >|
>                      |                           |
>                      |                         read
>                      |                      request-     update
>                      |                           |
>                      |                       Connected
>                      |                           |
> 
> Your patches add:
> 
>                    xenfb                       xenfb
>                   Backend                     Frontend
>                   -------                          --------
> 
>                    write                       read
>                 feature-     resize              feature-     resize
>                      |                           |
>                 Initialising                Initialising
>                      |                           |
>                     ...                         ...
> 
> Here's a design that would fit more naturally into the protocol: make
> the frontend advertise feature-     resize, and the backend request-     
> resize,
> just like feature-     update / request-     update.
> 
> The trouble with that is that the frontend knows doesn't know whether
> to do resize until it goes to state Connected.  Complicates
> framebuffer allocation.  It's allocated in xenfb_probe() for a reason:
> it's easy to handle failed allocations there, just fail the probe.
> 
> Relatively easy way out: allocate the full framebuffer in probe,
> attempt to downsize it when going to Connected.
> 
> By the way, the feature negotiation only covers whether the frontend
> is permitted to resize, not acceptable resolutions.

True.  Acceptable resolutions are what fits within a 5MB framebuffer
and has a width no greater than 1280.

> 
> What if the frontend resizes to a resolution the backend can't accept?
> The backend has no way to tell the frontend not to do that.  Would we
> end up with a defunct display and no way for the user to fix it?

I don't think this is a possible issue. Frontend code limits the size of
the frame buffer to 5MB with a max horizontal scanline length of
1280.  The backend VNC server should be able to handle that without
any problems.

> 
> What happens when a malicious frontend resizes to a resolution that
> makes pd[] extend beyond the end of the shared page?  Nothing new
> really, the current backend has the same problem with the initial
> resolution, I think.

Can't do that either.  Maximum frame buffer size of 5MB fits within
the 3 page descriptors.    

> 
>>  
>>      fprintf(stderr, "FB: Waiting for KBD backend creation\n");
>>      xenfb_wait_for_backend(&xenfb-     >kbd, xenfb_backend_created_kbd);
>> @@ -     510,6 +525,11 @@ 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;
>> +                    dpy_resize(xenfb-     >ds, xenfb-     >width, xenfb-    
>>  >height);
>> +                    break;
>>              }
>>      }
>>      mb();                   /* ensure we're done with ring contents */
>> @@ -     605,11 +625,22 @@ static int xenfb_send_motion(struct xenf
>>      return xenfb_kbd_event(xenfb, &event);
>>  }
>>  
>> +/* Descale abs pos for older evdev_drv without AbsoluteScreen option */
>> +static inline int xenfb_descale_for_evdev(float fb_width, float 
> screen_width, float pos)
> 
> This is used both for width and height, despite the parameter names.
> Suggest something like limit and max_limit.
> 
>> +{
>> +    return(((fb_width/screen_width) * pos) + 0.5);
> 
> Style nitpick:
> 
>       return (fb_width/screen_width) * pos + 0.5;
> 
>> +}
>> +

I have removed the whole scale code.  I have arbitarily decided that if
a VM wishes to use dynamic modes and absolute mouse positioning it 
should have an updated X evdev driver like what is in Fedora8 or
OpenSuSE 10.3

virt-manager with mouse grab works as good as it alway has.

>>  /* Send an absolute mouse movement event */
>>  static int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y, 
> int abs_z)
>>  {
>>      union xenkbd_in_event event;
>>  
>> +    if (xenfb-     >fixevdev_abs) {
>> +            struct xenfb_page *page = xenfb-     >fb.page;
>> +            abs_x = xenfb_descale_for_evdev(page-     >width, xenfb-     
>> >width, abs_x);
>> +            abs_y = xenfb_descale_for_evdev(page-     >height, xenfb-     
>> >height, abs_y);
>> +    }
>>      memset(&event, 0, XENKBD_IN_EVENT_SIZE);
>>      event.type = XENKBD_TYPE_POS;
>>      event.pos.abs_x = abs_x;
>> diff -     r 2491691e3e69 tools/python/xen/xend/server/vfbif.py
>> ---      a/tools/python/xen/xend/server/vfbif.py     Sat Dec 29 17:57:47 
>> 2007 +0000
>> +++ b/tools/python/xen/xend/server/vfbif.py  Sun Jan 06 12:35:21 2008 -     
>> 0700
>> @@ -     7,7 +7,8 @@ import os
>>  
>>  CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 
> 'vncunused',
>>                    'display', 'xauthority', 'keymap',
>> -                       'uuid', 'location', 'protocol']
>> +                  'uuid', 'location', 'protocol', 
>> +                  'vncresizable-     pvfb', 'vnc-     fixevdev-     abs' ]
>>  
>>  class VfbifController(DevController):
>>      """Virtual frame buffer controller. Handles all vfb devices for a 
> domain.
>> diff -     r 2491691e3e69 tools/python/xen/xm/create.py
>> ---      a/tools/python/xen/xm/create.py     Sat Dec 29 17:57:47 2007 +0000
>> +++ b/tools/python/xen/xm/create.py  Sun Jan 06 12:34:38 2008 -     0700
>> @@ -     485,6 +485,14 @@ gopts.var('vnclisten', val='',
>>            fn=set_value, default=None,
>>            use="""Address for VNC server to listen on.""")
>>  
>> +gopts.var('vncresizable-     pvfb', val='no|yes',
>> +          fn=set_bool, default=0,
>> +          use="""Allow resizable VNC PVFB if supported.""")
>> +
>> +gopts.var('vnc-     fixevdev-     abs', val='no|yes',
>> +          fn=set_bool, default=0,
>> +          use="""Correct resizable abs pointer positioning for evdev.""")
>> +
>>  gopts.var('vncunused', val='',
>>            fn=set_bool, default=1,
>>            use="""Try to find an unused port for the VNC server.
>> @@ -     620,7 +628,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' ]:
>> +                          'xauthority', 'type', 'vncpasswd',
>> +                          'vncresizable-     pvfb', 'vnc-     fixevdev-     
>> abs' ]:
>>                  err("configuration option %s unknown to vfbs" % k)
>>              config.append([k,v])
>>          if not d.has_key("keymap"):
>> diff -     r 2491691e3e69 xen/include/public/io/fbif.h
>> ---      a/xen/include/public/io/fbif.h      Sat Dec 29 17:57:47 2007 +0000
>> +++ b/xen/include/public/io/fbif.h   Sat Jan 05 11:10:07 2008 -     0700
>> @@ -     50,12 +50,26 @@ 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;   /* xres */
> 
> Commenting one snappy-     short identifier with another one seems rather
> pointless to me :)
> 
> If you insist on a comment, what about: x-     resolution in pixels.

Ok

> 
>> +    int32_t height;  /* yres */
>> +};
>> +
>>  #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];
>>  };
>>  
>> @@ -     111,8 +125,12 @@ struct xenfb_page
>>       * 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.
>> +     *
>> +     * Increased to 3 to support 1280x1024 resolution on a 64bit system
>> +     *  (1280*1024*4)/PAGE_SIZE = 1280 pages required
>> +     *  PAGE_SIZE/64bit long = 512 pages per page directory
> 
> Please update the comment instead of appending to it.
> 
>>       */
>> -         unsigned long pd[2];
>> +    unsigned long pd[3];
> 
> Extending pd[] is safe, because:
> 
> * Current backends compute the length of pd[] from the size of the
>   framebuffer.  However, when protocol is not set, they rely on pd[1]
>   == 0 to make 32-     on-     64 work.
> 
> * Old frontends don't set the protocol and use only pd[0].  They set
>   pd[1] to 0.
> 
> * Current frontends set the protocol and use pd[0..1].  Unused parts
>   of the shared page are 0, including pd[2].
> 

> * Your frontend additionally uses pd[2], but only when the backend
>   agreed to it.
>

This has changed slightly with the use of dynamicMode module parameter.
Now using pd[2] if the vm was configured for it.

 
>>  };
>>  
>>  /*

Thanks for your feedback

Will send updated patch when I have incorporated your suggestions

Pat





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

<Prev in Thread] Current Thread [Next in Thread>
  • Re: [Xen-devel][PATCH][IOEMU] Dynamic modes support for PV xenfb (2 of 2), Pat Campbell <=