use crate::x86::msr;
#[derive(Clone, Copy)]
pub enum VmxControl {
PinBased,
ProcessorBased,
ProcessorBased2,
VmExit,
VmEntry,
}
pub fn adjust_vmx_controls(control: VmxControl, requested_value: u64) -> u64 {
const IA32_VMX_BASIC_VMX_CONTROLS_FLAG: u64 = 1 << 55;
let vmx_basic = msr::rdmsr(msr::IA32_VMX_BASIC);
let true_cap_msr_supported = (vmx_basic & IA32_VMX_BASIC_VMX_CONTROLS_FLAG) != 0;
let cap_msr = match (control, true_cap_msr_supported) {
(VmxControl::PinBased, true) => msr::IA32_VMX_TRUE_PINBASED_CTLS,
(VmxControl::PinBased, false) => msr::IA32_VMX_PINBASED_CTLS,
(VmxControl::ProcessorBased, true) => msr::IA32_VMX_TRUE_PROCBASED_CTLS,
(VmxControl::ProcessorBased, false) => msr::IA32_VMX_PROCBASED_CTLS,
(VmxControl::VmExit, true) => msr::IA32_VMX_TRUE_EXIT_CTLS,
(VmxControl::VmExit, false) => msr::IA32_VMX_EXIT_CTLS,
(VmxControl::VmEntry, true) => msr::IA32_VMX_TRUE_ENTRY_CTLS,
(VmxControl::VmEntry, false) => msr::IA32_VMX_ENTRY_CTLS,
(VmxControl::ProcessorBased2, _) => msr::IA32_VMX_PROCBASED_CTLS2,
};
let capabilities =msr::rdmsr(cap_msr);
let allowed0 = capabilities as u32;
let allowed1 = (capabilities >> 32) as u32;
let mut effective_value = u32::try_from(requested_value).unwrap();
effective_value |= allowed0;
effective_value &= allowed1;
u64::from(effective_value)
}