Index: sys/compat/linuxkpi/common/include/linux/mm.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/mm.h +++ sys/compat/linuxkpi/common/include/linux/mm.h @@ -188,7 +188,7 @@ vm_fault_t lkpi_vmf_insert_pfn_prot_locked(struct vm_area_struct *vma, unsigned long addr, - unsigned long pfn, pgprot_t prot); + unsigned long pfn, pgprot_t prot, vm_object_t shm_obj); static inline vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, @@ -197,7 +197,7 @@ vm_fault_t ret; VM_OBJECT_WLOCK(vma->vm_obj); - ret = lkpi_vmf_insert_pfn_prot_locked(vma, addr, pfn, prot); + ret = lkpi_vmf_insert_pfn_prot_locked(vma, addr, pfn, prot, NULL); VM_OBJECT_WUNLOCK(vma->vm_obj); return (ret); Index: sys/compat/linuxkpi/common/src/linux_page.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_page.c +++ sys/compat/linuxkpi/common/src/linux_page.c @@ -278,7 +278,7 @@ vm_fault_t lkpi_vmf_insert_pfn_prot_locked(struct vm_area_struct *vma, unsigned long addr, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, vm_object_t shm_obj) { vm_object_t vm_obj = vma->vm_obj; vm_page_t page; @@ -296,6 +296,22 @@ page = PHYS_TO_VM_PAGE(IDX_TO_OFF(pfn)); if (!vm_page_busy_acquire(page, VM_ALLOC_WAITFAIL)) goto retry; + if (page->object != NULL) { + MPASS(shm_obj == page->object); + vm_page_xunbusy(page); + VM_OBJECT_WUNLOCK(vm_obj); + /* + * This is a special case for mmaping of shared memory + * object, thus shm_obj has longer lifespan than vm_obj + */ + VM_OBJECT_WLOCK(shm_obj); + vm_page_busy_acquire(page, 0); + vm_pager_page_unswapped(page); + vm_page_remove(page); + VM_OBJECT_WUNLOCK(shm_obj); + VM_OBJECT_WLOCK(vm_obj); + goto retry; + } if (vm_page_insert(page, vm_obj, pindex)) { vm_page_xunbusy(page); return (VM_FAULT_OOM);