Index: sys/vm/vm_reserv.c =================================================================== --- sys/vm/vm_reserv.c +++ sys/vm/vm_reserv.c @@ -1207,21 +1207,27 @@ vm_reserv_test_contig(vm_reserv_t rv, u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary) { - vm_paddr_t pa, size; - u_long changes; - int bitpos, bits_left, i, hi, lo, n; + vm_paddr_t bound, pa, size; + u_long changes, hi, lo; + int bitpos, bits_left, i, n; vm_reserv_assert_locked(rv); size = npages << PAGE_SHIFT; pa = VM_PAGE_TO_PHYS(&rv->pages[0]); - lo = (pa < low) ? + KASSERT(npages < VM_LEVEL_0_NPAGES, + ("%s: page count too high", __func__)); + KASSERT(pa + VM_LEVEL_0_SIZE - size >= low, + ("%s: reservation is too low", __func__)); + bound = (pa < low) ? ((low + PAGE_MASK - pa) >> PAGE_SHIFT) : 0; - i = lo / NBPOPMAP; - changes = rv->popmap[i] | ((1UL << (lo % NBPOPMAP)) - 1); - hi = (pa + VM_LEVEL_0_SIZE > high) ? - ((high + PAGE_MASK - pa) >> PAGE_SHIFT) : VM_LEVEL_0_NPAGES; - n = hi / NBPOPMAP; - bits_left = hi % NBPOPMAP; + i = bound / NBPOPMAP; + changes = rv->popmap[i] | ((1UL << (bound % NBPOPMAP)) - 1); + KASSERT(pa + size <= high, + ("%s: reservation is too high", __func__)); + bound = (pa + VM_LEVEL_0_SIZE > high) ? + ((high - pa) >> PAGE_SHIFT) : VM_LEVEL_0_NPAGES; + n = bound / NBPOPMAP; + bits_left = bound % NBPOPMAP; hi = lo = -1; for (;;) { /* @@ -1261,7 +1267,7 @@ return (false); pa = VM_PAGE_TO_PHYS(&rv->pages[lo]); } - if (lo * PAGE_SIZE + size <= hi * PAGE_SIZE) + if (lo < hi && npages <= hi - lo) return (true); lo = hi; }