From 53c3c47efa78434be55e416af1e77abaa2baf4cd Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 14 Jan 2020 07:04:15 -0500 Subject: [PATCH] tcg: Make probe_write() return a pointer to the host page ... similar to tlb_vaddr_to_host(); however, allow access to the host page except when TLB_NOTDIRTY or TLB_MMIO is set. Backports commit fef39ccd567032d3ad520ed80f3576068e6eb2e3 from qemu --- qemu/accel/tcg/cputlb.c | 21 ++++++++++++++++----- qemu/include/exec/exec-all.h | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/qemu/accel/tcg/cputlb.c b/qemu/accel/tcg/cputlb.c index 3aab7432..edc58b81 100644 --- a/qemu/accel/tcg/cputlb.c +++ b/qemu/accel/tcg/cputlb.c @@ -706,11 +706,11 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry, /* Probe for whether the specified guest write access is permitted. * If it is not permitted then an exception will be taken in the same * way as if this were a real write access (and we will not return). - * Otherwise the function will return, and there will be a valid - * entry in the TLB for this access. + * If the size is 0 or the page requires I/O access, returns NULL; otherwise, + * returns the address of the host page similar to tlb_vaddr_to_host(). */ -void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx, - uintptr_t retaddr) +void *probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx, + uintptr_t retaddr) { uintptr_t index = tlb_index(env, mmu_idx, addr); CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); @@ -729,12 +729,23 @@ void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx, tlb_addr = tlb_addr_write(entry); } + if (!size) { + return NULL; + } + /* Handle watchpoints. */ - if ((tlb_addr & TLB_WATCHPOINT) && size > 0) { + if (tlb_addr & TLB_WATCHPOINT) { cpu_check_watchpoint(env_cpu(env), addr, size, env->iotlb[mmu_idx][index].attrs, BP_MEM_WRITE, retaddr); } + + if (tlb_addr & (TLB_NOTDIRTY | TLB_MMIO)) { + /* I/O access */ + return NULL; + } + + return (void *)((uintptr_t)addr + entry->addend); } void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, diff --git a/qemu/include/exec/exec-all.h b/qemu/include/exec/exec-all.h index 3f0b6810..dac5e77d 100644 --- a/qemu/include/exec/exec-all.h +++ b/qemu/include/exec/exec-all.h @@ -213,8 +213,8 @@ static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr) } #endif -void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx, - uintptr_t retaddr); +void *probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx, + uintptr_t retaddr); #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */