diff options
author | alc <alc@FreeBSD.org> | 2006-06-12 20:05:27 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2006-06-12 20:05:27 +0000 |
commit | cbeb562815398b1216c1fe31e797c1b9cc57c0d9 (patch) | |
tree | 6c4218401ed8b7316956ab9f5c3dced0f8ef234a /sys/amd64 | |
parent | 6e19662308c05d28a5b7beffb8780a58561b0a9f (diff) | |
download | FreeBSD-src-cbeb562815398b1216c1fe31e797c1b9cc57c0d9.zip FreeBSD-src-cbeb562815398b1216c1fe31e797c1b9cc57c0d9.tar.gz |
Don't invalidate the TLB in pmap_qenter() unless the old mapping was valid.
Most often, it isn't.
Reviewed by: tegge@
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 7c0e102..9206f7d 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) -{ - vm_offset_t va; - - va = sva; - while (count-- > 0) { - pmap_kenter(va, VM_PAGE_TO_PHYS(*m)); - va += PAGE_SIZE; - m++; +pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) +{ + pt_entry_t *endpte, oldpte, *pte; + + 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); } /* |