Most hosts these days are 64 bit and have been for a few years. In fact, 32 bit hardware which supports the hardware-assisted virtualization needed for KVM is a rare thing. I have an old laptop which has this rare combination.

However 32 bit guests are relatively common. You might need to run Windows XP, or a proprietary kernel module that only works with a 32 bit kernel, and virtualization is an ideal way to keep these legacy programs going.

So the common question I am asked is: When installing a 32 bit guest, should I choose an i686 or x86-64 (32 or 64 bit) architecture?

The answer seems obvious. You should select i686 for your 32 bit guest.

Actually, no, this isn’t right. x86-64 is the default, and if you try it out you’ll see that 32 bit guests work just fine.

The reason that a 32 bit guest works even though the architecture is x86-64 is simple: When AMD first invented the 64 bit extensions that we now call x86-64, like all previous extensions to the 8086 model, they made them backwards compatible. Like real PC hardware, KVM x86-64 runs 32 bit code (and 16 bit, and 8 bit) code just fine. You can still run MS-DOS on your new x86-64 hardware, even though it’s a 16 bit program. You can still install Windows XP on your x86-64 hardware even though that is a 32 bit program. Same applies to x86-64 KVM guests.

What does the architecture selection do? It changes the -cpu flag that we pass to qemu-kvm. Look at the range of CPUs that qemu-kvm supports:

What happens in detail is that for x86-64, no -cpu flag is passed, which is the same as using -cpu qemu64. If the architecture is set to i686, then -cpu qemu32 flag is passed. You can see qemu64 and qemu32 appearing in the list above.

This raises two questions: What does the -cpu flag do, and what are “qemu64” and “qemu32” (not a CPU that has rolled off an Intel or AMD assembly line …).

Both questions can be answered by using a “super secret!” QEMU command line flag, -cpu ?dump. Dumping out the two CPU models of interest to us:

The only thing these flags do is change what is reported back to the guest in the CPUID instruction [PDF link]. The actual processor emulation is not changed*.

Could you install a 64 bit guest even if the architecture was configured as “i686”. In theory it could work, but in reality it won’t because Linux checks very early on if the CPUID instruction reports Long Mode (see the verify_cpu function in arch/x86/kernel). Basically Linux or any sane OS would refuse to boot.

Could you use all the features of the CPU if you just ignored CPUID? Yes, but really, don’t do this. Some badly behaved applications in fact do this (Skype for one, but it’s not the only culprit) and this causes all sorts of problems particularly for live migration, since we can’t predict any more if we can safely migrate a virtual machine over to another host that has different features.

* Two complications which make this statement not quite true: QEMU changes some very minor aspects of emulation based on the CPU features, in particular whether or not to enable APIC. Secondly KVM itself can emulate some instructions which are not supported by the hardware. So what your guest sees is a superset of what the hardware can do.

I think that -cpu qemu32 (or selecting “i686” in the advanced options of virt-manager) is no earthly use to anyone and I defy anyone to name a serious use case for it.

-cpu qemu64 is not the same as “all the features supported by my hardware”. If you want that then you have to use -cpu host. This might even be a good idea, but it’s likely to be incompatible with live migration. If you don’t care about live migration then in theory this will give your guests maximum potential performance.

This actually matters very much in my opinion, if you don’t choose the matching architecture your guest will run extremely slow because you won’t be using any hardware acceleration. I have seen the first hand when troubleshooting slow guest performance. Choosing the right architecture is absolutely essential if you care about native virtualization performance.

About the author

I am Richard W.M. Jones, a computer programmer. I have strong opinions on how we write software, about Reason and the scientific method. Consequently I am an atheist [To nutcases: Please stop emailing me about this, I'm not interested in your views on it] By day I work for Red Hat on all things to do with virtualization. I am a "citizen of the world".

My motto is "often wrong". I don't mind being wrong (I'm often wrong), and I don't mind changing my mind.

This blog is not affiliated or endorsed by Red Hat and all views are entirely my own.