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 @@ -327,6 +327,7 @@ LIST_ENTRY(vmmap) vm_next; void *vm_addr; unsigned long vm_size; + bool vm_is_io; }; struct vmmaphd { @@ -345,7 +346,7 @@ } static void -vmmap_add(void *addr, unsigned long size) +vmmap_add(void *addr, unsigned long size, bool is_io) { struct vmmap *vmmap; @@ -353,6 +354,7 @@ mtx_lock(&vmmaplock); vmmap->vm_size = size; vmmap->vm_addr = addr; + vmmap->vm_is_io = is_io; LIST_INSERT_HEAD(&vmmaphead[VM_HASH(addr)], vmmap, vm_next); mtx_unlock(&vmmaplock); } @@ -373,6 +375,25 @@ return (vmmap); } +static void +_lkpi_vunmap(void *addr) +{ + struct vmmap *vmmap; + + vmmap = vmmap_remove(addr); + if (vmmap == NULL) + return; + if (vmmap->vm_is_io) { +#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv) + pmap_unmapdev(addr, vmmap->vm_size); +#endif + } else { + pmap_qremove((vm_offset_t)addr, vmmap->vm_size / PAGE_SIZE); + kva_free((vm_offset_t)addr, vmmap->vm_size); + } + kfree(vmmap); +} + #if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv) void * _ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr) @@ -382,7 +403,7 @@ addr = pmap_mapdev_attr(phys_addr, size, attr); if (addr == NULL) return (NULL); - vmmap_add(addr, size); + vmmap_add(addr, size, true); return (addr); } @@ -391,15 +412,7 @@ void iounmap(void *addr) { - struct vmmap *vmmap; - - vmmap = vmmap_remove(addr); - if (vmmap == NULL) - return; -#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv) - pmap_unmapdev(addr, vmmap->vm_size); -#endif - kfree(vmmap); + _lkpi_vunmap(addr); } void * @@ -412,7 +425,7 @@ off = kva_alloc(size); if (off == 0) return (NULL); - vmmap_add((void *)off, size); + vmmap_add((void *)off, size, false); pmap_qenter(off, pages, count); return ((void *)off); @@ -421,14 +434,7 @@ void vunmap(void *addr) { - struct vmmap *vmmap; - - vmmap = vmmap_remove(addr); - if (vmmap == NULL) - return; - pmap_qremove((vm_offset_t)addr, vmmap->vm_size / PAGE_SIZE); - kva_free((vm_offset_t)addr, vmmap->vm_size); - kfree(vmmap); + _lkpi_vunmap(addr); } vm_fault_t