11use alloc:: collections:: VecDeque ;
2+ use axaddrspace:: device:: AccessWidth ;
23use bit_field:: BitField ;
34use core:: fmt:: { Debug , Formatter , Result } ;
45use core:: { arch:: naked_asm, mem:: size_of} ;
@@ -11,7 +12,7 @@ use x86_64::registers::control::{Cr0, Cr0Flags, Cr3, Cr4, Cr4Flags, EferFlags};
1112
1213use axaddrspace:: { GuestPhysAddr , GuestVirtAddr , HostPhysAddr , NestedPageFaultInfo } ;
1314use axerrno:: { AxResult , ax_err, ax_err_type} ;
14- use axvcpu:: { AccessWidth , AxArchVCpu , AxVCpuExitReason , AxVCpuHal } ;
15+ use axvcpu:: { AxArchVCpu , AxVCpuExitReason , AxVCpuHal } ;
1516
1617use super :: VmxExitInfo ;
1718use super :: as_axerr;
@@ -21,6 +22,7 @@ use super::vmcs::{
2122 self , VmcsControl32 , VmcsControl64 , VmcsControlNW , VmcsGuest16 , VmcsGuest32 , VmcsGuest64 ,
2223 VmcsGuestNW , VmcsHost16 , VmcsHost32 , VmcsHost64 , VmcsHostNW ,
2324} ;
25+ use crate :: vmx:: vmcs:: VmcsReadOnly64 ;
2426use crate :: { ept:: GuestPageWalkInfo , msr:: Msr , regs:: GeneralRegisters } ;
2527
2628const VMX_PREEMPTION_TIMER_SET_VALUE : u32 = 1_000_000 ;
@@ -866,6 +868,10 @@ impl<H: AxVCpuHal> VmxVcpu<H> {
866868 rflags as u64 & x86_64:: registers:: rflags:: RFlags :: INTERRUPT_FLAG . bits ( ) != 0
867869 && block_state == 0
868870 }
871+ /// MMIO access information.
872+ pub fn mmio_access_info ( & self ) -> AxResult < vmcs:: MmioAccessInfo > {
873+ vmcs:: mmio_access_info ( )
874+ }
869875
870876 /// Try to inject a pending event before next VM entry.
871877 fn inject_pending_events ( & mut self ) -> AxResult {
@@ -1229,6 +1235,31 @@ impl<H: AxVCpuHal> AxArchVCpu for VmxVcpu<H> {
12291235 }
12301236 }
12311237 }
1238+ VmxExitReason :: EPT_VIOLATION => {
1239+ self . advance_rip ( exit_info. exit_instruction_length as _ ) ?;
1240+ self . advance_rip ( exit_info. exit_instruction_length as _ ) ?;
1241+ let mmio_info = self . mmio_access_info ( ) ;
1242+ error ! ( "VMX EPT Violation: {:#x?} of {:#x?}" , mmio_info, exit_info) ;
1243+ if let Ok ( mmio_info) = mmio_info {
1244+ if mmio_info. is_read {
1245+ self . set_gpr ( 0 , 0x74726976 ) ;
1246+ } else {
1247+ if let Some ( data) = mmio_info. data {
1248+ error ! ( "Data write {:#x}" , data) ;
1249+ } else {
1250+ error ! ( "Data write None" ) ;
1251+ }
1252+ }
1253+ } ;
1254+
1255+ AxVCpuExitReason :: Nothing
1256+ // AxVCpuExitReason::MmioRead {
1257+ // addr: mmio_info.addr,
1258+ // width: mmio_info.access_width,
1259+ // reg: mmio_info.register as usize,
1260+ // reg_width: mmio_info.access_width,
1261+ // }
1262+ }
12321263 _ => {
12331264 warn ! ( "VMX unsupported VM-Exit: {:#x?}" , exit_info) ;
12341265 warn ! ( "VCpu {:#x?}" , self ) ;
0 commit comments