@ -119,9 +119,12 @@ void hvf_handle_io(CPUState *env, uint16_t port, void *buffer,
}
}
static bool ept_emulation_fault ( hvf_slot * slot , uint64_t gpa , uint64_t ept_qual )
static bool ept_emulation_fault ( CPUState * cs , uint64_t gpa , uint64_t ept_qual )
{
int read , write ;
bool read , write ;
MemoryRegion * mr ;
hwaddr gpa_page = gpa & qemu_real_host_page_mask ( ) ;
hwaddr xlat ;
/* EPT fault on an instruction fetch doesn't make sense here */
if ( ept_qual & EPT_VIOLATION_INST_FETCH ) {
@ -129,21 +132,22 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
}
/* EPT fault must be a read fault or a write fault */
read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0 ;
write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0 ;
if ( ( read | write ) = = 0 ) {
read = ept_qual & EPT_VIOLATION_DATA_READ ;
write = ept_qual & EPT_VIOLATION_DATA_WRITE ;
if ( ! read & & ! write ) {
return false ;
}
if ( write & & slot ) {
if ( slot - > flags & HVF_SLOT_LOG ) {
uintptr_t page_size = qemu_real_host_page_size ( ) ;
intptr_t page_mask = - ( intptr_t ) page_size ;
uint64_t dirty_page_start = gpa & page_mask ;
mr = address_space_translate ( cpu_get_address_space ( cs , X86ASIdx_MEM ) ,
gpa_page , & xlat , NULL , write ,
MEMTXATTRS_UNSPECIFIED ) ;
memory_region_set_dirty ( slot - > region , gpa - slot - > start , 1 ) ;
hvf_unprotect_dirty_range ( dirty_page_start , page_size ) ;
}
/* Handle dirty page logging for ram. */
if ( write & & memory_region_get_dirty_log_mask ( mr ) ) {
uintptr_t page_size = qemu_real_host_page_size ( ) ;
memory_region_set_dirty ( mr , gpa_page + xlat , page_size ) ;
hvf_unprotect_dirty_range ( gpa_page , page_size ) ;
}
/*
@ -156,11 +160,8 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
return false ;
}
if ( ! slot ) {
return true ;
}
if ( ! memory_region_is_ram ( slot - > region ) & &
! ( read & & memory_region_is_romd ( slot - > region ) ) ) {
if ( ! memory_region_is_ram ( mr ) & &
! ( read & & memory_region_is_romd ( mr ) ) ) {
return true ;
}
return false ;
@ -765,7 +766,6 @@ static int hvf_handle_vmexit(CPUState *cpu)
/* Need to check if MMIO or unmapped fault */
case EXIT_REASON_EPT_FAULT :
{
hvf_slot * slot ;
uint64_t gpa = rvmcs ( cpu - > accel - > fd , VMCS_GUEST_PHYSICAL_ADDRESS ) ;
if ( ( ( idtvec_info & VMCS_IDT_VEC_VALID ) = = 0 ) & &
@ -773,9 +773,8 @@ static int hvf_handle_vmexit(CPUState *cpu)
vmx_set_nmi_blocking ( cpu ) ;
}
slot = hvf_find_overlap_slot ( gpa , 1 ) ;
/* mmio */
if ( ept_emulation_fault ( slot , gpa , exit_qual ) ) {
if ( ept_emulation_fault ( cpu , gpa , exit_qual ) ) {
struct x86_decode decode ;
hvf_load_regs ( cpu ) ;