diff options
author | alc <alc@FreeBSD.org> | 2003-08-19 18:20:34 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-08-19 18:20:34 +0000 |
commit | b97ad4e18b7c77b56c1de1f9c206f356ae087f58 (patch) | |
tree | f92a99ad82820b45792533ba4dc6524a660b71e0 | |
parent | cd52f17217f177a388beea838368fa98b1bf40c2 (diff) | |
download | FreeBSD-src-b97ad4e18b7c77b56c1de1f9c206f356ae087f58.zip FreeBSD-src-b97ad4e18b7c77b56c1de1f9c206f356ae087f58.tar.gz |
Eliminate a possible race condition for multithreaded applications in
_pmap_allocpte(): Guarantee that the page table page is zero filled before
adding it to the directory. Otherwise, a 2nd, 3rd, etc. thread could
access a nearby virtual address and use garbage for the address
translation.
Discussed with: peter, tegge
-rw-r--r-- | sys/i386/i386/pmap.c | 15 |
1 files changed, 2 insertions, 13 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index ec5559a..50f181b 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -1165,7 +1165,6 @@ _pmap_allocpte(pmap, ptepindex) unsigned ptepindex; { vm_paddr_t ptepa; - vm_offset_t pteva; vm_page_t m; /* @@ -1174,6 +1173,8 @@ _pmap_allocpte(pmap, ptepindex) VM_OBJECT_LOCK(pmap->pm_pteobj); m = vm_page_grab(pmap->pm_pteobj, ptepindex, VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); + if ((m->flags & PG_ZERO) == 0) + pmap_zero_page(m); KASSERT(m->queue == PQ_NONE, ("_pmap_allocpte: %p->queue != PQ_NONE", m)); @@ -1195,18 +1196,6 @@ _pmap_allocpte(pmap, ptepindex) pmap->pm_pdir[ptepindex] = (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_A | PG_M); - /* - * Try to use the new mapping, but if we cannot, then - * do it with the routine that maps the page explicitly. - */ - if ((m->flags & PG_ZERO) == 0) { - if (pmap_is_current(pmap)) { - pteva = VM_MAXUSER_ADDRESS + i386_ptob(ptepindex); - bzero((caddr_t) pteva, PAGE_SIZE); - } else { - pmap_zero_page(m); - } - } vm_page_lock_queues(); m->valid = VM_PAGE_BITS_ALL; vm_page_flag_clear(m, PG_ZERO); |