VMX: Difference between revisions

84 bytes added ,  14 years ago
m
no edit summary
[unchecked revision][unchecked revision]
m (formatting fix)
mNo edit summary
Line 10:
=== 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:
<source lang="c">
#define IA32_VMX_BASIC 0x480
#define IA32_VMX_CR0_FIXED0 0x486
Line 15 ⟶ 16:
#define IA32_VMX_CR4_FIXED0 0x488
#define IA32_VMX_CR4_FIXED1 0x489
</source>
 
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.
Line 23 ⟶ 25:
=== Executing VMXON ===
The main entry point for using VMX is through the VMXON instruction. The instruction requires a single operand of a m64 region called the VMXON region. The memory region needs to be 4096-byte aligned (bits 0-11 must be 0) 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. In order to prepare a memory address in 32-bit PMode for use as an m64, some modifications need to be made. The upper 32-bits of the m64 have to be 0 or an "invalid memory address" error will occur and a VMEXIT will be called.
<source lang="c">
uint32_t * region = (uint32_t *)allocate_4k_aligned(4096);
uint64_t region64 = (uint64_t)((size_t)(region) & 0xFFFFFFFF);
asm volatile(" vmxon %0; "::"m" (region64));
</source>
 
This general process of taking a 32-bit memory address and turning it into a psuedo-64bit int (unsigned long long) will be used for all m64 operands later. VMCLEAR is another example instruction that requires the upper 32-bits of a memory address to be 0.
Line 54 ⟶ 58:
A VMCS is loaded with the VMPTRLD instruction, which loads and activates a VMCS, and requires a 64-bit memory address as it's operand in the same format as VMXON/VMCLEAR.
 
<source lang="c">
asm volatile ("vmptrld %0; ":: "m" (vmcsRegion64));
</source>
 
The structure of the VMCS is covered in detail in Chapter 20 of the Intel SDM volume 3B (see link below). Field encodings for VMWRITE and VMREAD are covered in Appendix H of the same manual.
Anonymous user