add VMCS entry ctrls

This commit is contained in:
Masato Imai
2025-04-22 09:59:23 +00:00
parent fa0d53cc36
commit 1e64555cba
2 changed files with 60 additions and 1 deletions

View File

@ -12,7 +12,7 @@ use core::arch::naked_asm;
use crate::{
info,
memory::BootInfoFrameAllocator,
vmm::vmcs::{DescriptorType, Granularity, SegmentRights},
vmm::vmcs::{DescriptorType, EntryControls, Granularity, SegmentRights},
};
use super::{
@ -46,6 +46,7 @@ impl VCpu {
.write_revision_id(revision_id, self.phys_mem_offset);
self.reset_vmcs().unwrap();
self.setup_exec_ctrls().unwrap();
self.setup_entry_ctrls().unwrap();
self.setup_host_state().unwrap();
self.setup_guest_state().unwrap();
}
@ -82,6 +83,27 @@ impl VCpu {
Ok(())
}
pub fn setup_entry_ctrls(&mut self) -> Result<(), VmFail> {
info!("Setting up entry controls");
let basic_msr = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) };
let mut entry_ctrl = EntryControls::read();
let reserved_bits = if basic_msr & (1 << 55) != 0 {
unsafe { rdmsr(x86::msr::IA32_VMX_TRUE_ENTRY_CTLS) }
} else {
unsafe { rdmsr(x86::msr::IA32_VMX_ENTRY_CTLS) }
};
entry_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
entry_ctrl.0 &= (reserved_bits >> 32) as u32;
entry_ctrl.write();
Ok(())
}
pub fn setup_host_state(&mut self) -> Result<(), VmFail> {
info!("Setting up host state");
unsafe {

View File

@ -218,6 +218,43 @@ bitfield! {
pub unusable, set_unusable: 16;
}
bitfield! {
pub struct EntryControls(u32);
impl Debug;
pub load_debug_controls, set_load_debug_controls: 2;
pub ia32e_mode_guest, set_ia32e_mode_guest: 9;
pub entry_smm, set_entry_smm: 10;
pub deactivate_dualmonitor, set_deactivate_dualmonitor: 11;
pub load_perf_global_ctrl, set_load_perf_global_ctrl: 13;
pub load_ia32_pat, set_load_ia32_pat: 14;
pub load_ia32_efer, set_load_ia32_efer: 15;
pub load_ia32_bndcfgs, set_load_ia32_bndcfgs: 16;
pub conceal_vmx_from_pt, set_conceal_vmx_from_pt: 17;
pub load_rtit_ctl, set_load_rtit_ctl: 18;
pub load_uinv, set_load_uinv: 19;
pub load_cet_state, set_load_cet_state: 20;
pub load_guest_lbr_ctl, set_load_guest_lbr_ctl: 21;
pub load_pkrs, set_load_pkrs: 22;
}
impl EntryControls {
pub fn read() -> Self {
let err = VmcsControl32::VM_ENTRY_CONTROLS.read();
if err.is_err() {
panic!("Failed to read VM Entry Controls");
}
let err = err.unwrap();
EntryControls(err)
}
pub fn write(&self) {
VmcsControl32::VM_ENTRY_CONTROLS
.write(self.0)
.expect("Failed to write VM Entry Controls");
}
}
pub enum VmcsControl32 {
PIN_BASED_VM_EXECUTION_CONTROLS = 0x00004000,
PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS = 0x00004002,