Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod gdt;
pub mod layout;
pub mod paging;
pub mod sse;
pub mod vmx;
22 changes: 22 additions & 0 deletions src/arch/x86_64/vmx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: Apache-2.0

use core::arch::x86_64::__cpuid;
use x86_64::registers::model_specific::Msr;

const IA32_FEATURE_CONTROL: u32 = 0x3a;
const FEATURE_CONTROL_LOCKED: u64 = 1 << 0;
const FEATURE_CONTROL_VMXON_OUTSIDE_SMX: u64 = 1 << 2;
const CPUID_1_ECX_VMX: u32 = 1 << 5;

// A guest hypervisor (Hyper-V / WSL2) refuses VMXON unless firmware locked IA32_FEATURE_CONTROL with VMXON enabled; real BIOS does this at boot, so we must too or nested virt is unusable despite VMX in CPUID.
pub fn enable_feature_control() {
let has_vmx = unsafe { __cpuid(1) }.ecx & CPUID_1_ECX_VMX != 0;
if !has_vmx {
return;
}
let mut msr = Msr::new(IA32_FEATURE_CONTROL);
let current = unsafe { msr.read() };
if current & FEATURE_CONTROL_LOCKED == 0 {
unsafe { msr.write(current | FEATURE_CONTROL_VMXON_OUTSIDE_SMX | FEATURE_CONTROL_LOCKED) };
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ pub extern "C" fn rust64_start(#[cfg(not(feature = "coreboot"))] pvh_info: &pvh:

arch::x86_64::sse::enable_sse();
arch::x86_64::paging::setup();
arch::x86_64::vmx::enable_feature_control();

#[cfg(feature = "coreboot")]
let info = &coreboot::StartInfo::default();
Expand Down
Loading