aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390/tlb.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-s390/tlb.h')
-rw-r--r--include/asm-s390/tlb.h33
1 files changed, 24 insertions, 9 deletions
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h
index ecac75ec6cb0..9b2ddb7aac49 100644
--- a/include/asm-s390/tlb.h
+++ b/include/asm-s390/tlb.h
@@ -38,7 +38,7 @@ struct mmu_gather {
38 struct mm_struct *mm; 38 struct mm_struct *mm;
39 unsigned int fullmm; 39 unsigned int fullmm;
40 unsigned int nr_ptes; 40 unsigned int nr_ptes;
41 unsigned int nr_pmds; 41 unsigned int nr_pxds;
42 void *array[TLB_NR_PTRS]; 42 void *array[TLB_NR_PTRS];
43}; 43};
44 44
@@ -53,7 +53,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
53 tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || 53 tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
54 (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); 54 (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
55 tlb->nr_ptes = 0; 55 tlb->nr_ptes = 0;
56 tlb->nr_pmds = TLB_NR_PTRS; 56 tlb->nr_pxds = TLB_NR_PTRS;
57 if (tlb->fullmm) 57 if (tlb->fullmm)
58 __tlb_flush_mm(mm); 58 __tlb_flush_mm(mm);
59 return tlb; 59 return tlb;
@@ -62,12 +62,13 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
62static inline void tlb_flush_mmu(struct mmu_gather *tlb, 62static inline void tlb_flush_mmu(struct mmu_gather *tlb,
63 unsigned long start, unsigned long end) 63 unsigned long start, unsigned long end)
64{ 64{
65 if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS)) 65 if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS))
66 __tlb_flush_mm(tlb->mm); 66 __tlb_flush_mm(tlb->mm);
67 while (tlb->nr_ptes > 0) 67 while (tlb->nr_ptes > 0)
68 pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); 68 pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]);
69 while (tlb->nr_pmds < TLB_NR_PTRS) 69 while (tlb->nr_pxds < TLB_NR_PTRS)
70 pmd_free(tlb->mm, (pmd_t *) tlb->array[tlb->nr_pmds++]); 70 /* pgd_free frees the pointer as region or segment table */
71 pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]);
71} 72}
72 73
73static inline void tlb_finish_mmu(struct mmu_gather *tlb, 74static inline void tlb_finish_mmu(struct mmu_gather *tlb,
@@ -99,7 +100,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte)
99{ 100{
100 if (!tlb->fullmm) { 101 if (!tlb->fullmm) {
101 tlb->array[tlb->nr_ptes++] = pte; 102 tlb->array[tlb->nr_ptes++] = pte;
102 if (tlb->nr_ptes >= tlb->nr_pmds) 103 if (tlb->nr_ptes >= tlb->nr_pxds)
103 tlb_flush_mmu(tlb, 0, 0); 104 tlb_flush_mmu(tlb, 0, 0);
104 } else 105 } else
105 pte_free(tlb->mm, pte); 106 pte_free(tlb->mm, pte);
@@ -113,15 +114,29 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
113{ 114{
114#ifdef __s390x__ 115#ifdef __s390x__
115 if (!tlb->fullmm) { 116 if (!tlb->fullmm) {
116 tlb->array[--tlb->nr_pmds] = (struct page *) pmd; 117 tlb->array[--tlb->nr_pxds] = pmd;
117 if (tlb->nr_ptes >= tlb->nr_pmds) 118 if (tlb->nr_ptes >= tlb->nr_pxds)
118 tlb_flush_mmu(tlb, 0, 0); 119 tlb_flush_mmu(tlb, 0, 0);
119 } else 120 } else
120 pmd_free(tlb->mm, pmd); 121 pmd_free(tlb->mm, pmd);
121#endif 122#endif
122} 123}
123 124
124#define pud_free_tlb(tlb, pud) do { } while (0) 125/*
126 * pud_free_tlb frees a pud table and clears the CRSTE for the
127 * region third table entry from the tlb.
128 */
129static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
130{
131#ifdef __s390x__
132 if (!tlb->fullmm) {
133 tlb->array[--tlb->nr_pxds] = pud;
134 if (tlb->nr_ptes >= tlb->nr_pxds)
135 tlb_flush_mmu(tlb, 0, 0);
136 } else
137 pud_free(tlb->mm, pud);
138#endif
139}
125 140
126#define tlb_start_vma(tlb, vma) do { } while (0) 141#define tlb_start_vma(tlb, vma) do { } while (0)
127#define tlb_end_vma(tlb, vma) do { } while (0) 142#define tlb_end_vma(tlb, vma) do { } while (0)