Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / include / linux / mmu_notifier.h
index b77486d..43dcfbd 100644 (file)
@@ -61,6 +61,15 @@ struct mmu_notifier_ops {
                                 struct mm_struct *mm,
                                 unsigned long address);
 
+       /*
+        * change_pte is called in cases that pte mapping to page is changed:
+        * for example, when ksm remaps pte to point to a new shared page.
+        */
+       void (*change_pte)(struct mmu_notifier *mn,
+                          struct mm_struct *mm,
+                          unsigned long address,
+                          pte_t pte);
+
        /*
         * Before this is invoked any secondary MMU is still ok to
         * read/write to the page previously pointed to by the Linux
@@ -154,6 +163,8 @@ extern void __mmu_notifier_mm_destroy(struct mm_struct *mm);
 extern void __mmu_notifier_release(struct mm_struct *mm);
 extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
                                          unsigned long address);
+extern void __mmu_notifier_change_pte(struct mm_struct *mm,
+                                     unsigned long address, pte_t pte);
 extern void __mmu_notifier_invalidate_page(struct mm_struct *mm,
                                          unsigned long address);
 extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
@@ -175,6 +186,13 @@ static inline int mmu_notifier_clear_flush_young(struct mm_struct *mm,
        return 0;
 }
 
+static inline void mmu_notifier_change_pte(struct mm_struct *mm,
+                                          unsigned long address, pte_t pte)
+{
+       if (mm_has_notifiers(mm))
+               __mmu_notifier_change_pte(mm, address, pte);
+}
+
 static inline void mmu_notifier_invalidate_page(struct mm_struct *mm,
                                          unsigned long address)
 {
@@ -209,7 +227,7 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
 
 /*
  * These two macros will sometime replace ptep_clear_flush.
- * ptep_clear_flush is impleemnted as macro itself, so this also is
+ * ptep_clear_flush is implemented as macro itself, so this also is
  * implemented as a macro until ptep_clear_flush will converted to an
  * inline function, to diminish the risk of compilation failure. The
  * invalidate_page method over time can be moved outside the PT lock
@@ -236,6 +254,16 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
        __young;                                                        \
 })
 
+#define set_pte_at_notify(__mm, __address, __ptep, __pte)              \
+({                                                                     \
+       struct mm_struct *___mm = __mm;                                 \
+       unsigned long ___address = __address;                           \
+       pte_t ___pte = __pte;                                           \
+                                                                       \
+       set_pte_at(___mm, ___address, __ptep, ___pte);                  \
+       mmu_notifier_change_pte(___mm, ___address, ___pte);             \
+})
+
 #else /* CONFIG_MMU_NOTIFIER */
 
 static inline void mmu_notifier_release(struct mm_struct *mm)
@@ -248,6 +276,11 @@ static inline int mmu_notifier_clear_flush_young(struct mm_struct *mm,
        return 0;
 }
 
+static inline void mmu_notifier_change_pte(struct mm_struct *mm,
+                                          unsigned long address, pte_t pte)
+{
+}
+
 static inline void mmu_notifier_invalidate_page(struct mm_struct *mm,
                                          unsigned long address)
 {
@@ -273,6 +306,7 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
 
 #define ptep_clear_flush_young_notify ptep_clear_flush_young
 #define ptep_clear_flush_notify ptep_clear_flush
+#define set_pte_at_notify set_pte_at
 
 #endif /* CONFIG_MMU_NOTIFIER */