From b74a62d602dab876ec97088d240508a3f29ebcfe Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 12 Jun 2006 20:05:27 +0000 Subject: [PATCH] Don't invalidate the TLB in pmap_qenter() unless the old mapping was valid. Most often, it isn't. Reviewed by: tegge@ --- sys/amd64/amd64/pmap.c | 21 +++++++++++++-------- sys/i386/i386/pmap.c | 21 +++++++++++++-------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 7c0e1021dc31..9206f7d21920 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1006,17 +1006,22 @@ pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) * Note: SMP coherent. Uses a ranged shootdown IPI. */ void -pmap_qenter(vm_offset_t sva, vm_page_t *m, int count) +pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) { - vm_offset_t va; + pt_entry_t *endpte, oldpte, *pte; - va = sva; - while (count-- > 0) { - pmap_kenter(va, VM_PAGE_TO_PHYS(*m)); - va += PAGE_SIZE; - m++; + oldpte = 0; + pte = vtopte(sva); + endpte = pte + count; + while (pte < endpte) { + oldpte |= *pte; + pte_store(pte, VM_PAGE_TO_PHYS(*ma) | PG_G | PG_RW | PG_V); + pte++; + ma++; } - pmap_invalidate_range(kernel_pmap, sva, va); + if ((oldpte & PG_V) != 0) + pmap_invalidate_range(kernel_pmap, sva, sva + count * + PAGE_SIZE); } /* diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index dc0f657c2d9e..86afaee971a2 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -1057,17 +1057,22 @@ pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) * Note: SMP coherent. Uses a ranged shootdown IPI. */ void -pmap_qenter(vm_offset_t sva, vm_page_t *m, int count) +pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) { - vm_offset_t va; + pt_entry_t *endpte, oldpte, *pte; - va = sva; - while (count-- > 0) { - pmap_kenter(va, VM_PAGE_TO_PHYS(*m)); - va += PAGE_SIZE; - m++; + oldpte = 0; + pte = vtopte(sva); + endpte = pte + count; + while (pte < endpte) { + oldpte |= *pte; + pte_store(pte, VM_PAGE_TO_PHYS(*ma) | pgeflag | PG_RW | PG_V); + pte++; + ma++; } - pmap_invalidate_range(kernel_pmap, sva, va); + if ((oldpte & PG_V) != 0) + pmap_invalidate_range(kernel_pmap, sva, sva + count * + PAGE_SIZE); } /*