On Wed, 2 Jun 2021, Ming Lin wrote: > > This is what I wrote so far. > > --- > include/linux/mm.h | 2 ++ > include/linux/mman.h | 1 + > include/uapi/asm-generic/mman-common.h | 1 + > mm/memory.c | 12 ++++++++++++ > mm/mmap.c | 4 ++++ > 5 files changed, 20 insertions(+) I have not looked at the rest, just looking at mm/memory.c: > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -3676,6 +3676,18 @@ static vm_fault_t __do_fault(struct vm_fault *vmf) > } > ret = vma->vm_ops->fault(vmf); > + if (unlikely(ret & VM_FAULT_SIGBUS) && (vma->vm_flags & VM_NOSIGBUS)) > { > + /* > + * Get zero page for MAP_NOSIGBUS mapping, which isn't > + * coherent wrt shmem contents that are expanded and > + * filled in later. > + */ > + vma->vm_flags |= VM_MIXEDMAP; > + if (!vm_insert_page(vma, (unsigned long)vmf->address, > + ZERO_PAGE(vmf->address))) > + return VM_FAULT_NOPAGE; > + } > + > if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY > | > VM_FAULT_DONE_COW))) > return ret; Sorry, I directed you to mm/memory.c without indicating what's appropriate here. Please don't attempt to use VM_MIXEDMAP and vm_insert_page(): they're for special driver mmaps, they're no better here than they were in mm/shmem.c. It's do_anonymous_page()'s business to map in the zero page on read fault (see "my_zero_pfn(vmf->address)" in there), or fill a freshly allocated page with zeroes on write fault - and now you're sticking to MAP_PRIVATE, write faults in VM_WRITE areas are okay for VM_NOSIGBUS. Ideally you can simply call do_anonymous_page() from __do_fault() in the VM_FAULT_SIGBUS on VM_NOSIGBUS case. That's what to start from anyway: but look to see if there's state to be adjusted to achieve that; and it won't be surprising if somewhere down in do_anonymous_page() or something it calls, there's a BUG on it being called when vma->vm_file is set, or something like that. May need some tweaking. Hugh