Archive for the ‘spice’ Category

Xspice talk given at FOSDEM 2012

Tuesday, February 28th, 2012

I gave a talk about the hack that is Xspice during the last awesome-if-you-aren’t-distracted-by-a-pending-talk-or-second-guessing-a-given-talk FOSDEM.

Slides, are in multitalk, also in html. Patches for multitalk used.

Things learned:

  • homework should include debunking assumption that the W thing is probably just a fad that is going away.
  • practicing to not talk fast doesn’t always work.
  • spice is not the greatest thing since sliced bread.

More positive lessons learned:

  • Wspice would be more interesting to the X-turning-W crowd, and in general for the future.
  • Perhaps rendering at the server and that’s it for 3D is a good idea.

DRM progress 1

Wednesday, November 30th, 2011


I’m planning on this being the first of many updates on my ongoing work on adding 3D support to Spice. Right now I have a three stage plan and stage one is adding a DRM driver for linux. Our current linux driver is an X one, adding a DRM driver will allow us to use KMS and have an interrupt handler, and later provide direct rendering of course.

I’ve setup a working environment for developing the DRM driver to it’s current state. I hope that when I look back at this post I’ll notice all the things I missed, but in order to do that I need to write them in the first place:

  1. fedora host, with kernel checkout to /home/alon/src/linux
  2. fedora vm, with 9pfs mount pointing to /home/alon/src, with ttyS0 console (should be hvc0 but this failed for some reason). vm setup with password less login (should be autologin, but still multiuser init level since ssh is helpful). vm boot time is also too long – 10 seconds (was 40-50 before I noticed I was using ide instead of virtio, thanks to writing this blog post), turned off one thing I can’t remember, but a lot more to tweak there.
  3. make install once in vm, get /boot/grub2/grub.cfg to boot the new kernel by default, no quiet, and tty=ttyS0 (again – should be hvc0, not sure why it doesn’t work).

Development iteration:

    1. change code, build driver (make drivers/gpu/drm/qxl/qxl.ko)
    2. reboot vm (can be in parallel to 1)
    3. login and modprobe the new modules. actual keyboard: root<enter> . qxl<enter>.
      qxl is a script that does:
      ifup eth0 # didn’t figure out how to set this up – too used to /etc/network/interfaces. RHCE next week 🙂 This starts sshd
      nc 5678 # knock on host side script that does ssh here
      insmod {ttm.ko,qxl.ko}
      on the host I have complementary script.

Most work so far was in figuring out TTM memory management enough to get memory allocated on the PCI BAR 0 for the commands. Initially I also had to figure out kernel debugging and building – building an individual module is much faster then building the whole kernel, and after trying to debug via qemu’s gdbserver (couldn’t find some symbols) gave up for now and am using printk / DRM_INFO’s, and making sure any module I touch (so far just ttm.ko and qxl.ko) is insmod’ed instead of modprobe’d to be sure I get the fresh one (already got bitten by this a few times – this time by just forgetting to build the specific module. inotify eclipse like instant build?). Reread the coding style, last time I read it was for fun, now I actually need to use it.


ifup eth0
iptables -F
echo go | nc 3456
nc -l 3456
# insmod everything to remove the "make modules_install" slow stage
# defaults to 10, doubled for soft lockup thresh, 22 seconds in reality,
# too long
#echo 1 &gt; /proc/sys/kernel/watchdog_thresh
cd $ROOT
insmod drm_kms_helper.ko
insmod ttm/ttm.ko
insmod qxl/qxl.ko



while [ 1 == 1 ]; do
nc -l 3456
#gnome-terminal -e "ssh root@"
#screen ssh root@
xterm -e "ssh root@" &amp;
sleep 1
echo go | nc 3456


while [ 1 == 1 ]; do
echo ====================== $filename ======================
(nc -l 6666 | tee $filename)

Started the practice of having a ~/tmp-bin with snippets that do not deserve to be in ~/bin but are currently useful. do-ssh, nc-6666 and f16-qxl-drm-6666 are there:

vm command line (need to switch to libvirt, this is done by spice-launcher):

x86_64 garlic:linux alon (qxl)$ cat ~/tmp-bin/f16-qxl-drm-6666
f16-qxl-drm --serial socket,host=,port=6666 --qxldebug 1 --guestdebug 1 $*
x86_64 garlic:linux alon (qxl)$ ls -l ~/bin/f16-qxl-drm
lrwxrwxrwx. 1 alon alon 6 Nov 11 16:49 /home/alon/bin/f16-qxl-drm -&gt; spice2</code>

f16-qxl-drm --serial socket,host=,port=6666 --qxldebug 1 --guestdebug 1

x86_64 garlic:linux alon (qxl)$ . ~/tmp-bin/f16-qxl-drm-6666 --print-commandline-only

/home/alon/spice/upstream/bin/qemu-system-x86_64 -chardev stdio,id=muxstdio,mux=on -mon chardev=muxstdio,mode=readline -vga qxl -drive file=/var/lib/libvirt/images/F16-qxl-drm.img,cache=unsafe,if=virtio,readonly=off -enable-kvm -L /home/alon/spice/upstream/share/qemu -m 1024 -cpu host -spice disable-ticketing,port=10006 -chardev socket,id=qmpmon,host=,port=20006,server,nowait,ipv4 -mon chardev=qmpmon,mode=control -snapshot -no-shutdown -global qxl-vga.guestdebug=1 -global qxl-vga.debug=1 -usb -device virtio-serial,multifunction=on -chardev spicevmc,name=vdagent,id=vdagent -device virtserialport,chardev=vdagent,name=com.redhat.spice.0 -chardev socket,server,path=/tmp/tmpCYCBQ1/virtconsole,nowait,id=virtconsole -device virtconsole,chardev=virtconsole,name=org.alon.console -netdev tap,id=hostnet0,ifname=tap0,script=no,downscript=no -device virtio-net-pci,netdev=hostnet0,id=net0 -chardev socket,host=,port=6666,id=serial -serial chardev:serial -virtfs local,path=/home/alon/src/,mount_tag=src,security_model=mapped,writeout=immediate

qxl DRM driver after insmod and ls

Announcing Xspice

Saturday, July 23rd, 2011

An X server and a Spice server. Yes, the idea that X is not a good enough networking protocol for WAN has been investigated already many times. Why yet another one? In the end because it seemed like a cool thing to do. And it’s easier to test the qxl driver without the guest/host split.

What I think would be really useful is to be able to use it side by side with an existing X server, i.e. having two drivers both receiving all X operations (vnc doesn’t have this problem because it isn’t implemented as a driver). Sadly this is not yet doable. But happily it is being worked on, mainly due to the relatively-new dual GPU laptops (I don’t know the ETA. I think it’s called sharding, or at least is related to that).

So right now, if you are tired of Xvnc, or Xrdp, or NX, or just want to compare and tell us again that we need to improve SPICE (*) (**)

The source release is one and the same as the xorg qxl driver: xspice source aka xf86-video-qxl-0.0.16.tar.bz2 (see spice-space for the latest)

Building requires the same dependencies as any X video driver, plus spice-server. See README.xspice for details.

XSpice installation as a normal user is a bit of a hassle, since it requires one to build their own X server. If you want to do it, see README.xspice for details. On the other hand, installing as root requires just three things:
* -> with all other xorg video drivers.
* xspice -> /usr/bin
* spiceqxl.xorg.conf.example -> /etc/X11/spiceqxl.xorg.conf (this is the default config file xspice looks for, you can change that with –config)

sudo make install will do the first two for you (assuming you did ./configure –prefix=/usr). The third you’ll have to do by hand.

To summarize, this should get you going:

./configure --prefix=/usr
sudo make install
sudo cp examples/spiceqxl.xorg.conf.example /etc/X11/spiceqxl.xorg.conf

Alternatively, somewhere in the near future I hope this will be enough

yum install xspice

Running is easier:

xspice --disable-ticketing --port 5900 --tls-port 0 :1.0 2>&1 > /dev/null &
spicy -h localhost -p 5900
DISPLAY=:1.0 favorite-window-manager-that-doesnt-need-dbus # i.e. icewm

Note: you don’t have to redirect, there is just a lot of spew, so you might want to run spicec/spicy in another terminal.

Note 2: that –tls-port 0 is weird, right? bug. But I already used one paper bag (0.0.15 never saw daylight), so I’ll just leave this for the next release.

Most of the options familiar from qemu’s -spice option are there, with some exceptions: no sound yet (do a pulseaudio proxy? not sure), no agent implementation (probably a good idea to reuse spice-vdagent for this), and no per channel secure/unsecure port selection (just laziness). The internal mechanism for passing those options is a bit of a hack – XSPICE_* environment variables are set by xspice and read by

I hope someone finds this useful, if you do, do let me know!

*) we know! but thanks for telling us! no, really! 🙂
**) Compared to VNC I don’t think there is a question that Spice is a better (***) protocol. Compared to the rest, it has it’s shortcomings. But it will be 😉
***) ok, I can’t write “better” without saying that it is a function of the optimization criteria. But you know what I mean.

p.s. also, we already had spice-x, so xspice was inevitable. Next, ispice!

tracking release fixed bugs (or, which BZ are missing from spice 0.8.2 NEWS file)

Friday, July 22nd, 2011

Our NEWS file looks like:

spice new-version
* bla
* fixed 666666, 777777

spice old version

To gurantee all the bz’s are in there the next time we need to track which bz’s were fixed in some git branch between the last and new release. Assuming they are tagged, and commits include the bz in the message (the last is hard to verify – could go look at bugzilla for real), this becomes:

git log 0.8.1..0.8.2 | grep -o -E "#[0-9]{6}\>" | tr -d "#"

If you happened to already have done a release, and you want to see how screwed up the NEWS file is, this works:

((git log 0.8.1..0.8.2 | grep -o -E "#[0-9]{6}\>" | tr -d "#" | sort -u); (git show 0.8:NEWS | gawk '/0.8.2/ { a=1; } /0.8.1/ { a=0; } { if (a) print; }' | grep -o -E "[0-9]{6}" | sort -u);) | sort | uniq -u

And if you also want to paste that into a blog post in html, do:

_last_command_output_ | sort | uniq -u | sed -e 's|\(.*\)|<a href="\1" title="\1">\1</a>|'

So let posterity know that the following BZs are also fixed in spice 0.8.2:


There are at least two ways to render a cursor (or ie9 rendering bug)

Thursday, April 7th, 2011

This post, and anything else tagged spice, is about the spice project development that I’m a part of, ever since starting to work for Red Hat last year.

So the first post will be just about a recent fix to a rendering problem (tl;dr version): ie9 (Internet Explorer 9) rendering. A glaring bug was discovered recently – we didn’t render ie9 pages correctly. After a lot of investigation this turned out to be a caching issue – we were using the same key to cache two different bitmap copy operations (this is the driver cache, unrelated to the server/client cache). The DrvCopyBits operation has two parameters, a SURFOBJ containing the bitmap, and a XLATEOBJ containing a color translation object. We ignored the later in some cases. Basically rendering of a blinking cursor (and any text) is done differently in ie9 as compared to a login blinking cursor:

ie9 renders a blinking cursor by sending the same SURFOBJ (iUniq is constant) with two alternating pallettes.

login (and ff4) draw a blinkinging cursor by using DrvBitBlt with a fill operation with mask 0xff (I assume xor, although this didn’t break so I didn’t take a too close look).

To be more precise this is the view from the device driver that is not implementing any DirectDraw, just GDI. So this could be actually an implementation detail of some dll being used by either of those browsers.

These are the logs for the events:

ie9, uses DrvCopyBits with the same SURFOBJ and alternating XLATEOBJ’s:

125684577551 qxldd: DrvCopyBits [0,296191,(15,16,130,146),3,0,(15,16,130,146)]
125684662828 qxldd: _BitBlt
125684693209 qxldd: __DrvBitBlt
125684725824 qxldd: DoCopy
125684760256 qxldd: GetDrawable 0x91f44d70
125684785190 qxldd: SetClip
125684808936 qxldd: SetClip: QXL_CLIP_TYPE_NONE
125684833241 qxldd: GetBitmap
125684856218 qxldd: QXLGetBitmap
125684885552 qxldd: QXLGetBitmap: iUniq=123d DONTCACHE=0 w=1 h=16 cx=1024 cy=674 hsurf=330507e4 ctiUniq=2263 XO_TABLE=0 format=6
125686471440 qxldd: GetCacheImage: ImageKeyPut 231944847
125686542120 qxldd: GetCacheImage: ImageCacheGetByKey 231944847 hits 8
125686567542 qxldd: QXLGetBitmap: cached image found 231944847
125686589891 qxldd: AddRes
125686610494 qxldd: AddRes: done
125686634939 qxldd: WaitForCmdRing: 0xffb83018
125686657847 qxldd: DoCopy: done
126216044861 qxldd: DrvCopyBits [0,296191,(15,16,130,146),3,0,(15,16,130,146)]
126216155001 qxldd: _BitBlt
126216198721 qxldd: __DrvBitBlt
126216264443 qxldd: DoCopy
126216321015 qxldd: GetDrawable 0x92086190
126216365434 qxldd: SetClip
126216406919 qxldd: SetClip: QXL_CLIP_TYPE_NONE
126216456437 qxldd: GetBitmap
126216499180 qxldd: QXLGetBitmap
126216553237 qxldd: QXLGetBitmap: iUniq=123d DONTCACHE=0 w=1 h=16 cx=1024 cy=674 hsurf=330507e4 ctiUniq=2264 XO_TABLE=0 format=6
126219653568 qxldd: GetCacheImage: ImageKeyPut 707842221
126219750019 qxldd: GetCacheImage: ImageCacheGetByKey 707842221 hits 8
126219808546 qxldd: QXLGetBitmap: cached image found 707842221
126220005499 qxldd: AddRes
126220069404 qxldd: AddRes: done
126220184642 qxldd: WaitForCmdRing: 0xffb83018

login cursor – using a fill DrvBitBlt (xor probably – the turn on and turn off operations are identical):

59327727656 qxldd: DrvBitBlt [-1,4294967295,(406,407,499,514),3,0,(406,407,499,514)]
59327845688 qxldd: _BitBlt
59327969167 qxldd: __DrvBitBlt
59328036913 qxldd: DoFill
59328186375 qxldd: GetDrawable 0x91235030
59328263480 qxldd: SetClip
59328360489 qxldd: SetClip: QXL_CLIP_TYPE_NONE
59328455334 qxldd: QXLGetBrush
59328550877 qxldd: QXLGetBrush: color 0xffffff
59328644953 qxldd: QXLGetBrush: done
59328741544 qxldd: WaitForCmdRing: 0xffb83018
59328837925 qxldd: DrvBitBlt: done
59827733713 qxldd: DrvBitBlt [-1,4294967295,(406,407,499,514),3,0,(406,407,499,514)]
59827853002 qxldd: _BitBlt
59827921377 qxldd: __DrvBitBlt
59827982837 qxldd: DoFill
59828117910 qxldd: GetDrawable 0x91233f90
59828291676 qxldd: SetClip
59828366476 qxldd: SetClip: QXL_CLIP_TYPE_NONE
59828461111 qxldd: QXLGetBrush
59828564826 qxldd: QXLGetBrush: color 0xffffff
59828664000 qxldd: QXLGetBrush: done
59828736566 qxldd: WaitForCmdRing: 0xffb83018
59828818839 qxldd: DrvBitBlt: done