add VMCS controls

This commit is contained in:
Masato Imai
2025-04-22 05:51:23 +00:00
parent 9ebd56b32a
commit 9b367331ea
3 changed files with 89 additions and 3 deletions

View File

@@ -56,7 +56,6 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
let mut vcpu = VCpu::new(phys_mem_offset.as_u64(), &mut frame_allocator);
vcpu.activate();
vcpu.reset_vmcs().unwrap();
info!("vmlaunch...");

View File

@@ -1,8 +1,11 @@
use x86::{msr::rdmsr, vmx::VmFail};
use crate::memory::BootInfoFrameAllocator;
use crate::{info, memory::BootInfoFrameAllocator};
use super::{vmcs::Vmcs, vmxon::Vmxon};
use super::{
vmcs::{PinBasedVmExecutionControls, Vmcs},
vmxon::Vmxon,
};
pub struct VCpu {
pub vmxon: Vmxon,
@@ -28,6 +31,39 @@ impl VCpu {
let revision_id = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) } as u32;
self.vmcs
.write_revision_id(revision_id, self.phys_mem_offset);
self.reset_vmcs().unwrap();
self.setup_exec_ctrls().unwrap();
}
pub fn setup_exec_ctrls(&mut self) -> Result<(), VmFail> {
let basic_msr = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) };
let mut pin_exec_ctrl = PinBasedVmExecutionControls::read();
let reserved_bits = if basic_msr & (1 << 55) != 0 {
unsafe { rdmsr(x86::msr::IA32_VMX_TRUE_PINBASED_CTLS) }
} else {
unsafe { rdmsr(x86::msr::IA32_VMX_PINBASED_CTLS) }
};
pin_exec_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
pin_exec_ctrl.0 &= (reserved_bits >> 32) as u32;
pin_exec_ctrl.write();
let mut primary_exec_ctrl = PinBasedVmExecutionControls::read();
let reserved_bits = if basic_msr & (1 << 55) != 0 {
unsafe { rdmsr(x86::msr::IA32_VMX_TRUE_PROCBASED_CTLS) }
} else {
unsafe { rdmsr(x86::msr::IA32_VMX_PROCBASED_CTLS) }
};
primary_exec_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
primary_exec_ctrl.0 &= (reserved_bits >> 32) as u32;
primary_exec_ctrl.write();
Ok(())
}
pub fn reset_vmcs(&mut self) -> Result<(), VmFail> {

View File

@@ -171,6 +171,57 @@ impl PinBasedVmExecutionControls {
}
}
/*
_reserved1: u2,
interrupt_window: bool,
tsc_offsetting: bool,
_reserved2: u3,
hlt: bool,
_reserved3: u1,
invlpg: bool,
mwait: bool,
rdpmc: bool,
rdtsc: bool,
_reserved4: u2,
cr3load: bool,
cr3store: bool,
activate_teritary_controls: bool,
_reserved: u1,
cr8load: bool,
cr8store: bool,
use_tpr_shadow: bool,
nmi_window: bool,
mov_dr: bool,
unconditional_io: bool,
use_io_bitmap: bool,
_reserved5: u1,
monitor_trap: bool,
use_msr_bitmap: bool,
monitor: bool,
pause: bool,
activate_secondary_controls: bool,
*/
pub struct PrimaryProcessorBasedVmExecutionControls(pub u32);
impl PrimaryProcessorBasedVmExecutionControls {
pub fn read() -> Self {
let err = VmcsControl32::PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS.read();
if err.is_err() {
panic!("Failed to read Primary Processor Based VM Execution Controls");
}
let err = err.unwrap();
PrimaryProcessorBasedVmExecutionControls(err)
}
pub fn write(&self) {
VmcsControl32::PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS
.write(self.0)
.expect("Failed to write Primary Processor Based VM Execution Controls");
}
}
pub enum VmcsControl32 {
PIN_BASED_VM_EXECUTION_CONTROLS = 0x00004000,
PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS = 0x00004002,