summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2012-05-25 05:28:14 +0000
committeralc <alc@FreeBSD.org>2012-05-25 05:28:14 +0000
commit0413b090c36a77e50e7252af0a74230ef368bb3a (patch)
treec62a6c2868646c4862d1a52d723795c8c6f56478
parentd6bb741dfb281f0bbb1d8e2e4c57dd471d1bf910 (diff)
downloadFreeBSD-src-0413b090c36a77e50e7252af0a74230ef368bb3a.zip
FreeBSD-src-0413b090c36a77e50e7252af0a74230ef368bb3a.tar.gz
Correct an error in pmap_pv_reclaim(). In a rare case, when it should have
returned NULL, it might instead return a pointer to a page that it had just unmapped.
-rw-r--r--sys/amd64/amd64/pmap.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index b98aca4..ccc431c 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -2058,14 +2058,14 @@ pmap_pv_reclaim(pmap_t locked_pmap)
pt_entry_t *pte, tpte;
pv_entry_t pv;
vm_offset_t va;
- vm_page_t free, m;
+ vm_page_t free, m, m_pc;
uint64_t inuse, freemask;
int bit, field, freed;
rw_assert(&pvh_global_lock, RA_WLOCKED);
PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED);
pmap = NULL;
- free = m = NULL;
+ free = m_pc = NULL;
TAILQ_INIT(&newtail);
while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL && free == NULL) {
TAILQ_REMOVE(&pv_chunks, pc, pc_lru);
@@ -2141,8 +2141,8 @@ pmap_pv_reclaim(pmap_t locked_pmap)
PV_STAT(pc_chunk_count--);
PV_STAT(pc_chunk_frees++);
/* Entire chunk is free; return it. */
- m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
- dump_drop_page(m->phys_addr);
+ m_pc = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
+ dump_drop_page(m_pc->phys_addr);
break;
}
TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
@@ -2157,15 +2157,15 @@ pmap_pv_reclaim(pmap_t locked_pmap)
if (pmap != locked_pmap)
PMAP_UNLOCK(pmap);
}
- if (m == NULL && free != NULL) {
- m = free;
- free = m->right;
+ if (m_pc == NULL && free != NULL) {
+ m_pc = free;
+ free = m_pc->right;
/* Recycle a freed page table page. */
- m->wire_count = 1;
+ m_pc->wire_count = 1;
atomic_add_int(&cnt.v_wire_count, 1);
}
pmap_free_zero_pages(free);
- return (m);
+ return (m_pc);
}
/*
OpenPOWER on IntegriCloud