diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c --- a/sys/compat/linuxkpi/common/src/linux_page.c +++ b/sys/compat/linuxkpi/common/src/linux_page.c @@ -145,6 +145,14 @@ return (page); } +static void +_linux_free_kmem(vm_offset_t addr, unsigned int order) +{ + size_t size = ((size_t)PAGE_SIZE) << order; + + kmem_free((void *)addr, size); +} + void linux_free_pages(struct page *page, unsigned int order) { @@ -163,7 +171,7 @@ vaddr = (vm_offset_t)page_address(page); - linux_free_kmem(vaddr, order); + _linux_free_kmem(vaddr, order); } } @@ -185,9 +193,17 @@ void linux_free_kmem(vm_offset_t addr, unsigned int order) { - size_t size = ((size_t)PAGE_SIZE) << order; + KASSERT((addr & PAGE_MASK) == 0, + ("%s: addr %p is not page aligned", __func__, (void *)addr)); - kmem_free((void *)addr, size); + if (addr >= VM_MIN_KERNEL_ADDRESS && addr < VM_MAX_KERNEL_ADDRESS) { + _linux_free_kmem(addr, order); + } else { + vm_page_t page; + + page = PHYS_TO_VM_PAGE(DMAP_TO_PHYS(addr)); + linux_free_pages(page, order); + } } static int