diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2019-09-18 09:15:44 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2019-09-25 10:43:22 -0700 |
commit | 08565552f70ca37da13f24928727f851073cd13e (patch) | |
tree | 95cbe6f260f0e0bf9dc74eb590a46c64b8bd99df /accel | |
parent | 7b0d792ce13c0e894ee32a94b321b329724c9a25 (diff) | |
download | qemu-08565552f70ca37da13f24928727f851073cd13e.zip qemu-08565552f70ca37da13f24928727f851073cd13e.tar.gz qemu-08565552f70ca37da13f24928727f851073cd13e.tar.bz2 |
cputlb: Move NOTDIRTY handling from I/O path to TLB path
Pages that we want to track for NOTDIRTY are RAM. We do not
really need to go through the I/O path to handle them.
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel')
-rw-r--r-- | accel/tcg/cputlb.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 404ec57..7e9a0f7 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -905,7 +905,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry, mr = section->mr; mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr; cpu->mem_io_pc = retaddr; - if (mr != &io_mem_notdirty && !cpu->can_do_io) { + if (!cpu->can_do_io) { cpu_io_recompile(cpu, retaddr); } @@ -946,7 +946,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry, section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs); mr = section->mr; mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr; - if (mr != &io_mem_notdirty && !cpu->can_do_io) { + if (!cpu->can_do_io) { cpu_io_recompile(cpu, retaddr); } cpu->mem_io_vaddr = addr; @@ -1612,7 +1612,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, need_swap = size > 1 && (tlb_addr & TLB_BSWAP); /* Handle I/O access. */ - if (likely(tlb_addr & (TLB_MMIO | TLB_NOTDIRTY))) { + if (tlb_addr & TLB_MMIO) { io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, op ^ (need_swap * MO_BSWAP)); return; @@ -1625,6 +1625,26 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, haddr = (void *)((uintptr_t)addr + entry->addend); + /* Handle clean RAM pages. */ + if (tlb_addr & TLB_NOTDIRTY) { + NotDirtyInfo ndi; + + /* We require mem_io_pc in tb_invalidate_phys_page_range. */ + env_cpu(env)->mem_io_pc = retaddr; + + memory_notdirty_write_prepare(&ndi, env_cpu(env), addr, + addr + iotlbentry->addr, size); + + if (unlikely(need_swap)) { + store_memop(haddr, val, op ^ MO_BSWAP); + } else { + store_memop(haddr, val, op); + } + + memory_notdirty_write_complete(&ndi); + return; + } + /* * Keep these two store_memop separate to ensure that the compiler * is able to fold the entire function to a single instruction. |