mirror of
https://github.com/mii443/nel_os.git
synced 2025-12-03 03:08:25 +00:00
add VMCS controls
This commit is contained in:
@@ -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...");
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user