From 398a05bc4f183178b0bd77c8bd32f6ffdf3dfade Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Sat, 3 Sep 2005 15:55:04 -0700 Subject: [PATCH] --- yaml --- r: 6879 b: refs/heads/master c: a600388d28419305aad3c4c0af52c223cf6fa0af h: refs/heads/master i: 6877: 01154dff54f890d694d922e9faf6b6f1a2590254 6875: 4d0ca8a05391576509c75ac8839b740e02944b9a 6871: f23f2073708d10a196a7300ea8323f99f7973a4e 6863: 08505f39af1322429b7abe95dcbd8411c1d9ca29 6847: 079764d772f292031122960242c6073589020e59 v: v3 --- [refs] | 2 +- trunk/include/asm-generic/pgtable.h | 16 ++++++++++++++++ trunk/include/asm-i386/pgtable.h | 13 +++++++++++++ trunk/mm/memory.c | 5 +++-- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 9de0d6330434..8989e3ef0847 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fa5b08d5f818063d18433194f20359ef2ae50254 +refs/heads/master: a600388d28419305aad3c4c0af52c223cf6fa0af diff --git a/trunk/include/asm-generic/pgtable.h b/trunk/include/asm-generic/pgtable.h index f40593565173..f86c1e549466 100644 --- a/trunk/include/asm-generic/pgtable.h +++ b/trunk/include/asm-generic/pgtable.h @@ -101,6 +101,22 @@ do { \ }) #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) \ ({ \ diff --git a/trunk/include/asm-i386/pgtable.h b/trunk/include/asm-i386/pgtable.h index f51fd2c956bb..d74185aee15b 100644 --- a/trunk/include/asm-i386/pgtable.h +++ b/trunk/include/asm-i386/pgtable.h @@ -260,6 +260,18 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned 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); @@ -417,6 +429,7 @@ extern void noexec_setup(const char *str); #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 diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index b25f5e58a14c..788a62810340 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -562,7 +562,8 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd, 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; @@ -590,7 +591,7 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd, 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); }