/* We enter with non-exclusive mmap_sem (to exclude vma changes, but allow concurrent faults), and pte mapped but not yet locked. We return with mmap_sem still held, but pte unmapped and unlocked.  */
static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *page_table, pmd_t *pmd, unsigned int flags, pte_t orig_pte)
/* We enter with non-exclusive mmap_sem (to exclude vma changes, but allow concurrent faults), and pte mapped but not yet locked. We return with mmap_sem still held, but pte unmapped and unlocked.  */
static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *page_table, pmd_t *pmd, unsigned int flags, pte_t orig_pte)
{
	pgoff_t pgoff;
	flags |= FAULT_FLAG_NONLINEAR;
	if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
		return 0;
	if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) {
		print_bad_pte(vma, address, orig_pte, NULL);
		return VM_FAULT_SIGBUS;
	}
	pgoff = pte_to_pgoff(orig_pte);
	return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
}