/* notification that a previously read-only page is about to become
* writable, if an error is returned it will cause a SIGBUS */
int (*page_mkwrite)(struct vm_area_struct *vma, struct page *page);
+ /* Area-specific function for clearing the PTE at @ptep. Returns the
+ * original value of @ptep. */
+ pte_t (*ptep_get_and_clear_full)(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ int is_fullmm);
#ifdef CONFIG_NUMA
int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);
struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
page->index > details->last_index))
continue;
}
- ptent = ptep_get_and_clear_full(mm, addr, pte,
- tlb->fullmm);
+ if (unlikely(vma->vm_ops &&
+ vma->vm_ops->ptep_get_and_clear_full))
+ ptent = vma->vm_ops->
+ ptep_get_and_clear_full(vma, addr,
+ pte,
+ tlb->fullmm);
+ else
+ ptent = ptep_get_and_clear_full(mm, addr, pte,
+ tlb->fullmm);
tlb_remove_tlb_entry(tlb, pte, addr);
if (unlikely(!page))
continue;
details = NULL;
BUG_ON(addr >= end);
+
tlb_start_vma(tlb, vma);
pgd = pgd_offset(vma->vm_mm, addr);
do {