1
2#ifndef _S390_TLB_H
3#define _S390_TLB_H
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/mm.h>
26#include <linux/pagemap.h>
27#include <linux/swap.h>
28#include <asm/processor.h>
29#include <asm/pgalloc.h>
30#include <asm/tlbflush.h>
31
32
33#ifndef nmi_uaccess_okay
34# define nmi_uaccess_okay() true
35#endif
36
37struct mmu_gather {
38 struct mm_struct *mm;
39 struct mmu_table_batch *batch;
40 unsigned int fullmm;
41 unsigned long start, end;
42};
43
44struct mmu_table_batch {
45 struct rcu_head rcu;
46 unsigned int nr;
47 void *tables[0];
48};
49
50#define MAX_TABLE_BATCH \
51 ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
52
53extern void tlb_table_flush(struct mmu_gather *tlb);
54extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
55
56static inline void
57arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
58 unsigned long start, unsigned long end)
59{
60 tlb->mm = mm;
61 tlb->start = start;
62 tlb->end = end;
63 tlb->fullmm = !(start | (end+1));
64 tlb->batch = NULL;
65}
66
67static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
68{
69 __tlb_flush_mm_lazy(tlb->mm);
70}
71
72static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
73{
74 tlb_table_flush(tlb);
75}
76
77
78static inline void tlb_flush_mmu(struct mmu_gather *tlb)
79{
80 tlb_flush_mmu_tlbonly(tlb);
81 tlb_flush_mmu_free(tlb);
82}
83
84static inline void
85arch_tlb_finish_mmu(struct mmu_gather *tlb,
86 unsigned long start, unsigned long end, bool force)
87{
88 if (force) {
89 tlb->start = start;
90 tlb->end = end;
91 }
92
93 tlb_flush_mmu(tlb);
94}
95
96
97
98
99
100
101static inline bool __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
102{
103 free_page_and_swap_cache(page);
104 return false;
105}
106
107static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
108{
109 free_page_and_swap_cache(page);
110}
111
112static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,
113 struct page *page, int page_size)
114{
115 return __tlb_remove_page(tlb, page);
116}
117
118static inline void tlb_remove_page_size(struct mmu_gather *tlb,
119 struct page *page, int page_size)
120{
121 return tlb_remove_page(tlb, page);
122}
123
124
125
126
127
128static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
129 unsigned long address)
130{
131 page_table_free_rcu(tlb, (unsigned long *) pte, address);
132}
133
134
135
136
137
138
139
140
141static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
142 unsigned long address)
143{
144 if (mm_pmd_folded(tlb->mm))
145 return;
146 pgtable_pmd_page_dtor(virt_to_page(pmd));
147 tlb_remove_table(tlb, pmd);
148}
149
150
151
152
153
154
155
156
157static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
158 unsigned long address)
159{
160 if (mm_p4d_folded(tlb->mm))
161 return;
162 tlb_remove_table(tlb, p4d);
163}
164
165
166
167
168
169
170
171
172static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
173 unsigned long address)
174{
175 if (mm_pud_folded(tlb->mm))
176 return;
177 tlb_remove_table(tlb, pud);
178}
179
180#define tlb_start_vma(tlb, vma) do { } while (0)
181#define tlb_end_vma(tlb, vma) do { } while (0)
182#define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0)
183#define tlb_remove_pmd_tlb_entry(tlb, pmdp, addr) do { } while (0)
184#define tlb_migrate_finish(mm) do { } while (0)
185#define tlb_remove_huge_tlb_entry(h, tlb, ptep, address) \
186 tlb_remove_tlb_entry(tlb, ptep, address)
187
188#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
189static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
190 unsigned int page_size)
191{
192}
193
194#endif
195