summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2010-12-01 03:35:19 +0000
committeralc <alc@FreeBSD.org>2010-12-01 03:35:19 +0000
commit9ebc09a72f97f4d9120b8386a7ecb5cc107be5e5 (patch)
tree7b50d41d49e40321a7bb604e3613a5527afb664c
parentbc2682b97b76f566f657795f57da6991d671a208 (diff)
downloadFreeBSD-src-9ebc09a72f97f4d9120b8386a7ecb5cc107be5e5.zip
FreeBSD-src-9ebc09a72f97f4d9120b8386a7ecb5cc107be5e5.tar.gz
Correct an error in the allocation of the vm_page_dump array in
vm_page_startup(). Specifically, the dump_avail array should be used instead of the phys_avail array to calculate the size of vm_page_dump. For example, the pages for the message buffer are allocated prior to vm_page_startup() by subtracting them from the last entry in the phys_avail array, but the first thing that vm_page_startup() does after creating the vm_page_dump array is to set the bits corresponding to the message buffer pages in that array. However, these bits might not actually exist in the array, because the size of the array is determined by the current value in the last entry of the phys_avail array. In general, the only reason why this doesn't always result in an out-of-bounds array access is that the size of the vm_page_dump array is rounded up to the next page boundary. This change eliminates that dependence on rounding (and luck). MFC after: 6 weeks
-rw-r--r--sys/vm/vm_page.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index ac6c791..863b842 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -282,7 +282,6 @@ vm_page_startup(vm_offset_t vaddr)
vm_paddr_t new_end;
int i;
vm_paddr_t pa;
- int nblocks;
vm_paddr_t last_pa;
char *list;
@@ -294,7 +293,6 @@ vm_page_startup(vm_offset_t vaddr)
biggestsize = 0;
biggestone = 0;
- nblocks = 0;
vaddr = round_page(vaddr);
for (i = 0; phys_avail[i + 1]; i += 2) {
@@ -316,7 +314,6 @@ vm_page_startup(vm_offset_t vaddr)
low_water = phys_avail[i];
if (phys_avail[i + 1] > high_water)
high_water = phys_avail[i + 1];
- ++nblocks;
}
#ifdef XEN
@@ -372,7 +369,11 @@ vm_page_startup(vm_offset_t vaddr)
* minidump code. In theory, they are not needed on i386, but are
* included should the sf_buf code decide to use them.
*/
- page_range = phys_avail[(nblocks - 1) * 2 + 1] / PAGE_SIZE;
+ last_pa = 0;
+ for (i = 0; dump_avail[i + 1] != 0; i += 2)
+ if (dump_avail[i + 1] > last_pa)
+ last_pa = dump_avail[i + 1];
+ page_range = last_pa / PAGE_SIZE;
vm_page_dump_size = round_page(roundup2(page_range, NBBY) / NBBY);
new_end -= vm_page_dump_size;
vm_page_dump = (void *)(uintptr_t)pmap_map(&vaddr, new_end,
OpenPOWER on IntegriCloud