Virtual Windows 8 (x86/x64) under Linux KVM/QEMU

I’ve spent way too much time getting Windows 8 to play ball under KVM/QEMU on my Debian host.

The first hurdle was to emulate the CPU prerequisites (Physical Address Extension (PAE), NX, and SSE2).  This was accomplished with the below CPU deceleration in the machine’s XML file.

<cpu mode='custom' match='minimum'>
 <model fallback='allow'>core2duo</model>
 <feature policy='require' name='lahf_lm'/>
 <feature policy='require' name='sse2'/>
 <feature policy='require' name='xtpr'/>
 <feature policy='require' name='cx16'/>
 <feature policy='require' name='tm2'/>
 <feature policy='require' name='est'/>
 <feature policy='require' name='vmx'/>
 <feature policy='require' name='ds_cpl'/>
 <feature policy='require' name='pbe'/>
 <feature policy='require' name='tm'/>
 <feature policy='require' name='ht'/>
 <feature policy='require' name='ss'/>
 <feature policy='require' name='acpi'/>
 <feature policy='require' name='ds'/>
 <feature policy='require' name='nx'/>
 <feature policy='require' name='pae'/>
 <feature policy='require' name='mmx'/>
 </cpu>

Thanks to VMcPherron for posting this information on http://superuser.com

An almost working copy of the XML looks like the below:

<domain type='kvm' id='168'>
 <name>Virtual8</name>
 <uuid>1a86fde6-45b3-bd10-9d96-9c17de4f2a9e</uuid>
 <memory unit='KiB'>2097152</memory>
 <currentMemory unit='KiB'>2097152</currentMemory>
 <vcpu>2</vcpu>
 <os>
 <type arch='x86_64' machine='pc-0.14'>hvm</type>
 <boot dev='cdrom'/>
 <boot dev='hd'/>
 <bootmenu enable='yes'/>
 </os>
 <features>
 <acpi/>
 <apic/>
 <pae/>
 </features>
 <cpu mode='custom' match='minimum'>
 <model fallback='allow'>core2duo</model>
 <feature policy='require' name='lahf_lm'/>
 <feature policy='require' name='sse2'/>
 <feature policy='require' name='xtpr'/>
 <feature policy='require' name='cx16'/>
 <feature policy='require' name='tm2'/>
 <feature policy='require' name='est'/>
 <feature policy='require' name='vmx'/>
 <feature policy='require' name='ds_cpl'/>
 <feature policy='require' name='pbe'/>
 <feature policy='require' name='tm'/>
 <feature policy='require' name='ht'/>
 <feature policy='require' name='ss'/>
 <feature policy='require' name='acpi'/>
 <feature policy='require' name='ds'/>
 <feature policy='require' name='nx'/>
 <feature policy='require' name='pae'/>
 <feature policy='require' name='mmx'/>
 </cpu>
 <clock offset='localtime'/>
 <on_poweroff>destroy</on_poweroff>
 <on_reboot>restart</on_reboot>
 <on_crash>destroy</on_crash>
 <devices>
 <emulator>/usr/bin/kvm</emulator>
 <disk type='file' device='disk'>
 <driver name='qemu' type='qcow2'/>
 <source file='/vm/clone/Virtual8.qcow2'/>
 <target dev='hda' bus='ide'/>
 <alias name='ide0-0-0'/>
 <address type='drive' controller='0' bus='0' target='0' unit='0'/>
 </disk>
 <disk type='file' device='cdrom'>
 <driver name='qemu' type='raw'/>
 <source file='/data/isos/en-gb_windows_8_enterprise_x64_dvd_922086.iso'/>
 <target dev='hdc' bus='ide'/>
 <readonly/>
 <alias name='ide0-1-0'/>
 <address type='drive' controller='0' bus='1' target='0' unit='0'/>
 </disk>
 <controller type='ide' index='0'>
 <alias name='ide0'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
 </controller>
 <controller type='usb' index='0'>
 <alias name='usb0'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
 </controller>
 <interface type='bridge'>
 <mac address='00:16:3a:d2:eb:27'/>
 <source bridge='br0'/>
 <target dev='vnet15'/>
 <alias name='net0'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
 </interface>
 <serial type='pty'>
 <source path='/dev/pts/19'/>
 <target port='0'/>
 <alias name='serial0'/>
 </serial>
 <console type='pty' tty='/dev/pts/19'>
 <source path='/dev/pts/19'/>
 <target type='serial' port='0'/>
 <alias name='serial0'/>
 </console>
 <input type='tablet' bus='usb'>
 <alias name='input0'/>
 </input>
 <input type='mouse' bus='ps2'/>
 <graphics type='vnc' port='5915' autoport='yes'/>
 <video>
 <model type='xen' vram='18432' heads='1'/>
 <alias name='video0'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
 </video>
 <memballoon model='virtio'>
 <alias name='balloon0'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
 </memballoon>
 </devices>
 <seclabel type='none'/>
</domain>

In the above code you will need to replace:

<model type='xen' vram='18432' heads='1'/>

with:

<model type='vga' vram='18432' heads='1'/>

for the install.

On my system (/usr/bin/kvm: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, stripped) I found the VM crashed after booting from a shutdown, it was fine between reboots though?

It's best not to shutdown the VM until you have finalised the install, then make the change from

type='vga'

to

type='xen'

It will crash on first boot, but will be fine for subsequent shut-downs and reboots.

The main hurdle I'm still facing is not being able to VNC into the machine (black/blank screen) with the above set-up, RDP works fine though. I'm able to VNC into the VM with the problematic video card settings:

type='vga'

but not:

type='xen'

I've lowered the graphics requirements by choosing 'Adjust for best performance' within Windows 8 but it doesn't make a difference.

Windows 2012 server will install and run fine with the above XML, keep the video as:

type='vga'

Seems like Windows 8 is a bit more neurotic about video cards :-(

I would appreciate your feedback on getting Windows 8 running both RDP and VNC under Linux/KVM/QEMU.