* This is used to check if a page has been accessed or modified. */
| 5255 | * This is used to check if a page has been accessed or modified. |
| 5256 | */ |
| 5257 | static boolean_t |
| 5258 | pmap_page_test_mappings(vm_page_t m, boolean_t accessed, boolean_t modified) |
| 5259 | { |
| 5260 | struct rwlock *lock; |
| 5261 | pv_entry_t pv; |
| 5262 | struct md_page *pvh; |
| 5263 | pt_entry_t *pte, mask, value; |
| 5264 | pmap_t pmap; |
| 5265 | int lvl, md_gen, pvh_gen; |
| 5266 | boolean_t rv; |
| 5267 | |
| 5268 | rv = FALSE; |
| 5269 | lock = VM_PAGE_TO_PV_LIST_LOCK(m); |
| 5270 | rw_rlock(lock); |
| 5271 | restart: |
| 5272 | TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { |
| 5273 | pmap = PV_PMAP(pv); |
| 5274 | PMAP_ASSERT_STAGE1(pmap); |
| 5275 | if (!PMAP_TRYLOCK(pmap)) { |
| 5276 | md_gen = m->md.pv_gen; |
| 5277 | rw_runlock(lock); |
| 5278 | PMAP_LOCK(pmap); |
| 5279 | rw_rlock(lock); |
| 5280 | if (md_gen != m->md.pv_gen) { |
| 5281 | PMAP_UNLOCK(pmap); |
| 5282 | goto restart; |
| 5283 | } |
| 5284 | } |
| 5285 | pte = pmap_pte(pmap, pv->pv_va, &lvl); |
| 5286 | KASSERT(lvl == 3, |
| 5287 | ("pmap_page_test_mappings: Invalid level %d", lvl)); |
| 5288 | mask = 0; |
| 5289 | value = 0; |
| 5290 | if (modified) { |
| 5291 | mask |= ATTR_S1_AP_RW_BIT; |
| 5292 | value |= ATTR_S1_AP(ATTR_S1_AP_RW); |
| 5293 | } |
| 5294 | if (accessed) { |
| 5295 | mask |= ATTR_AF | ATTR_DESCR_MASK; |
| 5296 | value |= ATTR_AF | L3_PAGE; |
| 5297 | } |
| 5298 | rv = (pmap_load(pte) & mask) == value; |
| 5299 | PMAP_UNLOCK(pmap); |
| 5300 | if (rv) |
| 5301 | goto out; |
| 5302 | } |
| 5303 | if ((m->flags & PG_FICTITIOUS) == 0) { |
| 5304 | pvh = page_to_pvh(m); |
| 5305 | TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { |
| 5306 | pmap = PV_PMAP(pv); |
| 5307 | PMAP_ASSERT_STAGE1(pmap); |
| 5308 | if (!PMAP_TRYLOCK(pmap)) { |
| 5309 | md_gen = m->md.pv_gen; |
| 5310 | pvh_gen = pvh->pv_gen; |
| 5311 | rw_runlock(lock); |
| 5312 | PMAP_LOCK(pmap); |
| 5313 | rw_rlock(lock); |
| 5314 | if (md_gen != m->md.pv_gen || |
no test coverage detected