From: Richard Henderson <[email protected]> The hvf_slot structure is a poor replacement for properly looking up a memory region in the address space. Use memory_region_get_dirty_log_mask instead of HVF_SLOT_LOG.
Signed-off-by: Richard Henderson <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- target/i386/hvf/hvf.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index de06ec6125f..d0ee00425f0 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -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,9 +160,6 @@ 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))) { return true; @@ -764,7 +765,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) && @@ -772,9 +772,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); -- 2.51.0
