summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-08-19 18:20:34 +0000
committeralc <alc@FreeBSD.org>2003-08-19 18:20:34 +0000
commitb97ad4e18b7c77b56c1de1f9c206f356ae087f58 (patch)
treef92a99ad82820b45792533ba4dc6524a660b71e0
parentcd52f17217f177a388beea838368fa98b1bf40c2 (diff)
downloadFreeBSD-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.c15
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);
OpenPOWER on IntegriCloud