})
 #endif
 
+#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+#define ptep_get_and_clear_full(__mm, __address, __ptep, __full)       \
+({                                                                     \
+       pte_t __pte;                                                    \
+       __pte = ptep_get_and_clear((__mm), (__address), (__ptep));      \
+       __pte;                                                          \
+})
+#endif
+
+#ifndef __HAVE_ARCH_PTE_CLEAR_FULL
+#define pte_clear_full(__mm, __address, __ptep, __full)                        \
+do {                                                                   \
+       pte_clear((__mm), (__address), (__ptep));                       \
+} while (0)
+#endif
+
 #ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
 #define ptep_clear_flush(__vma, __address, __ptep)                     \
 ({                                                                     \
 
        return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
 }
 
+static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
+{
+       pte_t pte;
+       if (full) {
+               pte = *ptep;
+               *ptep = __pte(0);
+       } else {
+               pte = ptep_get_and_clear(mm, addr, ptep);
+       }
+       return pte;
+}
+
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
        clear_bit(_PAGE_BIT_RW, &ptep->pte_low);
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 #define __HAVE_ARCH_PTE_SAME
 #include <asm-generic/pgtable.h>
 
                                     page->index > details->last_index))
                                        continue;
                        }
-                       ptent = ptep_get_and_clear(tlb->mm, addr, pte);
+                       ptent = ptep_get_and_clear_full(tlb->mm, addr, pte,
+                                                       tlb->fullmm);
                        tlb_remove_tlb_entry(tlb, pte, addr);
                        if (unlikely(!page))
                                continue;
                        continue;
                if (!pte_file(ptent))
                        free_swap_and_cache(pte_to_swp_entry(ptent));
-               pte_clear(tlb->mm, addr, pte);
+               pte_clear_full(tlb->mm, addr, pte, tlb->fullmm);
        } while (pte++, addr += PAGE_SIZE, addr != end);
        pte_unmap(pte - 1);
 }