diff options
author | Gerald Schaefer <gerald.schaefer@de.ibm.com> | 2012-09-05 08:07:59 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-09-06 04:40:37 -0400 |
commit | 9016083b7bc4829c4f97f37a1a3102e0f5a37692 (patch) | |
tree | a70b3bf5b849c8815c9c7af3fbfe3d79dc260097 /arch/s390/include/asm/hugetlb.h | |
parent | d5feaea364281a7e9b80b4712e790ab908d61711 (diff) |
s390/hugetlb: use direct TLB flushing for hugetlbfs pages
huge_ptep_get_and_clear() is either missing a TLB invalidation or
an mm->context.attach_count check. Since the attach_count logic was
introduced with normal ptes in mind, let's just use direct TLB
flushing for hugetlbfs pages.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include/asm/hugetlb.h')
-rw-r--r-- | arch/s390/include/asm/hugetlb.h | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index 799ed0f1643d..2d6e6e380564 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -66,16 +66,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
66 | return pte; | 66 | return pte; |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | ||
70 | unsigned long addr, pte_t *ptep) | ||
71 | { | ||
72 | pte_t pte = huge_ptep_get(ptep); | ||
73 | |||
74 | mm->context.flush_mm = 1; | ||
75 | pmd_clear((pmd_t *) ptep); | ||
76 | return pte; | ||
77 | } | ||
78 | |||
79 | static inline void __pmd_csp(pmd_t *pmdp) | 69 | static inline void __pmd_csp(pmd_t *pmdp) |
80 | { | 70 | { |
81 | register unsigned long reg2 asm("2") = pmd_val(*pmdp); | 71 | register unsigned long reg2 asm("2") = pmd_val(*pmdp); |
@@ -117,6 +107,15 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm, | |||
117 | __pmd_csp(pmdp); | 107 | __pmd_csp(pmdp); |
118 | } | 108 | } |
119 | 109 | ||
110 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | ||
111 | unsigned long addr, pte_t *ptep) | ||
112 | { | ||
113 | pte_t pte = huge_ptep_get(ptep); | ||
114 | |||
115 | huge_ptep_invalidate(mm, addr, ptep); | ||
116 | return pte; | ||
117 | } | ||
118 | |||
120 | #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ | 119 | #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ |
121 | ({ \ | 120 | ({ \ |
122 | int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \ | 121 | int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \ |
@@ -131,10 +130,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm, | |||
131 | ({ \ | 130 | ({ \ |
132 | pte_t __pte = huge_ptep_get(__ptep); \ | 131 | pte_t __pte = huge_ptep_get(__ptep); \ |
133 | if (pte_write(__pte)) { \ | 132 | if (pte_write(__pte)) { \ |
134 | (__mm)->context.flush_mm = 1; \ | 133 | huge_ptep_invalidate(__mm, __addr, __ptep); \ |
135 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
136 | (__mm) != current->active_mm) \ | ||
137 | huge_ptep_invalidate(__mm, __addr, __ptep); \ | ||
138 | set_huge_pte_at(__mm, __addr, __ptep, \ | 134 | set_huge_pte_at(__mm, __addr, __ptep, \ |
139 | huge_pte_wrprotect(__pte)); \ | 135 | huge_pte_wrprotect(__pte)); \ |
140 | } \ | 136 | } \ |