I am having a trouble when using the VMXON instruction. Basically, each time I use it the cpu resets, even though I do everything that is required to do in order to initialize and run the VMX environment. I am working on a windows xp 64, intel core2 duo, i am using WDK 6001.18001 and the compiler intrinsics to write and compile my kernel driver.
Here is the environment i set up right before the vmxon:
(cpuid check indicates that VMX is supported)
Vmxon region virtual address: high FFFFFADF low ADA5A000
VMXON region physical address: A1F35000 (allocated by MmAllocateNonCachedMemory, the physical memory page exists, i double checked with windbg, i used the !pte command to make sure these virtual and physical address correspond, then the command !dc to make sure the data in the physical page actually is correct. Allocation size is PAGE_SIZE (4096))
CR0 is: high 00000000 low 80050033 (PE NE PG bits are set, as required by intel manuals)
CR4 is: high 00000000 low 000026F8 (VMXE bit set, SMXE bit not set)
MSR 3A is: high 00000000 low 00000005 (lock bit and VMX outside SMX bit are set. Also, i doublechecked the bios and the vt is actually enabled)
MSR 480: high 001A0400 low 00000007 (the low part is the revision ID that i have copied in the first field of the vmxon region)
MSR 486: high 00000000 low 80000021 (these four registers are the bitmasks specifying valid values for CR0 and CR4)
MSR 487: high 00000000 low FFFFFFFF
MSR 488: high 00000000 low 00002000
MSR 489: high 00000000 low 000027FF
Vmxon region data at offset 0: 00000007 (this is the revision id taken from MSR 480)
Vmxon region data at offset 4: 00000000
Vmxon region data at offset 8: 00000000 (etc. i zeroed all the memory)
So basically what i did is:
- check cpuid for vmx capability
- set VMXE in cr4
- make sure PE PG NE are set in CR0
- allocate noncached memory for the vmxon region and initialize the revision id member with the low part of MSR 480
- check that lock bit and VMX outside SMX bit in MSR 3A are set
- call vmxon
it looks like i am doing everything correct, i just cannot understand why the cpu resets when i call VMXON. I get no bluescreen, the machine just reboots. I am sure the reboot is caused by the vmxon instruction because i log all this information to a file right before i call the instruction. Also, there is no "dangerous" code after the vmxon, since the first thing i do after it is calling a VMXOFF. Also, i tried passing a hardcoded address to the VMXON instruction, just to be sure i was not messing with pointers, still even if the address is valid (doublechecked with windbg) i get a reset.
I have been looking other source code examples (including xen), and they seem to do the same things that i am doing, also, i could not find any other requirements in the intel manuals that specify what to do in order to activate the VMX correctly.
The only thing i am not checking is the A20 mode, but in windows this should not be a problem.
Any idea on what i am doing wrong? Am i missing some initialization step? If this is correct then probably i am having troubles with the compiler intrinsics.