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.
4 Comments
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.
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
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
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.