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

[Xen-devel] Prototype to use QEMU for PV guest framebuffer

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] Prototype to use QEMU for PV guest framebuffer
From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>
Date: Fri, 27 Jul 2007 21:28:44 +0100
Delivery-date: Fri, 27 Jul 2007 13:26:30 -0700
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>
Reply-to: "Daniel P. Berrange" <berrange@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.1i
As many of us are all too painfully aware we have completely different VNC 
server implementations for paravirt vs fullyvirt Xen guests. The former 
based on libvncserver, the latter integrated into QEMU. There are many new
and interesting ideas being tried out in the VNC server space in particular
wrt to virtualization and having to implement them all twice is not very
desirable.  Also libvncserver code is terrible - many bad thread race 
conditions that are near impossible to diagnose, let alone solve :-(

At the summit there were a couple of suggestions, either taking the VNC
server code from QEMU and splicing it into the xenfb daemon. Another was
to take the QEMU VNC code and put it into a library that can be used by
both QEMU & xenfb. Neither of those is a particularly appealing prospect.

Then Anthony Liguori suggested a 3rd approach, which was to add a new QEMU
machine type to the x86 target, and simply disable all the emulated hardwre
and just make use of QEMU infrastructure for the VNC server, select() event 
loop and display state.

This sounded very intriguing so I did a little experimentation today doing
exactly that. First of all I've copied  tools/xenfb/xenfb.c into the 
qemu/hw/xenfb.c file. Next I added a qemu/hw/xen.c file to provide the 
implementation of the QEMU machine type - called 'xenpv'. 

All the interesting code (all 100 lines of it) is in hw/xen.c in the
xen_init_pv method - which is called when using the '-M xenpv' command
line arg. 

The first thing this does is get the domain ID - to avoid touching QEMU's
command line args, I just use an environ variable XEN_DOMID to pass this
in.

The main_loop() in qemu/vl.c assumes there is always one CPU created in
the VM, but for our purposes we're not doing any CPU emulation merely 
using the event loop/display state. So to workaround this assumption I
create a single CPUState  *  instance, and permanently disable it by 
setting 'cpu->hflags = HF_HALTED_MASK'. Seems to do the job.

Next, up we attach to the guest PVFB frontend - just using the existing code
for this - qemu/hw/xenfb.c (formerly xen-unstable/tools/xenfb/xenfb.c).

Now we register a QEMU graphical console, a mouse event receiver, a
keyboard event receiver, and register the xenstored and event channel
file handles with QEMU's event loop.

Finally, initialize QEMU's display state to match the PVFB framebuffer
config (ie 800x600x32).

Pushing mouse & keyboard events through from QEMU to PVFB frontend is
trivial. The only bit I'm unhappy about is that QEMU can't access the
guest framebuffer directly. The DisplayState * struct has its own copy
of the framebuffer - allocated by the VNC or SDL impls in QEMU - and
so whenever the guest framebuffer changes, we have to memcpy() the data
from the guest into the QEMU framebuffer. Still, this is no worse than
what the HVM guests already do. Its probably not too hard to change the
QEMU impl of VNC / SDL to use the guest framebuffer directly if we did
a little re-factoring. I wanted to keep it simple for now & not change
any of the upstream QEMU code.

This attached patch is against the current upstream QEMU  CVS code, not Xen's 
ioemu, since I wanted to work against pristine QEMU codebase & avoid any
potential wierd iteractions with HVM stuff added to ioemu. The diff is

$ diffstat ~/xen-qemu-pvfb-machine.patch
 Makefile.target |    3 
 b/hw/xen.c      |  113 +++++++
 b/hw/xenfb.c    |  822 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 b/hw/xenfb.h    |   35 ++
 vl.c            |    1 
 vl.h            |    3 
 6 files changed, 976 insertions(+), 1 deletion(-)

So, you can see a mere 113 lines of new code to make this work - xenfb.c 
is the existnig tools/xenfb/xenfb.c file with minor tweaks. And we get to
delete 20,000 lines of terrible libvncserver code !

Apply the patch to QEMU CVS checkout, configure to build an x86 target,
and once done you can run with 

  # XEN_DOMID=31 ./i386-softmmu/qemu -M xenpv -hda /dev/null -vnc :0

The -hda flag is just to keep QEMU's command line parse quiet - it wants
at least one disk.

You can also run in SDL mode

  # XEN_DOMID=31 ./i386-softmmu/qemu -M xenpv -hda /dev/null

Thoughts... ?  If there's positive feedback on this approach I'll develop
the patch further & properly integrate with XenD & domain create/teardown.

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

Attachment: xen-qemu-pvfb-machine.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>