The code may look like this:
vmxon [vmxon_ptr]
vmxon_ptr dq vmxon_region_begin
vmxon_region_begin: vmxon_rev_id dd 0
Key things to note in the above snippet:
a. The operand to vmxon is vmxon_ptr. vmxon_ptr is a pointer to the vmxon_region. Note: vmxon_region is in physical memory.
b. The vmxon_region contains a 4-byte field called 'rev_id'. The hypervisor is expected to set up the revision-id in the vmxon-region provided by the processor.
How does the hypervisor determine the revision-id?
On Intel processors, the revision-id is contained in VMX_BASIC_MSR (0x480). Bits 31:0 of this MSR contains the revision-id of the processor.
So, for the example above, the hypervisor may want to do:
///////////////////////////////////////////////////
xor eax, eax
xor edx, edx
mov ecx, 0x480
rdmsr ; after rdmsr eax has the revision id
mov dword [vmxon_rev_id], eax ; write the rev-id into vmxon region
vmxon [vmxon_ptr]
////////////////////////////////////////////////
Note: Intel PRM also specifies that the vmxon_region must be aligned on a 4K boundary. If it is not 4K aligned , VMXON is guaranteed to fail.
It is worth repeating that the operand to vmxon is a pointer to the vmxon_region which is in physical memory. Hence vmxon regions should reside in unpaged memory.
Successful completion of vmxon will cause the processor to enter the VMX_ROOT operation.
Hypervisors must also check to see if the execution of vmxon was successful. That can be done by checking the state of eflags.ZF and eflags.CF. If eflags.ZF =0 and eflags.CF=0 then vmxon was successful.
Continuing our previous code:
///////////////////////////////////////////////////
xor eax, eax
xor edx, edx
mov ecx, 0x480
rdmsr
mov dword [vmxon_rev_id], eax
vmxon [vmxon_ptr]
jbe vmxon_failed
vmxon_pass:
if i am here then eflags.ZF=0 and eflags.CF=0. So vmxon was successful.
vmxon_failed:
either eflags.ZF=1 or eflags.CF=1
handle failed code here
//////////////////////////////////////////////////
No comments:
Post a Comment