mirror of
https://github.com/mii443/nel_os.git
synced 2025-12-04 19:58:33 +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);
|
let mut vcpu = VCpu::new(phys_mem_offset.as_u64(), &mut frame_allocator);
|
||||||
vcpu.activate();
|
vcpu.activate();
|
||||||
vcpu.reset_vmcs().unwrap();
|
|
||||||
|
|
||||||
info!("vmlaunch...");
|
info!("vmlaunch...");
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
use x86::{msr::rdmsr, vmx::VmFail};
|
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 struct VCpu {
|
||||||
pub vmxon: Vmxon,
|
pub vmxon: Vmxon,
|
||||||
@@ -28,6 +31,39 @@ impl VCpu {
|
|||||||
let revision_id = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) } as u32;
|
let revision_id = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) } as u32;
|
||||||
self.vmcs
|
self.vmcs
|
||||||
.write_revision_id(revision_id, self.phys_mem_offset);
|
.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> {
|
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 {
|
pub enum VmcsControl32 {
|
||||||
PIN_BASED_VM_EXECUTION_CONTROLS = 0x00004000,
|
PIN_BASED_VM_EXECUTION_CONTROLS = 0x00004000,
|
||||||
PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS = 0x00004002,
|
PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS = 0x00004002,
|
||||||
|
|||||||
Reference in New Issue
Block a user