* Clear the wired attribute from the mappings for the specified range of * addresses in the given pmap. Every valid mapping within that range * must have the wired attribute set. In contrast, invalid mappings * cannot have the wired attribute set, so they are ignored. * * The wired attribute of the page table entry is not a hardware feature, * so there is no need to invalidate any TLB entr
| 4584 | * so there is no need to invalidate any TLB entries. |
| 4585 | */ |
| 4586 | void |
| 4587 | pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) |
| 4588 | { |
| 4589 | vm_offset_t va_next; |
| 4590 | pd_entry_t *l0, *l1, *l2; |
| 4591 | pt_entry_t *l3; |
| 4592 | |
| 4593 | PMAP_LOCK(pmap); |
| 4594 | for (; sva < eva; sva = va_next) { |
| 4595 | l0 = pmap_l0(pmap, sva); |
| 4596 | if (pmap_load(l0) == 0) { |
| 4597 | va_next = (sva + L0_SIZE) & ~L0_OFFSET; |
| 4598 | if (va_next < sva) |
| 4599 | va_next = eva; |
| 4600 | continue; |
| 4601 | } |
| 4602 | |
| 4603 | l1 = pmap_l0_to_l1(l0, sva); |
| 4604 | va_next = (sva + L1_SIZE) & ~L1_OFFSET; |
| 4605 | if (va_next < sva) |
| 4606 | va_next = eva; |
| 4607 | if (pmap_load(l1) == 0) |
| 4608 | continue; |
| 4609 | |
| 4610 | if ((pmap_load(l1) & ATTR_DESCR_MASK) == L1_BLOCK) { |
| 4611 | KASSERT(va_next <= eva, |
| 4612 | ("partial update of non-transparent 1G page " |
| 4613 | "l1 %#lx sva %#lx eva %#lx va_next %#lx", |
| 4614 | pmap_load(l1), sva, eva, va_next)); |
| 4615 | MPASS(pmap != kernel_pmap); |
| 4616 | MPASS((pmap_load(l1) & (ATTR_SW_MANAGED | |
| 4617 | ATTR_SW_WIRED)) == ATTR_SW_WIRED); |
| 4618 | pmap_clear_bits(l1, ATTR_SW_WIRED); |
| 4619 | pmap->pm_stats.wired_count -= L1_SIZE / PAGE_SIZE; |
| 4620 | continue; |
| 4621 | } |
| 4622 | |
| 4623 | va_next = (sva + L2_SIZE) & ~L2_OFFSET; |
| 4624 | if (va_next < sva) |
| 4625 | va_next = eva; |
| 4626 | |
| 4627 | l2 = pmap_l1_to_l2(l1, sva); |
| 4628 | if (pmap_load(l2) == 0) |
| 4629 | continue; |
| 4630 | |
| 4631 | if ((pmap_load(l2) & ATTR_DESCR_MASK) == L2_BLOCK) { |
| 4632 | if ((pmap_load(l2) & ATTR_SW_WIRED) == 0) |
| 4633 | panic("pmap_unwire: l2 %#jx is missing " |
| 4634 | "ATTR_SW_WIRED", (uintmax_t)pmap_load(l2)); |
| 4635 | |
| 4636 | /* |
| 4637 | * Are we unwiring the entire large page? If not, |
| 4638 | * demote the mapping and fall through. |
| 4639 | */ |
| 4640 | if (sva + L2_SIZE == va_next && eva >= va_next) { |
| 4641 | pmap_clear_bits(l2, ATTR_SW_WIRED); |
| 4642 | pmap->pm_stats.wired_count -= L2_SIZE / |
| 4643 | PAGE_SIZE; |
nothing calls this directly
no test coverage detected