From d4c430a80f000d722bb70287af4d4c184a8d7006 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Wed, 17 Mar 2010 02:14:28 +0000 Subject: Large page TLB flush QEMU uses a fixed page size for the CPU TLB. If the guest uses large pages then we effectively split these into multiple smaller pages, and populate the corresponding TLB entries on demand. When the guest invalidates the TLB by virtual address we must invalidate all entries covered by the large page. However the address used to invalidate the entry may not be present in the QEMU TLB, so we do not know which regions to clear. Implementing a full vaiable size TLB is hard and slow, so just keep a simple address/mask pair to record which addresses may have been mapped by large pages. If the guest invalidates this region then flush the whole TLB. Signed-off-by: Paul Brook --- target-i386/helper.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'target-i386') diff --git a/target-i386/helper.c b/target-i386/helper.c index 05758f9bfe..35ab72090a 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -531,14 +531,13 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, -1 = cannot handle fault 0 = nothing more to do 1 = generate PF fault - 2 = soft MMU activation required for this block */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, int is_write1, int mmu_idx, int is_softmmu) { uint64_t ptep, pte; target_ulong pde_addr, pte_addr; - int error_code, is_dirty, prot, page_size, ret, is_write, is_user; + int error_code, is_dirty, prot, page_size, is_write, is_user; target_phys_addr_t paddr; uint32_t page_offset; target_ulong vaddr, virt_addr; @@ -799,8 +798,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, paddr = (pte & TARGET_PAGE_MASK) + page_offset; vaddr = virt_addr + page_offset; - ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); - return ret; + tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size); + return 0; do_fault_protect: error_code = PG_ERROR_P_MASK; do_fault: -- cgit v1.2.3