Deep into CR0/CR4 in VMX operation
In VMX operation, the value of guest CR0/CR4 need to consider the following cases:
- processors may fix certain bits in CR0 and CR4 to specific values and not support other values.
- Guest/Host Masks and Read Shadows for CR0 and CR4
1. Background
For the first case, you can refer to intel SDM Vol. 3D A.7(VMX-FIXED BITS IN CR0) and A.8(VMX-FIXED BITS IN CR4).
We’ll deep into the second case.
From the description, please try to answer this question: Why needs the guest/host masks and read shadow?
Let’s consider this example:
From SDM description, CR4.VMXE must be 1 in VMX operation. Without guest/host masks and read shadow, if guest is a normal operating system, not a VMM, when guest want to get CR4.VMXE, it would be 1. That’s the wrong value for guest. But we still need to ensure physical CR4.VMXE is1 in non-root mode!
How can we satisfy all the above requirements?
guest/host masks and read shadow help us solve the issue.
set VMCS Guest CR4(00006804H ) field VMXE bit to be 1, to ensure physical CR4.VMXE is 1 in non-root mode;
set CR4 guest/host masks(00006002H ) field VMXE bit to be 1, means VMXE bit is owned by host;
- set CR4 read shadow(00006006H ) field VMXE bit to be 0.
When guest reads CR4.VMXE, hardware will return value for this bit from the corresponding read shadow(the value is 0 here). While physical CR4.VMXE still is 1 in non-root mode.
2. Example
Let’s take ACRN virtual_cr.c as an example.
1 | /* |
1 |
CR0_PG is trapped by HV and HV emulation will eventually write the guest value to physical CR0 (GUEST_CR0) too. Can we pass through CR0_PG to guest? The answer is no!
1 | if ((cr0_changed_bits & CR0_PG) != 0UL) { |
Here’s the reason why we set theVMX_ENTRY_CTLS_IA32E_MODE
and MSR_IA32_EFER_LMA_BIT
.
If pass through CR0_PG to guest, while guest runs in non-root mode, hardware couldn’t updateVMX_ENTRY_CONTROLS
field. So we should trap CR0_PG, and HV will updateVMX_ENTRY_CONTROLS
field in root mode.
3. Conclusion
If one bit has restriction in VMX operation or needs to do some operations in root mode, It’s better to trap(owned by host) this bit.