| 3683 | } |
| 3684 | |
| 3685 | int |
| 3686 | pmap_change_attr(vm_offset_t sva, vm_size_t size, vm_memattr_t ma) |
| 3687 | { |
| 3688 | pd_entry_t *pde, *pdpe; |
| 3689 | pt_entry_t *pte; |
| 3690 | vm_offset_t ova, eva, va, va_next; |
| 3691 | pmap_t pmap; |
| 3692 | |
| 3693 | ova = sva; |
| 3694 | eva = sva + size; |
| 3695 | if (eva < sva) |
| 3696 | return (EINVAL); |
| 3697 | |
| 3698 | pmap = kernel_pmap; |
| 3699 | PMAP_LOCK(pmap); |
| 3700 | |
| 3701 | for (; sva < eva; sva = va_next) { |
| 3702 | pdpe = pmap_segmap(pmap, sva); |
| 3703 | #ifdef __mips_n64 |
| 3704 | if (*pdpe == 0) { |
| 3705 | va_next = (sva + NBSEG) & ~SEGMASK; |
| 3706 | if (va_next < sva) |
| 3707 | va_next = eva; |
| 3708 | continue; |
| 3709 | } |
| 3710 | #endif |
| 3711 | va_next = (sva + NBPDR) & ~PDRMASK; |
| 3712 | if (va_next < sva) |
| 3713 | va_next = eva; |
| 3714 | |
| 3715 | pde = pmap_pdpe_to_pde(pdpe, sva); |
| 3716 | if (*pde == NULL) |
| 3717 | continue; |
| 3718 | |
| 3719 | /* |
| 3720 | * Limit our scan to either the end of the va represented |
| 3721 | * by the current page table page, or to the end of the |
| 3722 | * range being removed. |
| 3723 | */ |
| 3724 | if (va_next > eva) |
| 3725 | va_next = eva; |
| 3726 | |
| 3727 | va = va_next; |
| 3728 | for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++, |
| 3729 | sva += PAGE_SIZE) { |
| 3730 | if (!pte_test(pte, PTE_V) || pte_cache_bits(pte) == ma) { |
| 3731 | if (va != va_next) { |
| 3732 | pmap_invalidate_range(pmap, va, sva); |
| 3733 | va = va_next; |
| 3734 | } |
| 3735 | continue; |
| 3736 | } |
| 3737 | if (va == va_next) |
| 3738 | va = sva; |
| 3739 | |
| 3740 | pmap_pte_attr(pte, ma); |
| 3741 | } |
| 3742 | if (va != va_next) |
nothing calls this directly
no test coverage detected