* vm_page_set_validclean: * * Sets portions of a page valid and clean. The arguments are expected * to be DEV_BSIZE aligned but if they aren't the bitmap is inclusive * of any partial chunks touched by the range. The invalid portion of * such chunks will be zero'd. * * (base + size) must be less then or equal to PAGE_SIZE. */
| 5116 | * (base + size) must be less then or equal to PAGE_SIZE. |
| 5117 | */ |
| 5118 | void |
| 5119 | vm_page_set_validclean(vm_page_t m, int base, int size) |
| 5120 | { |
| 5121 | vm_page_bits_t oldvalid, pagebits; |
| 5122 | int endoff, frag; |
| 5123 | |
| 5124 | vm_page_assert_busied(m); |
| 5125 | if (size == 0) /* handle degenerate case */ |
| 5126 | return; |
| 5127 | |
| 5128 | /* |
| 5129 | * If the base is not DEV_BSIZE aligned and the valid |
| 5130 | * bit is clear, we have to zero out a portion of the |
| 5131 | * first block. |
| 5132 | */ |
| 5133 | if ((frag = rounddown2(base, DEV_BSIZE)) != base && |
| 5134 | (m->valid & ((vm_page_bits_t)1 << (base >> DEV_BSHIFT))) == 0) |
| 5135 | pmap_zero_page_area(m, frag, base - frag); |
| 5136 | |
| 5137 | /* |
| 5138 | * If the ending offset is not DEV_BSIZE aligned and the |
| 5139 | * valid bit is clear, we have to zero out a portion of |
| 5140 | * the last block. |
| 5141 | */ |
| 5142 | endoff = base + size; |
| 5143 | if ((frag = rounddown2(endoff, DEV_BSIZE)) != endoff && |
| 5144 | (m->valid & ((vm_page_bits_t)1 << (endoff >> DEV_BSHIFT))) == 0) |
| 5145 | pmap_zero_page_area(m, endoff, |
| 5146 | DEV_BSIZE - (endoff & (DEV_BSIZE - 1))); |
| 5147 | |
| 5148 | /* |
| 5149 | * Set valid, clear dirty bits. If validating the entire |
| 5150 | * page we can safely clear the pmap modify bit. We also |
| 5151 | * use this opportunity to clear the PGA_NOSYNC flag. If a process |
| 5152 | * takes a write fault on a MAP_NOSYNC memory area the flag will |
| 5153 | * be set again. |
| 5154 | * |
| 5155 | * We set valid bits inclusive of any overlap, but we can only |
| 5156 | * clear dirty bits for DEV_BSIZE chunks that are fully within |
| 5157 | * the range. |
| 5158 | */ |
| 5159 | oldvalid = m->valid; |
| 5160 | pagebits = vm_page_bits(base, size); |
| 5161 | if (vm_page_xbusied(m)) |
| 5162 | m->valid |= pagebits; |
| 5163 | else |
| 5164 | vm_page_bits_set(m, &m->valid, pagebits); |
| 5165 | #if 0 /* NOT YET */ |
| 5166 | if ((frag = base & (DEV_BSIZE - 1)) != 0) { |
| 5167 | frag = DEV_BSIZE - frag; |
| 5168 | base += frag; |
| 5169 | size -= frag; |
| 5170 | if (size < 0) |
| 5171 | size = 0; |
| 5172 | } |
| 5173 | pagebits = vm_page_bits(base, size & (DEV_BSIZE - 1)); |
| 5174 | #endif |
| 5175 | if (base == 0 && size == PAGE_SIZE) { |
no test coverage detected