diff --git a/src/vmm/msr.rs b/src/vmm/msr.rs index 0394d9c..90eeecf 100644 --- a/src/vmm/msr.rs +++ b/src/vmm/msr.rs @@ -7,6 +7,8 @@ use x86::vmx::vmcs; use x86_64::structures::paging::{OffsetPageTable, Translate}; use x86_64::{PhysAddr, VirtAddr}; +use crate::info; + use super::vcpu::VCpu; type MsrIndex = u32; @@ -132,7 +134,7 @@ impl ShadowMsr { // Lock bit (0) | Enable VMX inside SMX (1) | Enable VMX outside SMX (2) Self::set_ret_val(vcpu, 0x5) } - 0x48 => Self::set_ret_val(vcpu, 0), // IA32_SPEC_CTRL + 0x48 => Self::set_ret_val(vcpu, 0), // IA32_SPEC_CTRL 0x122 => Self::set_ret_val(vcpu, 0), // IA32_TSX_CTRL 0x560 => Self::set_ret_val(vcpu, 0), // IA32_RTIT_OUTPUT_BASE 0x561 => Self::set_ret_val(vcpu, 0), // IA32_RTIT_OUTPUT_MASK_PTRS @@ -158,15 +160,15 @@ impl ShadowMsr { x86::msr::IA32_LSTAR => Self::shadow_read(vcpu, msr_kind), x86::msr::IA32_CSTAR => Self::shadow_read(vcpu, msr_kind), x86::msr::IA32_FMASK => Self::shadow_read(vcpu, msr_kind), - x86::msr::SYSENTER_CS_MSR => { - Self::set_ret_val(vcpu, unsafe { vmread(vmcs::guest::IA32_SYSENTER_CS).unwrap() }) - } - x86::msr::SYSENTER_ESP_MSR => { - Self::set_ret_val(vcpu, unsafe { vmread(vmcs::guest::IA32_SYSENTER_ESP).unwrap() }) - } - x86::msr::SYSENTER_EIP_MSR => { - Self::set_ret_val(vcpu, unsafe { vmread(vmcs::guest::IA32_SYSENTER_EIP).unwrap() }) - } + x86::msr::SYSENTER_CS_MSR => Self::set_ret_val(vcpu, unsafe { + vmread(vmcs::guest::IA32_SYSENTER_CS).unwrap() + }), + x86::msr::SYSENTER_ESP_MSR => Self::set_ret_val(vcpu, unsafe { + vmread(vmcs::guest::IA32_SYSENTER_ESP).unwrap() + }), + x86::msr::SYSENTER_EIP_MSR => Self::set_ret_val(vcpu, unsafe { + vmread(vmcs::guest::IA32_SYSENTER_EIP).unwrap() + }), 0x1b => Self::shadow_read(vcpu, msr_kind), 0x8b => Self::set_ret_val(vcpu, 0x8701021), 0xc0011029 => Self::set_ret_val(vcpu, 0x3000310e08202), @@ -179,10 +181,10 @@ impl ShadowMsr { 0xc0010117 => Self::set_ret_val(vcpu, 0), // MSR_VM_HSAVE_PA 0x277 => Self::set_ret_val(vcpu, 0x0007040600070406), 0xc0000103 => Self::shadow_read(vcpu, msr_kind), // TSC_AUX - 0xd90 => Self::set_ret_val(vcpu, 0), // MSR_C1_PMON_EVNT_SEL0 - 0xe1 => Self::set_ret_val(vcpu, 0), // IA32_UMWAIT_CONTROL - 0x1c4 => Self::set_ret_val(vcpu, 0), // Unknown MSR - 0x1c5 => Self::set_ret_val(vcpu, 0), // Unknown MSR + 0xd90 => Self::set_ret_val(vcpu, 0), // MSR_C1_PMON_EVNT_SEL0 + 0xe1 => Self::set_ret_val(vcpu, 0), // IA32_UMWAIT_CONTROL + 0x1c4 => Self::set_ret_val(vcpu, 0), // Unknown MSR + 0x1c5 => Self::set_ret_val(vcpu, 0), // Unknown MSR _ => { panic!("Unhandled RDMSR: {:#x}", msr_kind); } @@ -218,11 +220,17 @@ impl ShadowMsr { x86::msr::SYSENTER_ESP_MSR => unsafe { vmwrite(vmcs::guest::IA32_SYSENTER_ESP, value).unwrap() }, - x86::msr::IA32_EFER => unsafe { vmwrite(vmcs::guest::IA32_EFER_FULL, value).unwrap() }, + x86::msr::IA32_EFER => { + info!("Setting IA32_EFER: {:#x}", value); + if value == 0xd01 || value == 0x100 { + unsafe { vmwrite(vmcs::guest::IA32_EFER_FULL, value).unwrap() } + } + } x86::msr::IA32_FS_BASE => unsafe { vmwrite(vmcs::guest::FS_BASE, value).unwrap() }, x86::msr::IA32_GS_BASE => unsafe { vmwrite(vmcs::guest::GS_BASE, value).unwrap() }, 0x1b => Self::shadow_write(vcpu, msr_kind), 0xc0010007 => Self::shadow_write(vcpu, msr_kind), + 0xc0010117 => Self::shadow_write(vcpu, msr_kind), _ => { panic!("Unhandled WRMSR: {:#x}", msr_kind); diff --git a/src/vmm/vcpu.rs b/src/vmm/vcpu.rs index 8a3de8d..afd27f9 100644 --- a/src/vmm/vcpu.rs +++ b/src/vmm/vcpu.rs @@ -369,6 +369,7 @@ impl VCpu { .unwrap(); self.guest_msr.set(0x1b, 0).unwrap(); self.guest_msr.set(0xc0010007, 0).unwrap(); + self.guest_msr.set(0xc0010117, 0).unwrap(); vmwrite( vmcs::control::VMEXIT_MSR_LOAD_ADDR_FULL, @@ -1017,7 +1018,7 @@ impl VCpu { if let Err(e) = self.ept.map_4k(gpa, hpa, frame_allocator) { panic!("Failed to map page at GPA {:#x}: {}", gpa, e); } - + // Invalidate EPT after mapping new page // Note: INVEPT might not be available on all processors use crate::vmm::invlpg::invept_single_context; @@ -1061,44 +1062,57 @@ impl VCpu { 33 => { info!(" Reason: VM-entry failure due to invalid guest state"); // Read VM-instruction error for more details - let vm_instruction_error = unsafe { - vmread(vmcs::ro::VM_INSTRUCTION_ERROR).unwrap_or(0) - }; + let vm_instruction_error = + unsafe { vmread(vmcs::ro::VM_INSTRUCTION_ERROR).unwrap_or(0) }; info!(" VM-instruction error: {}", vm_instruction_error); - + // Dump guest state for debugging unsafe { info!(" Guest state dump:"); - info!(" CS: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", - vmread(vmcs::guest::CS_SELECTOR).unwrap(), - vmread(vmcs::guest::CS_BASE).unwrap(), - vmread(vmcs::guest::CS_LIMIT).unwrap(), - vmread(vmcs::guest::CS_ACCESS_RIGHTS).unwrap()); - info!(" SS: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", - vmread(vmcs::guest::SS_SELECTOR).unwrap(), - vmread(vmcs::guest::SS_BASE).unwrap(), - vmread(vmcs::guest::SS_LIMIT).unwrap(), - vmread(vmcs::guest::SS_ACCESS_RIGHTS).unwrap()); - info!(" DS: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", - vmread(vmcs::guest::DS_SELECTOR).unwrap(), - vmread(vmcs::guest::DS_BASE).unwrap(), - vmread(vmcs::guest::DS_LIMIT).unwrap(), - vmread(vmcs::guest::DS_ACCESS_RIGHTS).unwrap()); - info!(" ES: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", - vmread(vmcs::guest::ES_SELECTOR).unwrap(), - vmread(vmcs::guest::ES_BASE).unwrap(), - vmread(vmcs::guest::ES_LIMIT).unwrap(), - vmread(vmcs::guest::ES_ACCESS_RIGHTS).unwrap()); - info!(" RIP={:#x}, RSP={:#x}, RFLAGS={:#x}", - vmread(vmcs::guest::RIP).unwrap(), - vmread(vmcs::guest::RSP).unwrap(), - vmread(vmcs::guest::RFLAGS).unwrap()); - info!(" CR0={:#x}, CR3={:#x}, CR4={:#x}", - vmread(vmcs::guest::CR0).unwrap(), - vmread(vmcs::guest::CR3).unwrap(), - vmread(vmcs::guest::CR4).unwrap()); - info!(" EFER={:#x}", - vmread(vmcs::guest::IA32_EFER_FULL).unwrap()); + info!( + " CS: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", + vmread(vmcs::guest::CS_SELECTOR).unwrap(), + vmread(vmcs::guest::CS_BASE).unwrap(), + vmread(vmcs::guest::CS_LIMIT).unwrap(), + vmread(vmcs::guest::CS_ACCESS_RIGHTS).unwrap() + ); + info!( + " SS: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", + vmread(vmcs::guest::SS_SELECTOR).unwrap(), + vmread(vmcs::guest::SS_BASE).unwrap(), + vmread(vmcs::guest::SS_LIMIT).unwrap(), + vmread(vmcs::guest::SS_ACCESS_RIGHTS).unwrap() + ); + info!( + " DS: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", + vmread(vmcs::guest::DS_SELECTOR).unwrap(), + vmread(vmcs::guest::DS_BASE).unwrap(), + vmread(vmcs::guest::DS_LIMIT).unwrap(), + vmread(vmcs::guest::DS_ACCESS_RIGHTS).unwrap() + ); + info!( + " ES: selector={:#x}, base={:#x}, limit={:#x}, rights={:#x}", + vmread(vmcs::guest::ES_SELECTOR).unwrap(), + vmread(vmcs::guest::ES_BASE).unwrap(), + vmread(vmcs::guest::ES_LIMIT).unwrap(), + vmread(vmcs::guest::ES_ACCESS_RIGHTS).unwrap() + ); + info!( + " RIP={:#x}, RSP={:#x}, RFLAGS={:#x}", + vmread(vmcs::guest::RIP).unwrap(), + vmread(vmcs::guest::RSP).unwrap(), + vmread(vmcs::guest::RFLAGS).unwrap() + ); + info!( + " CR0={:#x}, CR3={:#x}, CR4={:#x}", + vmread(vmcs::guest::CR0).unwrap(), + vmread(vmcs::guest::CR3).unwrap(), + vmread(vmcs::guest::CR4).unwrap() + ); + info!( + " EFER={:#x}", + vmread(vmcs::guest::IA32_EFER_FULL).unwrap() + ); } panic!("VM-entry failure due to invalid guest state"); }