From a0a204b43c970c6685ca5e03a2e30052fa51f265 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Fri, 22 Aug 2025 08:34:41 +0000 Subject: [PATCH] cr vmexit --- .../src/vmm/x86_64/intel/controls.rs | 20 ++++++++-- nel_os_kernel/src/vmm/x86_64/intel/msr.rs | 6 --- nel_os_kernel/src/vmm/x86_64/intel/vcpu.rs | 40 ++++++++++++++++--- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/nel_os_kernel/src/vmm/x86_64/intel/controls.rs b/nel_os_kernel/src/vmm/x86_64/intel/controls.rs index 302e52f..59474a3 100644 --- a/nel_os_kernel/src/vmm/x86_64/intel/controls.rs +++ b/nel_os_kernel/src/vmm/x86_64/intel/controls.rs @@ -1,4 +1,7 @@ -use crate::vmm::x86_64::{common, intel::vmcs}; +use crate::vmm::x86_64::{ + common, + intel::{vmcs, vmwrite}, +}; pub fn setup_exec_controls() -> Result<(), &'static str> { let basic_msr = common::read_msr(0x480); @@ -12,8 +15,8 @@ pub fn setup_exec_controls() -> Result<(), &'static str> { raw_pin_exec_ctrl |= (reserved_bits & 0xFFFFFFFF) as u32; raw_pin_exec_ctrl &= (reserved_bits >> 32) as u32; - let pin_exec_ctrl = vmcs::controls::PinBasedVmExecutionControls::from(raw_pin_exec_ctrl); - //pin_exec_ctrl.set_external_interrupt_exiting(false); + let mut pin_exec_ctrl = vmcs::controls::PinBasedVmExecutionControls::from(raw_pin_exec_ctrl); + pin_exec_ctrl.set_external_interrupt_exiting(false); pin_exec_ctrl.write()?; @@ -55,6 +58,9 @@ pub fn setup_exec_controls() -> Result<(), &'static str> { secondary_exec_ctrl.write()?; + vmwrite(x86::vmx::vmcs::control::CR0_GUEST_HOST_MASK, u64::MAX)?; + vmwrite(x86::vmx::vmcs::control::CR4_GUEST_HOST_MASK, u64::MAX)?; + Ok(()) } @@ -101,7 +107,13 @@ pub fn setup_exit_controls() -> Result<(), &'static str> { exit_ctrl.write()?; - //vmwrite(0x4004, 1u64 << 6)?; // EXCEPTION_BITMAP + /*vmwrite( + 0x4004, + 1u64 << x86::irq::DOUBLE_FAULT_VECTOR + | 1u64 << x86::irq::GENERAL_PROTECTION_FAULT_VECTOR + | 1u64 << x86::irq::PAGE_FAULT_VECTOR + | 1u64 << x86::irq::X87_FPU_VECTOR, + )?;*/ Ok(()) } diff --git a/nel_os_kernel/src/vmm/x86_64/intel/msr.rs b/nel_os_kernel/src/vmm/x86_64/intel/msr.rs index 84b7630..644e747 100644 --- a/nel_os_kernel/src/vmm/x86_64/intel/msr.rs +++ b/nel_os_kernel/src/vmm/x86_64/intel/msr.rs @@ -101,8 +101,6 @@ pub fn update_msrs(vcpu: &mut IntelVCpu) -> Result<(), MsrError> { .map(|entry| entry.index) .collect(); - info!("1"); - for index in indices_to_update { info!("{}", index); let value = read_msr(index); @@ -110,25 +108,21 @@ pub fn update_msrs(vcpu: &mut IntelVCpu) -> Result<(), MsrError> { vcpu.host_msr.set_by_index(index, value).unwrap(); } - info!("2"); vmwrite( vmcs::control::VMEXIT_MSR_LOAD_COUNT, vcpu.host_msr.saved_ents().len() as u64, ) .unwrap(); - info!("3"); vmwrite( vmcs::control::VMEXIT_MSR_STORE_COUNT, vcpu.guest_msr.saved_ents().len() as u64, ) .unwrap(); - info!("4"); vmwrite( vmcs::control::VMENTRY_MSR_LOAD_COUNT, vcpu.guest_msr.saved_ents().len() as u64, ) .unwrap(); - info!("5"); Ok(()) } diff --git a/nel_os_kernel/src/vmm/x86_64/intel/vcpu.rs b/nel_os_kernel/src/vmm/x86_64/intel/vcpu.rs index 9a863a4..185f5ff 100644 --- a/nel_os_kernel/src/vmm/x86_64/intel/vcpu.rs +++ b/nel_os_kernel/src/vmm/x86_64/intel/vcpu.rs @@ -93,6 +93,32 @@ impl IntelVCpu { info!("EPT Violation at guest address: {:#x}", guest_address); return Err("EPT Violation"); } + VmxExitReason::TRIPLE_FAULT => { + info!("Triple fault detected"); + return Err("Triple fault"); + } + VmxExitReason::EXCEPTION => { + let vmexit_intr_info = vmread(vmcs::ro::VMEXIT_INTERRUPTION_INFO)?; + let vector = (vmexit_intr_info & 0xFF) as u8; + let error_code = (vmexit_intr_info >> 8) & 0b111; + let error_code_valid = (vmexit_intr_info >> 11) & 0b1 != 0; + + let idt_vectoring_info = vmread(vmcs::ro::IDT_VECTORING_INFO)?; + info!("idt valid: {}", idt_vectoring_info >> 31 & 0b1 != 0); + + let rip = vmread(vmcs::guest::RIP)?; + let hpa = self.ept.get_phys_addr(rip).unwrap(); + + if error_code_valid { + info!( + "VM exit due to exception: vector {}, error code {}, at RIP {:#x} (hpa: {:#x})", + vector, error_code, rip, hpa + ); + } else { + info!("VM exit due to exception: vector {}", vector); + } + return Err("VM exit due to exception"); + } _ => { info!("VM exit reason: {:?}", exit_reason); return Err("Unhandled VM exit reason"); @@ -114,8 +140,6 @@ impl IntelVCpu { } fn vmentry(&mut self) -> Result<(), InstructionError> { - msr::update_msrs(self).unwrap(); - auditor::controls::check_vmcs_control_fields().unwrap(); let success = { @@ -233,14 +257,18 @@ impl IntelVCpu { fn setup_guest_state(&mut self) -> Result<(), &'static str> { use x86::{controlregs::*, vmx::vmcs}; - let cr0 = Cr0::empty() + let cr0 = (Cr0::empty() | Cr0::CR0_PROTECTED_MODE - | Cr0::CR0_NUMERIC_ERROR & !Cr0::CR0_ENABLE_PAGING; + | Cr0::CR0_NUMERIC_ERROR + | Cr0::CR0_EXTENSION_TYPE) + & !Cr0::CR0_ENABLE_PAGING; vmwrite(vmcs::guest::CR0, cr0.bits() as u64)?; - vmwrite(vmcs::guest::CR3, unsafe { cr3() })?; + vmwrite(vmcs::guest::CR3, 0)?; vmwrite( vmcs::guest::CR4, - vmread(vmcs::guest::CR4)? & !Cr4Flags::VIRTUAL_MACHINE_EXTENSIONS.bits(), + vmread(vmcs::guest::CR4)? + | Cr4Flags::VIRTUAL_MACHINE_EXTENSIONS.bits() + & !Cr4Flags::PHYSICAL_ADDRESS_EXTENSION.bits(), )?; vmwrite(vmcs::guest::CS_BASE, 0)?;