+ idx = folio_page_idx(folio, vmf->page); + folio_start = address - idx * PAGE_SIZE; + folio_end = folio_start + nr * PAGE_SIZE; + + if (unlikely(folio_start < max(address & PMD_MASK, vma->vm_start))) + return false; + if (unlikely(folio_end > pmd_addr_end(address, vma->vm_end))) + return false; + folio_ptep = vmf->pte - idx; + folio_pte = ptep_get(folio_ptep); + if (!pte_present(folio_pte) || pte_pfn(folio_pte) != folio_pfn(folio)) + return false; + if (folio_pte_batch(folio, folio_start, folio_ptep, folio_pte, nr, 0, + NULL, NULL, NULL) != nr) + return false; + if (folio_mapcount(folio) != nr) + return false;
BTW, you're not checking against the refcount (and it's all a bit racy on concurrent unmapping!). So you're re-introducing the vmsplice child->parent attak.
-- Cheers, David / dhildenb