VMX
Intel's Virtual-Machine Extensions
Programming
Discovering support
After enumerating the features from CPUID, bit 5 in ECX will tell you if VMX is supported or not. This is the first thing that should be checked!
Basic environment
Software should enable bit 13 of CR4 (CR4.VMXE) first. Here are a few definitions of some used MSR's that we'll be dealing with:
#define IA32_VMX_BASIC 0x480 #define IA32_VMX_CR0_FIXED0 0x486 #define IA32_VMX_CR0_FIXED1 0x487 #define IA32_VMX_CR4_FIXED0 0x488 #define IA32_VMX_CR4_FIXED1 0x489
In order to see what your OS needs to support, you need to read the lower 32-bits of IA32_VMX_CR0_FIXED0 and IA32_VMX_CR4_FIXED0. The bits in those MSR's are what need to be set (and supported) in their corresponding control registers (CR0/CR4). If any of those bits are not enabled, a GPF will occur. Also, to see what extra bits can be set, check the IA32_VMX_CR0_FIXED1 and IA32_VMX_CR4_FIXED1. It's basically a mask of bits, if a bit is set to 1, then it "can" be enabled, but if it's a 0, you may generate an exception if you enable the corresponding bit in the control registers.
From my own hardware and emulator (bochs), I've found that you will most likely need to enable these bits: CR0.NE, CR4.PAE, CR0.PG and CR0.PE. Yes, that means you need to support PAE-enabled paging and have those structures installed into CR3. For 64-bit kernels, you need to have IA32_EFER.LMA set.
Executing VMXON
The main entry point for using VMX is through the VMXON instruction. The instruction requires a single operand of an m32 or m64 region called an VMCS (Virtual-Machine Control Structure). The memory region needs to be size_t-aligned (I use 16-byte alignment to be safe) and the only VMCS field that should be modified is the VMCS revision identification field. This ID field should contain the value in bits 0-31 of MSR IA32_VMX_BASIC.
References
Intel's SDM 3B: http://www.intel.com/Assets/PDF/manual/253669.pdf Intel's SDM 2B: http://www.intel.com/Assets/PDF/manual/253667.pdf