* kmem_unback: * * Unmap and free the physical pages underlying the specified virtual * address range. * * A physical page must exist within the specified object at each index * that is being unmapped. */
| 556 | * that is being unmapped. |
| 557 | */ |
| 558 | static struct vmem * |
| 559 | _kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size) |
| 560 | { |
| 561 | struct vmem *arena; |
| 562 | vm_page_t m, next; |
| 563 | vm_offset_t end, offset; |
| 564 | int domain; |
| 565 | |
| 566 | KASSERT(object == kernel_object, |
| 567 | ("kmem_unback: only supports kernel object.")); |
| 568 | |
| 569 | if (size == 0) |
| 570 | return (NULL); |
| 571 | pmap_remove(kernel_pmap, addr, addr + size); |
| 572 | offset = addr - VM_MIN_KERNEL_ADDRESS; |
| 573 | end = offset + size; |
| 574 | VM_OBJECT_WLOCK(object); |
| 575 | m = vm_page_lookup(object, atop(offset)); |
| 576 | domain = vm_page_domain(m); |
| 577 | if (__predict_true((m->oflags & VPO_KMEM_EXEC) == 0)) |
| 578 | arena = vm_dom[domain].vmd_kernel_arena; |
| 579 | else |
| 580 | arena = vm_dom[domain].vmd_kernel_rwx_arena; |
| 581 | for (; offset < end; offset += PAGE_SIZE, m = next) { |
| 582 | next = vm_page_next(m); |
| 583 | vm_page_xbusy_claim(m); |
| 584 | vm_page_unwire_noq(m); |
| 585 | vm_page_free(m); |
| 586 | } |
| 587 | VM_OBJECT_WUNLOCK(object); |
| 588 | |
| 589 | return (arena); |
| 590 | } |
| 591 | |
| 592 | void |
| 593 | kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size) |
no test coverage detected