From 513ced85fd64e14bbd06de6a935c60fda047536f Mon Sep 17 00:00:00 2001 From: "iliya.saroukha" <iliya.saroukhanian@etu.hesge.ch> Date: Tue, 3 Dec 2024 21:17:20 +0100 Subject: [PATCH] wip: added part about restrictions on VMX operation due to the values of certain bits in CR0 and CR4 --- docs/re.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/re.md b/docs/re.md index b4ecdd5..dbeb93a 100644 --- a/docs/re.md +++ b/docs/re.md @@ -82,6 +82,7 @@ to the above mentioned instruction ```c static bool vmx_supported(void) { + /*unsigned int ecx = cpuid_ecx(1);*/ // #include "asm/cpuid.h" int ecx; __asm__ volatile("mov $1, %rax"); @@ -92,7 +93,7 @@ static bool vmx_supported(void) { } ``` -### Enabling VMX +### Enabling VMX in CR4 In order to enter VMX operation, the software (our hypervisor) has to firstly enable VMX by setting the 13th bit of the CR4 register to 1. This will of course @@ -109,6 +110,8 @@ static void cr4_enable_vmx(void) { } ``` +### IA32_FEATURE_CONTROL MSR + VMXON is also controlled by the IA32_FEATURE_CONTROL MSR (Model-Specific Register). MSRs are 64-bit wide. The address of IA32_FEATURE_CONTROL MSR is **0x3a**. @@ -156,6 +159,66 @@ static bool ia32_feature_control_flags(void) { } ``` +### Restrictions on VMX operation + +From what I understand, certains bits in the CR0 and CR4 control registers need +to either be set or cleared (still quite vague for now) so that a call to +`vmxon` won't fail. + +"Full" explanation from Intel's SDM (Chapter 25.8, p. 4040): + +> _In VMX operation, processors may fix certain bits in CR0 and CR4 to specific values and not support other +> values. VMXON fails if any of these bits contains an unsupported value (see “VMXON—Enter VMX Operation” in +> Chapter 32). Any attempt to set one of these bits to an unsupported value while in VMX operation (including +> VMX root operation) using any of the CLTS, LMSW, or MOV CR instructions causes a general-protection +> exception. VM entry or VM exit cannot set any of these bits to an unsupported value. Software should consult +> the VMX capability MSRs IA32_VMX_CR0_FIXED0 and IA32_VMX_CR0_FIXED1 to determine how bits in CR0 +> are fixed (see Appendix A.7). For CR4, software should consult the VMX capability MSRs +> IA32_VMX_CR4_FIXED0 and IA32_VMX_CR4_FIXED1 (see Appendix A.8)._ + +#### Pseudo-code for successfully executing VMXON + +``` +IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0) +THEN #UD; +ELSIF not in VMX operation + THEN + IF (CPL > 0) or (in A20M mode) or + (the values of CR0 and CR4 are not supported in VMX operation; see Section 25.8) or + (bit 0 (lock bit) of IA32_FEATURE_CONTROL MSR is clear) or + (in SMX operation2 and bit 1 of IA32_FEATURE_CONTROL MSR is clear) or + (outside SMX operation and bit 2 of IA32_FEATURE_CONTROL MSR is clear) + THEN #GP(0); + ELSE + addr := contents of 64-bit in-memory source operand; + IF addr is not 4KB-aligned or + addr sets any bits beyond the physical-address width3 + THEN VMfailInvalid; + ELSE + rev := 32 bits located at physical address addr; + IF rev[30:0] ≠ VMCS revision identifier supported by processor OR rev[31] = 1 + THEN VMfailInvalid; + ELSE + current-VMCS pointer := FFFFFFFF_FFFFFFFFH; + enter VMX operation; + block INIT signals; + block and disable A20M; + clear address-range monitoring; + IF the processor supports Intel PT but does not allow it to be used in VMX operation 1 + THEN IA32_RTIT_CTL.TraceEn := 0; + FI; + VMsucceed + FI; + FI; + FI; +ELSIF in VMX non-root operation + THEN VMexit; +ELSIF CPL > 0 + THEN #GP(0); + ELSE VMfail(“VMXON executed in VMX root operation”); +FI; +``` + ## References [^1]: [The Linux Kernel Module Programming Guide](https://sysprog21.github.io/lkmpg/) -- GitLab