]>
Commit | Line | Data |
---|---|---|
26b6a3d9 AK |
1 | #ifndef _ASM_POWERPC_BOOK3S_64_HASH_H |
2 | #define _ASM_POWERPC_BOOK3S_64_HASH_H | |
c605782b BH |
3 | #ifdef __KERNEL__ |
4 | ||
e34aa03c AK |
5 | /* |
6 | * Common bits between 4K and 64K pages in a linux-style PTE. | |
1ec3f937 | 7 | * Additional bits may be defined in pgtable-hash64-*.h |
e34aa03c AK |
8 | * |
9 | * Note: We only support user read/write permissions. Supervisor always | |
10 | * have full read/write to pages above PAGE_OFFSET (pages below that | |
11 | * always use the user access permissions). | |
12 | * | |
13 | * We could create separate kernel read-only if we used the 3 PP bits | |
14 | * combinations that newer processors provide but we currently don't. | |
15 | */ | |
c915df16 PM |
16 | #define _PAGE_BIT_SWAP_TYPE 0 |
17 | ||
18 | #define _PAGE_EXEC 0x00001 /* execute permission */ | |
19 | #define _PAGE_RW 0x00002 /* read & write access allowed */ | |
20 | #define _PAGE_READ 0x00004 /* read access allowed */ | |
21 | #define _PAGE_USER 0x00008 /* page may be accessed by userspace */ | |
1ec3f937 PM |
22 | #define _PAGE_GUARDED 0x00010 /* G: guarded (side-effect) page */ |
23 | /* M (memory coherence) is always set in the HPTE, so we don't need it here */ | |
e34aa03c AK |
24 | #define _PAGE_COHERENT 0x0 |
25 | #define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ | |
26 | #define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ | |
27 | #define _PAGE_DIRTY 0x00080 /* C: page changed */ | |
28 | #define _PAGE_ACCESSED 0x00100 /* R: page referenced */ | |
e726202f | 29 | #define _PAGE_SPECIAL 0x00400 /* software: special page */ |
e34aa03c | 30 | #define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ |
2f10f1a7 HD |
31 | |
32 | #ifdef CONFIG_MEM_SOFT_DIRTY | |
e726202f | 33 | #define _PAGE_SOFT_DIRTY 0x200 /* software: software dirty tracking */ |
2f10f1a7 | 34 | #else |
e726202f | 35 | #define _PAGE_SOFT_DIRTY 0x000 |
2f10f1a7 | 36 | #endif |
e34aa03c | 37 | |
a9d4996d PM |
38 | #define _PAGE_F_GIX_SHIFT 57 |
39 | #define _PAGE_F_GIX (7ul << 57) /* HPTE index within HPTEG */ | |
40 | #define _PAGE_F_SECOND (1ul << 60) /* HPTE is in 2ndary HPTEG */ | |
41 | #define _PAGE_HASHPTE (1ul << 61) /* PTE has associated HPTE */ | |
84c95756 | 42 | #define _PAGE_PTE (1ul << 62) /* distinguishes PTEs from pointers */ |
849f86a6 PM |
43 | #define _PAGE_PRESENT (1ul << 63) /* pte contains a translation */ |
44 | ||
e34aa03c AK |
45 | /* |
46 | * We need to differentiate between explicit huge page and THP huge | |
47 | * page, since THP huge page also need to track real subpage details | |
48 | */ | |
49 | #define _PAGE_THP_HUGE _PAGE_4K_PFN | |
50 | ||
51 | /* | |
52 | * set of bits not changed in pmd_modify. | |
53 | */ | |
7aa9a23c | 54 | #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ |
2d19fc63 AK |
55 | _PAGE_ACCESSED | _PAGE_THP_HUGE | _PAGE_PTE | \ |
56 | _PAGE_SOFT_DIRTY) | |
57 | ||
e34aa03c | 58 | |
371352ca AK |
59 | #ifdef CONFIG_PPC_64K_PAGES |
60 | #include <asm/book3s/64/hash-64k.h> | |
61 | #else | |
62 | #include <asm/book3s/64/hash-4k.h> | |
63 | #endif | |
64 | ||
65 | /* | |
66 | * Size of EA range mapped by our pagetables. | |
67 | */ | |
68 | #define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ | |
69 | PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) | |
70 | #define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) | |
71 | ||
72 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
73 | #define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1) | |
74 | #else | |
75 | #define PMD_CACHE_INDEX PMD_INDEX_SIZE | |
76 | #endif | |
77 | /* | |
78 | * Define the address range of the kernel non-linear virtual area | |
79 | */ | |
80 | #define KERN_VIRT_START ASM_CONST(0xD000000000000000) | |
81 | #define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) | |
82 | ||
83 | /* | |
84 | * The vmalloc space starts at the beginning of that region, and | |
85 | * occupies half of it on hash CPUs and a quarter of it on Book3E | |
86 | * (we keep a quarter for the virtual memmap) | |
87 | */ | |
88 | #define VMALLOC_START KERN_VIRT_START | |
89 | #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) | |
90 | #define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) | |
91 | ||
92 | /* | |
93 | * Region IDs | |
94 | */ | |
95 | #define REGION_SHIFT 60UL | |
96 | #define REGION_MASK (0xfUL << REGION_SHIFT) | |
97 | #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) | |
98 | ||
99 | #define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START)) | |
100 | #define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET)) | |
101 | #define VMEMMAP_REGION_ID (0xfUL) /* Server only */ | |
102 | #define USER_REGION_ID (0UL) | |
103 | ||
104 | /* | |
105 | * Defines the address of the vmemap area, in its own region on | |
106 | * hash table CPUs. | |
107 | */ | |
108 | #define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT) | |
109 | ||
110 | #ifdef CONFIG_PPC_MM_SLICES | |
111 | #define HAVE_ARCH_UNMAPPED_AREA | |
112 | #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN | |
113 | #endif /* CONFIG_PPC_MM_SLICES */ | |
8d1cf34e BH |
114 | |
115 | /* No separate kernel read-only */ | |
116 | #define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */ | |
117 | #define _PAGE_KERNEL_RO _PAGE_KERNEL_RW | |
b0412ea9 | 118 | #define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC) |
c605782b BH |
119 | |
120 | /* Strong Access Ordering */ | |
8d1cf34e | 121 | #define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT) |
c605782b | 122 | |
8d1cf34e BH |
123 | /* No page size encoding in the linux PTE */ |
124 | #define _PAGE_PSIZE 0 | |
c605782b BH |
125 | |
126 | /* PTEIDX nibble */ | |
127 | #define _PTEIDX_SECONDARY 0x8 | |
128 | #define _PTEIDX_GROUP_IX 0x7 | |
129 | ||
a033a487 BH |
130 | /* Hash table based platforms need atomic updates of the linux PTE */ |
131 | #define PTE_ATOMIC_UPDATES 1 | |
371352ca AK |
132 | #define _PTE_NONE_MASK _PAGE_HPTEFLAGS |
133 | /* | |
134 | * The mask convered by the RPN must be a ULL on 32-bit platforms with | |
135 | * 64-bit PTEs | |
136 | */ | |
f1a9ae03 | 137 | #define PTE_RPN_MASK (((1UL << PTE_RPN_SIZE) - 1) << PTE_RPN_SHIFT) |
371352ca AK |
138 | /* |
139 | * _PAGE_CHG_MASK masks of bits that are to be preserved across | |
140 | * pgprot changes | |
141 | */ | |
142 | #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ | |
7207f436 LD |
143 | _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \ |
144 | _PAGE_SOFT_DIRTY) | |
371352ca AK |
145 | /* |
146 | * Mask of bits returned by pte_pgprot() | |
147 | */ | |
148 | #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ | |
149 | _PAGE_WRITETHRU | _PAGE_4K_PFN | \ | |
150 | _PAGE_USER | _PAGE_ACCESSED | \ | |
7207f436 LD |
151 | _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC | \ |
152 | _PAGE_SOFT_DIRTY) | |
371352ca AK |
153 | /* |
154 | * We define 2 sets of base prot bits, one for basic pages (ie, | |
155 | * cacheable kernel and user pages) and one for non cacheable | |
156 | * pages. We always set _PAGE_COHERENT when SMP is enabled or | |
157 | * the processor might need it for DMA coherency. | |
158 | */ | |
159 | #define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) | |
160 | #define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) | |
161 | ||
162 | /* Permission masks used to generate the __P and __S table, | |
163 | * | |
164 | * Note:__pgprot is defined in arch/powerpc/include/asm/page.h | |
165 | * | |
166 | * Write permissions imply read permissions for now (we could make write-only | |
167 | * pages on BookE but we don't bother for now). Execute permission control is | |
168 | * possible on platforms that define _PAGE_EXEC | |
169 | * | |
170 | * Note due to the way vm flags are laid out, the bits are XWR | |
171 | */ | |
172 | #define PAGE_NONE __pgprot(_PAGE_BASE) | |
173 | #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) | |
174 | #define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \ | |
175 | _PAGE_EXEC) | |
176 | #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER ) | |
177 | #define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) | |
178 | #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER ) | |
179 | #define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) | |
180 | ||
181 | #define __P000 PAGE_NONE | |
182 | #define __P001 PAGE_READONLY | |
183 | #define __P010 PAGE_COPY | |
184 | #define __P011 PAGE_COPY | |
185 | #define __P100 PAGE_READONLY_X | |
186 | #define __P101 PAGE_READONLY_X | |
187 | #define __P110 PAGE_COPY_X | |
188 | #define __P111 PAGE_COPY_X | |
189 | ||
190 | #define __S000 PAGE_NONE | |
191 | #define __S001 PAGE_READONLY | |
192 | #define __S010 PAGE_SHARED | |
193 | #define __S011 PAGE_SHARED | |
194 | #define __S100 PAGE_READONLY_X | |
195 | #define __S101 PAGE_READONLY_X | |
196 | #define __S110 PAGE_SHARED_X | |
197 | #define __S111 PAGE_SHARED_X | |
198 | ||
199 | /* Permission masks used for kernel mappings */ | |
200 | #define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW) | |
201 | #define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ | |
202 | _PAGE_NO_CACHE) | |
203 | #define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ | |
204 | _PAGE_NO_CACHE | _PAGE_GUARDED) | |
205 | #define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) | |
206 | #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO) | |
207 | #define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX) | |
208 | ||
209 | /* Protection used for kernel text. We want the debuggers to be able to | |
210 | * set breakpoints anywhere, so don't write protect the kernel text | |
211 | * on platforms where such control is possible. | |
212 | */ | |
213 | #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\ | |
214 | defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) | |
215 | #define PAGE_KERNEL_TEXT PAGE_KERNEL_X | |
c605782b | 216 | #else |
371352ca | 217 | #define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX |
c605782b BH |
218 | #endif |
219 | ||
371352ca AK |
220 | /* Make modules code happy. We don't set RO yet */ |
221 | #define PAGE_KERNEL_EXEC PAGE_KERNEL_X | |
222 | #define PAGE_AGP (PAGE_KERNEL_NC) | |
223 | ||
224 | #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) | |
225 | #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) | |
371352ca AK |
226 | |
227 | #ifndef __ASSEMBLY__ | |
c61a8843 PM |
228 | #define pmd_bad(pmd) (pmd_val(pmd) & PMD_BAD_BITS) |
229 | #define pmd_page_vaddr(pmd) __va(pmd_val(pmd) & ~PMD_MASKED_BITS) | |
371352ca | 230 | |
c61a8843 PM |
231 | #define pud_bad(pud) (pud_val(pud) & PUD_BAD_BITS) |
232 | #define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS) | |
233 | ||
234 | /* Pointers in the page table tree are physical addresses */ | |
235 | #define __pgtable_ptr_val(ptr) __pa(ptr) | |
371352ca AK |
236 | |
237 | #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) | |
368ced78 | 238 | #define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1)) |
371352ca AK |
239 | #define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) |
240 | #define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) | |
241 | ||
242 | extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, | |
243 | pte_t *ptep, unsigned long pte, int huge); | |
c6a3c495 | 244 | extern unsigned long htab_convert_pte_flags(unsigned long pteflags); |
371352ca AK |
245 | /* Atomic PTE updates */ |
246 | static inline unsigned long pte_update(struct mm_struct *mm, | |
247 | unsigned long addr, | |
248 | pte_t *ptep, unsigned long clr, | |
249 | unsigned long set, | |
250 | int huge) | |
251 | { | |
252 | unsigned long old, tmp; | |
253 | ||
254 | __asm__ __volatile__( | |
255 | "1: ldarx %0,0,%3 # pte_update\n\ | |
256 | andi. %1,%0,%6\n\ | |
257 | bne- 1b \n\ | |
258 | andc %1,%0,%4 \n\ | |
259 | or %1,%1,%7\n\ | |
260 | stdcx. %1,0,%3 \n\ | |
261 | bne- 1b" | |
262 | : "=&r" (old), "=&r" (tmp), "=m" (*ptep) | |
263 | : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set) | |
264 | : "cc" ); | |
265 | /* huge pages use the old page table lock */ | |
266 | if (!huge) | |
267 | assert_pte_locked(mm, addr); | |
268 | ||
269 | if (old & _PAGE_HASHPTE) | |
270 | hpte_need_flush(mm, addr, ptep, old, huge); | |
271 | ||
272 | return old; | |
273 | } | |
274 | ||
275 | static inline int __ptep_test_and_clear_young(struct mm_struct *mm, | |
276 | unsigned long addr, pte_t *ptep) | |
277 | { | |
278 | unsigned long old; | |
279 | ||
280 | if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) | |
281 | return 0; | |
282 | old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); | |
283 | return (old & _PAGE_ACCESSED) != 0; | |
284 | } | |
285 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | |
286 | #define ptep_test_and_clear_young(__vma, __addr, __ptep) \ | |
287 | ({ \ | |
288 | int __r; \ | |
289 | __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \ | |
290 | __r; \ | |
291 | }) | |
292 | ||
293 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | |
294 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |
295 | pte_t *ptep) | |
296 | { | |
297 | ||
298 | if ((pte_val(*ptep) & _PAGE_RW) == 0) | |
299 | return; | |
300 | ||
301 | pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); | |
302 | } | |
303 | ||
304 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, | |
305 | unsigned long addr, pte_t *ptep) | |
306 | { | |
307 | if ((pte_val(*ptep) & _PAGE_RW) == 0) | |
308 | return; | |
309 | ||
310 | pte_update(mm, addr, ptep, _PAGE_RW, 0, 1); | |
311 | } | |
312 | ||
313 | /* | |
314 | * We currently remove entries from the hashtable regardless of whether | |
315 | * the entry was young or dirty. The generic routines only flush if the | |
316 | * entry was young or dirty which is not good enough. | |
317 | * | |
318 | * We should be more intelligent about this but for the moment we override | |
319 | * these functions and force a tlb flush unconditionally | |
320 | */ | |
321 | #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH | |
322 | #define ptep_clear_flush_young(__vma, __address, __ptep) \ | |
323 | ({ \ | |
324 | int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \ | |
325 | __ptep); \ | |
326 | __young; \ | |
327 | }) | |
328 | ||
329 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | |
330 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, | |
331 | unsigned long addr, pte_t *ptep) | |
332 | { | |
333 | unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0); | |
334 | return __pte(old); | |
335 | } | |
336 | ||
337 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, | |
338 | pte_t * ptep) | |
339 | { | |
340 | pte_update(mm, addr, ptep, ~0UL, 0, 0); | |
341 | } | |
342 | ||
343 | ||
344 | /* Set the dirty and/or accessed bits atomically in a linux PTE, this | |
345 | * function doesn't need to flush the hash entry | |
346 | */ | |
347 | static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) | |
348 | { | |
349 | unsigned long bits = pte_val(entry) & | |
7207f436 LD |
350 | (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC | |
351 | _PAGE_SOFT_DIRTY); | |
371352ca AK |
352 | |
353 | unsigned long old, tmp; | |
354 | ||
355 | __asm__ __volatile__( | |
356 | "1: ldarx %0,0,%4\n\ | |
357 | andi. %1,%0,%6\n\ | |
358 | bne- 1b \n\ | |
359 | or %0,%3,%0\n\ | |
360 | stdcx. %0,0,%4\n\ | |
361 | bne- 1b" | |
362 | :"=&r" (old), "=&r" (tmp), "=m" (*ptep) | |
363 | :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY) | |
364 | :"cc"); | |
365 | } | |
366 | ||
368ced78 AK |
367 | static inline int pgd_bad(pgd_t pgd) |
368 | { | |
369 | return (pgd_val(pgd) == 0); | |
370 | } | |
371 | ||
371352ca AK |
372 | #define __HAVE_ARCH_PTE_SAME |
373 | #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) | |
368ced78 AK |
374 | static inline unsigned long pgd_page_vaddr(pgd_t pgd) |
375 | { | |
376 | return (unsigned long)__va(pgd_val(pgd) & ~PGD_MASKED_BITS); | |
377 | } | |
378 | ||
371352ca | 379 | |
1ca72129 AK |
380 | /* Generic accessors to PTE bits */ |
381 | static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} | |
382 | static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } | |
383 | static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } | |
384 | static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } | |
385 | static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } | |
386 | static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } | |
387 | ||
7207f436 LD |
388 | #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY |
389 | static inline bool pte_soft_dirty(pte_t pte) | |
390 | { | |
391 | return !!(pte_val(pte) & _PAGE_SOFT_DIRTY); | |
392 | } | |
393 | static inline pte_t pte_mksoft_dirty(pte_t pte) | |
394 | { | |
395 | return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY); | |
396 | } | |
397 | ||
398 | static inline pte_t pte_clear_soft_dirty(pte_t pte) | |
399 | { | |
400 | return __pte(pte_val(pte) & ~_PAGE_SOFT_DIRTY); | |
401 | } | |
402 | #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ | |
403 | ||
1ca72129 AK |
404 | #ifdef CONFIG_NUMA_BALANCING |
405 | /* | |
406 | * These work without NUMA balancing but the kernel does not care. See the | |
407 | * comment in include/asm-generic/pgtable.h . On powerpc, this will only | |
408 | * work for user pages and always return true for kernel pages. | |
409 | */ | |
410 | static inline int pte_protnone(pte_t pte) | |
411 | { | |
412 | return (pte_val(pte) & | |
413 | (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT; | |
414 | } | |
415 | #endif /* CONFIG_NUMA_BALANCING */ | |
416 | ||
417 | static inline int pte_present(pte_t pte) | |
418 | { | |
849f86a6 | 419 | return !!(pte_val(pte) & _PAGE_PRESENT); |
1ca72129 AK |
420 | } |
421 | ||
422 | /* Conversion functions: convert a page and protection to a page entry, | |
423 | * and a page entry and page directory to the page they refer to. | |
424 | * | |
425 | * Even if PTEs can be unsigned long long, a PFN is always an unsigned | |
426 | * long for now. | |
427 | */ | |
428 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) | |
429 | { | |
f1a9ae03 | 430 | return __pte((((pte_basic_t)(pfn) << PTE_RPN_SHIFT) & PTE_RPN_MASK) | |
1ca72129 AK |
431 | pgprot_val(pgprot)); |
432 | } | |
433 | ||
434 | static inline unsigned long pte_pfn(pte_t pte) | |
435 | { | |
f1a9ae03 | 436 | return (pte_val(pte) & PTE_RPN_MASK) >> PTE_RPN_SHIFT; |
1ca72129 AK |
437 | } |
438 | ||
439 | /* Generic modifiers for PTE bits */ | |
440 | static inline pte_t pte_wrprotect(pte_t pte) | |
441 | { | |
442 | return __pte(pte_val(pte) & ~_PAGE_RW); | |
443 | } | |
444 | ||
445 | static inline pte_t pte_mkclean(pte_t pte) | |
446 | { | |
447 | return __pte(pte_val(pte) & ~_PAGE_DIRTY); | |
448 | } | |
449 | ||
450 | static inline pte_t pte_mkold(pte_t pte) | |
451 | { | |
452 | return __pte(pte_val(pte) & ~_PAGE_ACCESSED); | |
453 | } | |
454 | ||
455 | static inline pte_t pte_mkwrite(pte_t pte) | |
456 | { | |
457 | return __pte(pte_val(pte) | _PAGE_RW); | |
458 | } | |
459 | ||
460 | static inline pte_t pte_mkdirty(pte_t pte) | |
461 | { | |
7207f436 | 462 | return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY); |
1ca72129 AK |
463 | } |
464 | ||
465 | static inline pte_t pte_mkyoung(pte_t pte) | |
466 | { | |
467 | return __pte(pte_val(pte) | _PAGE_ACCESSED); | |
468 | } | |
469 | ||
470 | static inline pte_t pte_mkspecial(pte_t pte) | |
471 | { | |
472 | return __pte(pte_val(pte) | _PAGE_SPECIAL); | |
473 | } | |
474 | ||
475 | static inline pte_t pte_mkhuge(pte_t pte) | |
476 | { | |
477 | return pte; | |
478 | } | |
479 | ||
480 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |
481 | { | |
482 | return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); | |
483 | } | |
484 | ||
485 | /* This low level function performs the actual PTE insertion | |
486 | * Setting the PTE depends on the MMU type and other factors. It's | |
487 | * an horrible mess that I'm not going to try to clean up now but | |
488 | * I'm keeping it in one place rather than spread around | |
489 | */ | |
490 | static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, | |
491 | pte_t *ptep, pte_t pte, int percpu) | |
492 | { | |
493 | /* | |
494 | * Anything else just stores the PTE normally. That covers all 64-bit | |
495 | * cases, and 32-bit non-hash with 32-bit PTEs. | |
496 | */ | |
497 | *ptep = pte; | |
498 | } | |
499 | ||
500 | /* | |
501 | * Macro to mark a page protection value as "uncacheable". | |
502 | */ | |
503 | ||
504 | #define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \ | |
505 | _PAGE_WRITETHRU) | |
506 | ||
507 | #define pgprot_noncached pgprot_noncached | |
508 | static inline pgprot_t pgprot_noncached(pgprot_t prot) | |
509 | { | |
510 | return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | | |
511 | _PAGE_NO_CACHE | _PAGE_GUARDED); | |
512 | } | |
513 | ||
514 | #define pgprot_noncached_wc pgprot_noncached_wc | |
515 | static inline pgprot_t pgprot_noncached_wc(pgprot_t prot) | |
516 | { | |
517 | return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | | |
518 | _PAGE_NO_CACHE); | |
519 | } | |
520 | ||
521 | #define pgprot_cached pgprot_cached | |
522 | static inline pgprot_t pgprot_cached(pgprot_t prot) | |
523 | { | |
524 | return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | | |
525 | _PAGE_COHERENT); | |
526 | } | |
527 | ||
528 | #define pgprot_cached_wthru pgprot_cached_wthru | |
529 | static inline pgprot_t pgprot_cached_wthru(pgprot_t prot) | |
530 | { | |
531 | return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | | |
532 | _PAGE_COHERENT | _PAGE_WRITETHRU); | |
533 | } | |
534 | ||
535 | #define pgprot_cached_noncoherent pgprot_cached_noncoherent | |
536 | static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot) | |
537 | { | |
538 | return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL); | |
539 | } | |
540 | ||
541 | #define pgprot_writecombine pgprot_writecombine | |
542 | static inline pgprot_t pgprot_writecombine(pgprot_t prot) | |
543 | { | |
544 | return pgprot_noncached_wc(prot); | |
545 | } | |
546 | ||
371352ca AK |
547 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
548 | extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, | |
549 | pmd_t *pmdp, unsigned long old_pmd); | |
550 | #else | |
551 | static inline void hpte_do_hugepage_flush(struct mm_struct *mm, | |
552 | unsigned long addr, pmd_t *pmdp, | |
553 | unsigned long old_pmd) | |
554 | { | |
555 | WARN(1, "%s called with THP disabled\n", __func__); | |
556 | } | |
557 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | |
558 | ||
559 | #endif /* !__ASSEMBLY__ */ | |
c605782b | 560 | #endif /* __KERNEL__ */ |
26b6a3d9 | 561 | #endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */ |