]> xenbits.xensource.com Git - xen.git/commitdiff
linux: Add a hook before a page table entry is cleared, for use with
authorKeir Fraser <keir@xensource.com>
Sat, 31 Mar 2007 11:42:02 +0000 (12:42 +0100)
committerKeir Fraser <keir@xensource.com>
Sat, 31 Mar 2007 11:42:02 +0000 (12:42 +0100)
the grant-table device.

Signed-off-by: Derek Murray <Derek.Murray@cl.cam.ac.uk>
linux-2.6-xen-sparse/include/linux/mm.h
linux-2.6-xen-sparse/mm/memory.c

index 1368b8450a0dc4d27aafa1569688b0e2ca9c5449..19654229cc30a2d3a7b82ff0172da035c6f608a6 100644 (file)
@@ -205,6 +205,11 @@ struct vm_operations_struct {
        /* 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,
index f55ed7dedc49427e47dfbd2acb1edd8e9bad3931..4af5beccaaf0dd1c749a099904e5752b47b20755 100644 (file)
@@ -659,8 +659,15 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
                                     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;
@@ -755,6 +762,7 @@ static unsigned long unmap_page_range(struct mmu_gather *tlb,
                details = NULL;
 
        BUG_ON(addr >= end);
+
        tlb_start_vma(tlb, vma);
        pgd = pgd_offset(vma->vm_mm, addr);
        do {