Compiling kvm Under Ubuntu Edgy i386

kvm is QEMU with support for the VT Vanderpool or Virtualization Technology. This means you can now run QEMU on CPUs that have the VT instructions and you get a super quick emulated environment. Yay!

Previously to get spritely performance out of QEMU you needed the closed-source KQEMU kernel module. Now you don’t. This interests me because I use QEMU quite heavily with my little screencasting project with Ubuntu-UK. Having a totally Free (GPL) and easy to use method for running virtual machines is essential. Of course there’s Xen but kvm is a great drop-in solution with very little requirements on the host, no replacement kernels for example.

Here’s what I did on a core 2 duo CPU machine – this is on an utterly clean 32-bit Ubuntu Edgy system – I know it’s clean, I installed it last night. This assumes that you have a stock Ubuntu kernel, and not one that you have either compiled yourself or in any way patched.

  • Check my CPU support VT
$ egrep '^flags.*(vmx|svm)' /proc/cpuinfo

If you get some output it does, if you don’t, it doesn’t. I got this:-

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm

The important bit there being “vmx” – oh and the fact that there are two lines means it’s dual core – more yay!

  • Get the necessary pre-requisites

You need GCC version 3.4 to compile qemu (which is included in kvm).

$ sudo apt-get install gcc-3.4 g++-3.4 uuid-dev zlib1g-dev libsdl1.2-dev build-essential linux-headers-generic

You should see something like this:-

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  cpp-3.4 dpkg-dev g++ g++-4.1 gcc-3.4-base libaa1-dev libartsc0 libartsc0-dev
  libasound2-dev libaudio-dev libaudiofile-dev libdirectfb-dev
  libdirectfb-extra libesd0-dev libfreetype6-dev libgl1-mesa-dev
  libglib2.0-dev libglu1-mesa-dev libice-dev libjpeg62-dev libncurses5-dev
  libpng12-dev libslang2-dev libsm-dev libstdc++6-4.1-dev libstdc++6-dev
  libx11-dev libxau-dev libxdmcp-dev libxext-dev libxt-dev
  linux-headers-2.6.17-10-generic mesa-common-dev x-dev x11proto-core-dev
  x11proto-input-dev x11proto-kb-dev x11proto-xext-dev xtrans-dev
Suggested packages:
  debian-keyring gcc-3.4-doc lib64stdc++6 gcc-4.1-doc libc6-dev-amd64
  lib64gcc1 libasound2-doc libglib2.0-doc libstdc++6-4.1-doc libstdc++6-doc
The following NEW packages will be installed:
  build-essential cpp-3.4 dpkg-dev g++ g++-3.4 g++-4.1 gcc-3.4 gcc-3.4-base
  libaa1-dev libartsc0 libartsc0-dev libasound2-dev libaudio-dev
  libaudiofile-dev libdirectfb-dev libdirectfb-extra libesd0-dev
  libfreetype6-dev libgl1-mesa-dev libglib2.0-dev libglu1-mesa-dev libice-dev
  libjpeg62-dev libncurses5-dev libpng12-dev libsdl1.2-dev libslang2-dev
  libsm-dev libstdc++6-4.1-dev libstdc++6-dev libx11-dev libxau-dev
  libxdmcp-dev libxext-dev libxt-dev linux-headers-2.6.17-10-generic
  linux-headers-generic mesa-common-dev uuid-dev x-dev x11proto-core-dev
  x11proto-input-dev x11proto-kb-dev x11proto-xext-dev xtrans-dev zlib1g-dev
0 upgraded, 46 newly installed, 0 to remove and 2 not upgraded.
Need to get 0B/19.8MB of archives.
After unpacking 98.3MB of additional disk space will be used.
Do you want to continue [Y/n]?

(except the bit where it says “need to get 0B” will be something bigger – I cheated and already downloaded that lot)

  • Get kvm

Go get kvm from their Sourceforge download page. I saved it to my desktop because I’m messy like that.

  • Unpack it
$ mkdir ~/src
$ cd ~/src
$ tar zxvf ~/Desktop/kvm-3.tar.gz
  • Configure it
$ cd kvm-3
$ ./configure --prefix=/usr/local/kvm --qemu-cc="/usr/bin/gcc-3.4"

If all goes well it should look like this:-

Install prefix    /usr/local/kvm
BIOS directory    /usr/local/kvm/share/qemu
binary directory  /usr/local/kvm/bin
Manual directory  /usr/local/kvm/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /home/alan/src/kvm-3/qemu
C compiler        /usr/bin/gcc-3.4
Host C compiler   gcc
make              make
install           install
host CPU          i386
host big endian   no
target list       i386-softmmu
gprof enabled     no
profiler          no
static build      no
SDL support       yes
SDL static link   yes
mingw32 support   no
Adlib support     no
CoreAudio support no
ALSA support      no
DSound support    no
FMOD support      no
kqemu support     no
kvm support       yes
Documentation     no

Note: kqemu support is “no” and kvm support is “yes”, that’s the really good stuff :)

  • Compile it
$ make

You should get a boatload of “stuff” starting with:-

make -C kernel
make[1]: Entering directory `/home/alan/src/kvm-3/kernel'
make -C /lib/modules/`uname -r`/build M=`pwd` "$@"
make[2]: Entering directory `/usr/src/linux-headers-2.6.17-10-generic'
  LD      /home/alan/src/kvm-3/kernel/built-in.o
  CC [M]  /home/alan/src/kvm-3/kernel/kvm_main.o

and finishing with something like:-

/usr/bin/gcc-3.4 -L /home/alan/src/kvm-3/qemu/../user -o qemu vl.o osdep.o block.o readline.o monitor.o pci.o console.o loader.o block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o scsi-disk.o cdrom.o lsi53c895a.o usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o ne2000.o rtl8139.o pcnet.o ide.o pckbd.o ps2.o vga.o sb16.o es1370.o dma.o audio.o noaudio.o wavaudio.o sdlaudio.o ossaudio.o wavcapture.o fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o usb-uhci.o gdbstub.o sdl.o vnc.o slirp/cksum.o slirp/if.o slirp/ip_icmp.o slirp/ip_input.o slirp/ip_output.o slirp/slirp.o slirp/mbuf.o slirp/misc.o slirp/sbuf.o slirp/socket.o slirp/tcp_input.o slirp/tcp_output.o slirp/tcp_subr.o slirp/tcp_timer.o slirp/udp.o slirp/bootp.o slirp/debug.o slirp/tftp.o libqemu.a  -lm -lz -lkvm -L/usr/lib -lSDL -lpthread  -lutil -lrt -luuid
make[2]: Leaving directory `/home/alan/src/kvm-3/qemu/i386-softmmu'
make[1]: Leaving directory `/home/alan/src/kvm-3/qemu'

Looking good!.

  • Install it
$ sudo make install
  • Insert the kernel module into the running kernel
$ sudo insmod kernel/kvm.ko

At this point you can now run qemu from the /usr/local/kvm directory into which we installed it.

I already have some disk images used by qemu which can of course be used by kvm also. It is based on qemu after all.

$ sudo /usr/local/kvm/bin/qemu -hda ~/vm/edgygold.qcow -m 512 -soundhw all -net nic -net user

There’s more detail about qemu in a previous blog post called Creating Screencasts (down the bottom), and also on the HantsLUG wiki.

If the kvm module isn’t loaded when you start qemu then you’ll get this:-

Could not initialize KVM, will disable KVM support

Which is clearly bad.

If the kvm module is loaded correctly – i.e. you did everything above right then you should see this:-

set_vram_mapping: memory: e0000000 - e0800000
set_vram_mapping: return 0x9614a000
vga_update_vram: base 0x9614a000 ptr 0x9694a008
vga_update_vram: done

And of course, here’s the obligatory screenshot :)

I thought I’d run a couple of benchmarks to see how it performs. I ran two. One is the amazing, nay reference gold standard benchmark that is Hugos Random Benchmark which is basically where you get a machine to count to a very big number and time it doing that. It’s great for raw clock speed pissing contests, but not much more. I should point out that the pc running this qemu/kvm image is actually top of that list. Here’s what the host gets when I run hugos random benchmark:-

alan@wopr:~$  time perl -e 'for($i=0;$i<1e8;$i++) { }'

real    0m6.689s
user    0m6.688s
sys     0m0.000s

And here's what the qemu/kvm image gets:-

alan@edgyvm:~$  time perl -e 'for($i=0;$i<1e8;$i++) { }'

real    0m7.230s
user    0m7.056s
sys     0m0.032s

That looks pretty good going to me!

Ok, lets try a more sane benchmark. The UnixBench benchmark should be more like it.

Here's the result from running UnixBench on the host computer.

==============================================================
BYTE UNIX Benchmarks (Version 4.1-wht)
System -- Linux wopr 2.6.17-10-generic #2 SMP Fri Oct 13 18:45:35 UTC 2006 i686 GNU/Linux
/dev/sdb1            235288032  30517988 192818088  14% /

Start Benchmark Run: Wed Nov 15 22:10:55 GMT 2006
 22:10:55 up  2:28,  7 users,  load average: 0.37, 0.34, 0.23

End Benchmark Run: Wed Nov 15 22:21:25 GMT 2006
 22:21:25 up  2:39,  5 users,  load average: 15.93, 6.89, 3.14

                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        376783.7 19976788.8      530.2
Double-Precision Whetstone                      83.1     2285.9      275.1
Execl Throughput                               188.3     8953.1      475.5
File Copy 1024 bufsize 2000 maxblocks         2672.0   150910.0      564.8
File Copy 256 bufsize 500 maxblocks           1077.0    40765.0      378.5
File Read 4096 bufsize 8000 maxblocks        15382.0  1234477.0      802.5
Pipe-based Context Switching                 15448.6   456975.1      295.8
Pipe Throughput                             111814.6  1201420.9      107.4
Process Creation                               569.3    23939.3      420.5
Shell Scripts (8 concurrent)                    44.8     1180.8      263.6
System Call Overhead                        114433.5  3513796.1      307.1
                                                                 =========
     FINAL SCORE                                                     359.3

..and here we having running under qemu/kvm..

>==============================================================
BYTE UNIX Benchmarks (Version 4.1-wht)
System -- Linux edgyvm 2.6.17-10-generic #2 SMP Fri Oct 13 18:45:35 UTC 2006 i686 GNU/Linux
/dev/hda1              9859036   1931768   7426444  21% /

Start Benchmark Run: Wed Nov 15 22:34:21 GMT 2006
 22:34:21 up 2 min,  2 users,  load average: 1.65, 0.90, 0.35

End Benchmark Run: Wed Nov 15 22:35:20 GMT 2006
 22:35:20 up 3 min,  2 users,  load average: 0.67, 0.75, 0.33

                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        376783.7        1.0        0.0
Double-Precision Whetstone                      83.1        0.0        0.0
Execl Throughput                               188.3        1.0        0.1
Pipe-based Context Switching                 15448.6        1.0        0.0
Pipe Throughput                             111814.6        1.0        0.0
Process Creation                               569.3        1.0        0.0
Shell Scripts (8 concurrent)                    44.8        1.0        0.2
System Call Overhead                        114433.5        1.0        0.0
                                                                 =========
     FINAL SCORE                                                       0.0

Hmm. Well that's not what I was expecting, that's for sure. Answers why on a postcard.

Overall, kvm receives the "popey 5 minute test" seal of approval.

This entry was posted in Advocacy, Linux, Ubuntu. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

4 Comments

  1. hugo
    Posted November 18, 2006 at 10:07 pm | Permalink

    It’s worth noting that Avi Kivity (the author of kvm) is working well with the kernel developers on LKML. I’d expect kvm to make it into the kernel for 2.6.20.

    Also, like qemu and Xen/HVM, kvm will use the qemu device model for mapping host resources to guest resources. qemu’s device model is apparently the most complete and functional open source one, so it makes sense to use it for this as well. It also means that the capabilities of kvm should be pretty much identical to those of Xen’s HVM.

  2. Posted January 10, 2007 at 7:40 pm | Permalink

    I Havn’t been able to start KVM without loading the kvm-amd module

    So for everybody do a modprobe kvm-amd or modprobe kvm-intel before loading qemu

  3. Jesus
    Posted December 10, 2006 at 11:07 pm | Permalink

    Thanks for your guide.
    In a fresh edgy install I cannot insert the resulting kernel module:

    jesus@jesus-laptop:~/sources/kvm-3$ sudo insmod kernel/kvm.ko
    insmod: error inserting 'kernel/kvm.ko': -1 Operation not supported

    And when I run quemu I get:

    Could not initialize KVM, will disable KVM support

    The same result with kvm-4…
    In /proc/version:

    Linux version 2.6.17-10-generic (root@vernadsky) (gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)) #2 SMP Fri Oct 13 18:45:35 UTC 2006 (Ubuntu 2.6.17-10.33-generic)

    ¿Could you share a working compiled module, or even better a .deb package?
    Thanks again

  4. Gabe Rudy
    Posted December 19, 2006 at 3:35 pm | Permalink

    I had this same error, by googling a bit i figured out that I had my /usr/bin/gcc symbolic link pointing to gcc-4.0.

    The kernel will not load kernel modules built with a different gcc. Make sure you have gcc-4.1 installed and /usr/bin/gcc pointing to /usr/bin/gcc-4.1

    something like this helped me:

    grudy@gamma:/usr/bin$ ls -lh gcc
    lrwxrwxrwx 1 root root 7 2006-12-13 15:24 gcc -> gcc-4.0
    grudy@gamma:/usr/bin$ sudo rm gcc
    Password:
    grudy@gamma:/usr/bin$ sudo ln -s gcc-4.1 gcc
    grudy@gamma:/usr/bin$ gcc –version
    gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)
    Copyright (C) 2006 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    good luck.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>