1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _ASM_S390_PGTABLE_H
14#define _ASM_S390_PGTABLE_H
15
16#include <asm-generic/4level-fixup.h>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#ifndef __ASSEMBLY__
34#include <asm/bug.h>
35#include <asm/processor.h>
36#include <linux/threads.h>
37
38struct vm_area_struct;
39
40extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
41extern void paging_init(void);
42
43
44
45
46
47#define update_mmu_cache(vma, address, pte) do { } while (0)
48
49
50
51
52
53extern char empty_zero_page[PAGE_SIZE];
54#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
55#endif
56
57
58
59
60
61
62#ifndef __s390x__
63# define PMD_SHIFT 22
64# define PGDIR_SHIFT 22
65#else
66# define PMD_SHIFT 21
67# define PGDIR_SHIFT 31
68#endif
69
70#define PMD_SIZE (1UL << PMD_SHIFT)
71#define PMD_MASK (~(PMD_SIZE-1))
72#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
73#define PGDIR_MASK (~(PGDIR_SIZE-1))
74
75
76
77
78
79
80
81#ifndef __s390x__
82# define PTRS_PER_PTE 1024
83# define PTRS_PER_PMD 1
84# define PTRS_PER_PGD 512
85#else
86# define PTRS_PER_PTE 512
87# define PTRS_PER_PMD 1024
88# define PTRS_PER_PGD 2048
89#endif
90
91
92
93
94#ifndef __s390x__
95# define USER_PTRS_PER_PGD 512
96# define USER_PGD_PTRS 512
97# define KERNEL_PGD_PTRS 512
98# define FIRST_USER_PGD_NR 0
99#else
100# define USER_PTRS_PER_PGD 2048
101# define USER_PGD_PTRS 2048
102# define KERNEL_PGD_PTRS 2048
103# define FIRST_USER_PGD_NR 0
104#endif
105
106#define pte_ERROR(e) \
107 printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
108#define pmd_ERROR(e) \
109 printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
110#define pgd_ERROR(e) \
111 printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
112
113#ifndef __ASSEMBLY__
114
115
116
117
118
119
120
121
122#define VMALLOC_OFFSET (8*1024*1024)
123#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \
124 & ~(VMALLOC_OFFSET-1))
125#ifndef __s390x__
126# define VMALLOC_END (0x7fffffffL)
127#else
128# define VMALLOC_END (0x40000000000L)
129#endif
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215#define _PAGE_RO 0x200
216#define _PAGE_INVALID 0x400
217
218
219#define _PAGE_INVALID_MASK 0x601
220#define _PAGE_INVALID_EMPTY 0x400
221#define _PAGE_INVALID_NONE 0x401
222#define _PAGE_INVALID_SWAP 0x600
223#define _PAGE_INVALID_FILE 0x601
224
225#ifndef __s390x__
226
227
228#define _PAGE_TABLE_LEN 0xf
229#define _PAGE_TABLE_COM 0x10
230#define _PAGE_TABLE_INV 0x20
231#define _SEG_PRESENT 0x001
232
233
234#define _PAGE_CHANGED 0x02
235#define _PAGE_REFERENCED 0x04
236
237#define _USER_SEG_TABLE_LEN 0x7f
238#define _KERNEL_SEG_TABLE_LEN 0x7f
239
240
241
242
243#define _PAGE_TABLE _PAGE_TABLE_LEN
244#define _KERNPG_TABLE _PAGE_TABLE_LEN
245
246
247
248
249
250#define _SEGMENT_TABLE (_USER_SEG_TABLE_LEN|0x80000000|0x100)
251#define _KERNSEG_TABLE _KERNEL_SEG_TABLE_LEN
252
253#define USER_STD_MASK 0x00000080UL
254
255#else
256
257
258#define _PMD_ENTRY_INV 0x20
259#define _PMD_ENTRY 0x00
260
261
262#define _PGD_ENTRY_INV 0x20
263#define _PGD_ENTRY 0x07
264
265
266
267
268#define _REGION_THIRD 0x4
269#define _REGION_THIRD_LEN 0x3
270#define _REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
271#define _KERN_REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN)
272
273#define USER_STD_MASK 0x0000000000000080UL
274
275
276#define _PAGE_CHANGED 0x02
277#define _PAGE_REFERENCED 0x04
278
279#endif
280
281
282
283
284#define PAGE_NONE_SHARED __pgprot(_PAGE_INVALID_NONE)
285#define PAGE_NONE_PRIVATE __pgprot(_PAGE_INVALID_NONE)
286#define PAGE_RO_SHARED __pgprot(_PAGE_RO)
287#define PAGE_RO_PRIVATE __pgprot(_PAGE_RO)
288#define PAGE_COPY __pgprot(_PAGE_RO)
289#define PAGE_SHARED __pgprot(0)
290#define PAGE_KERNEL __pgprot(0)
291
292
293
294
295
296
297
298#define __P000 PAGE_NONE_PRIVATE
299#define __P001 PAGE_RO_PRIVATE
300#define __P010 PAGE_COPY
301#define __P011 PAGE_COPY
302#define __P100 PAGE_RO_PRIVATE
303#define __P101 PAGE_RO_PRIVATE
304#define __P110 PAGE_COPY
305#define __P111 PAGE_COPY
306
307#define __S000 PAGE_NONE_SHARED
308#define __S001 PAGE_RO_SHARED
309#define __S010 PAGE_SHARED
310#define __S011 PAGE_SHARED
311#define __S100 PAGE_RO_SHARED
312#define __S101 PAGE_RO_SHARED
313#define __S110 PAGE_SHARED
314#define __S111 PAGE_SHARED
315
316
317
318
319
320
321extern inline void set_pte(pte_t *pteptr, pte_t pteval)
322{
323 *pteptr = pteval;
324}
325
326
327
328
329#ifndef __s390x__
330
331extern inline int pgd_present(pgd_t pgd) { return 1; }
332extern inline int pgd_none(pgd_t pgd) { return 0; }
333extern inline int pgd_bad(pgd_t pgd) { return 0; }
334
335extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
336extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
337extern inline int pmd_bad(pmd_t pmd)
338{
339 return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
340}
341
342#else
343
344extern inline int pgd_present(pgd_t pgd)
345{
346 return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
347}
348
349extern inline int pgd_none(pgd_t pgd)
350{
351 return pgd_val(pgd) & _PGD_ENTRY_INV;
352}
353
354extern inline int pgd_bad(pgd_t pgd)
355{
356 return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
357}
358
359extern inline int pmd_present(pmd_t pmd)
360{
361 return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
362}
363
364extern inline int pmd_none(pmd_t pmd)
365{
366 return pmd_val(pmd) & _PMD_ENTRY_INV;
367}
368
369extern inline int pmd_bad(pmd_t pmd)
370{
371 return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
372}
373
374#endif
375
376extern inline int pte_none(pte_t pte)
377{
378 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY;
379}
380
381extern inline int pte_present(pte_t pte)
382{
383 return !(pte_val(pte) & _PAGE_INVALID) ||
384 (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE;
385}
386
387extern inline int pte_file(pte_t pte)
388{
389 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE;
390}
391
392#define pte_same(a,b) (pte_val(a) == pte_val(b))
393
394
395
396
397
398extern inline int pte_write(pte_t pte)
399{
400 return (pte_val(pte) & _PAGE_RO) == 0;
401}
402
403extern inline int pte_dirty(pte_t pte)
404{
405
406
407
408
409 return 0;
410}
411
412extern inline int pte_young(pte_t pte)
413{
414
415
416
417
418 return 0;
419}
420
421extern inline int pte_read(pte_t pte)
422{
423
424
425
426 return 1;
427}
428
429
430
431
432
433#ifndef __s390x__
434
435extern inline void pgd_clear(pgd_t * pgdp) { }
436
437extern inline void pmd_clear(pmd_t * pmdp)
438{
439 pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
440 pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
441 pmd_val(pmdp[2]) = _PAGE_TABLE_INV;
442 pmd_val(pmdp[3]) = _PAGE_TABLE_INV;
443}
444
445#else
446
447extern inline void pgd_clear(pgd_t * pgdp)
448{
449 pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
450}
451
452extern inline void pmd_clear(pmd_t * pmdp)
453{
454 pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
455 pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
456}
457
458#endif
459
460extern inline void pte_clear(pte_t *ptep)
461{
462 pte_val(*ptep) = _PAGE_INVALID_EMPTY;
463}
464
465
466
467
468
469extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
470{
471 pte_val(pte) &= PAGE_MASK;
472 pte_val(pte) |= pgprot_val(newprot);
473 return pte;
474}
475
476extern inline pte_t pte_wrprotect(pte_t pte)
477{
478
479 if (!(pte_val(pte) & _PAGE_INVALID))
480 pte_val(pte) |= _PAGE_RO;
481 return pte;
482}
483
484extern inline pte_t pte_mkwrite(pte_t pte)
485{
486 pte_val(pte) &= ~_PAGE_RO;
487 return pte;
488}
489
490extern inline pte_t pte_mkclean(pte_t pte)
491{
492
493
494
495
496 return pte;
497}
498
499extern inline pte_t pte_mkdirty(pte_t pte)
500{
501
502
503
504
505 return pte;
506}
507
508extern inline pte_t pte_mkold(pte_t pte)
509{
510
511
512
513 return pte;
514}
515
516extern inline pte_t pte_mkyoung(pte_t pte)
517{
518
519
520
521 return pte;
522}
523
524static inline int ptep_test_and_clear_young(pte_t *ptep)
525{
526 return 0;
527}
528
529static inline int
530ptep_clear_flush_young(struct vm_area_struct *vma,
531 unsigned long address, pte_t *ptep)
532{
533
534 return ptep_test_and_clear_young(ptep);
535}
536
537static inline int ptep_test_and_clear_dirty(pte_t *ptep)
538{
539 return 0;
540}
541
542static inline int
543ptep_clear_flush_dirty(struct vm_area_struct *vma,
544 unsigned long address, pte_t *ptep)
545{
546
547 return ptep_test_and_clear_dirty(ptep);
548}
549
550static inline pte_t ptep_get_and_clear(pte_t *ptep)
551{
552 pte_t pte = *ptep;
553 pte_clear(ptep);
554 return pte;
555}
556
557static inline pte_t
558ptep_clear_flush(struct vm_area_struct *vma,
559 unsigned long address, pte_t *ptep)
560{
561 pte_t pte = *ptep;
562#ifndef __s390x__
563 if (!(pte_val(pte) & _PAGE_INVALID)) {
564
565 pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00);
566 __asm__ __volatile__ ("ipte %2,%3"
567 : "=m" (*ptep) : "m" (*ptep),
568 "a" (pto), "a" (address) );
569 }
570#else
571 if (!(pte_val(pte) & _PAGE_INVALID))
572 __asm__ __volatile__ ("ipte %2,%3"
573 : "=m" (*ptep) : "m" (*ptep),
574 "a" (ptep), "a" (address) );
575#endif
576 pte_clear(ptep);
577 return pte;
578}
579
580static inline void ptep_set_wrprotect(pte_t *ptep)
581{
582 pte_t old_pte = *ptep;
583 set_pte(ptep, pte_wrprotect(old_pte));
584}
585
586static inline void ptep_mkdirty(pte_t *ptep)
587{
588 pte_mkdirty(*ptep);
589}
590
591static inline void
592ptep_establish(struct vm_area_struct *vma,
593 unsigned long address, pte_t *ptep,
594 pte_t entry)
595{
596 ptep_clear_flush(vma, address, ptep);
597 set_pte(ptep, entry);
598}
599
600#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
601 ptep_establish(__vma, __address, __ptep, __entry)
602
603
604
605
606
607
608
609
610#define page_test_and_clear_dirty(_page) \
611({ \
612 struct page *__page = (_page); \
613 unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
614 int __skey = page_get_storage_key(__physpage); \
615 if (__skey & _PAGE_CHANGED) \
616 page_set_storage_key(__physpage, __skey & ~_PAGE_CHANGED);\
617 (__skey & _PAGE_CHANGED); \
618})
619
620
621
622
623#define page_test_and_clear_young(page) \
624({ \
625 struct page *__page = (page); \
626 unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
627 int __ccode; \
628 asm volatile ("rrbe 0,%1\n\t" \
629 "ipm %0\n\t" \
630 "srl %0,28\n\t" \
631 : "=d" (__ccode) : "a" (__physpage) : "cc" ); \
632 (__ccode & 2); \
633})
634
635
636
637
638
639static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
640{
641 pte_t __pte;
642 pte_val(__pte) = physpage + pgprot_val(pgprot);
643 return __pte;
644}
645
646#define mk_pte(pg, pgprot) \
647({ \
648 struct page *__page = (pg); \
649 pgprot_t __pgprot = (pgprot); \
650 unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
651 pte_t __pte = mk_pte_phys(__physpage, __pgprot); \
652 __pte; \
653})
654
655#define pfn_pte(pfn, pgprot) \
656({ \
657 pgprot_t __pgprot = (pgprot); \
658 unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \
659 pte_t __pte = mk_pte_phys(__physpage, __pgprot); \
660 __pte; \
661})
662
663#define SetPageUptodate(_page) \
664 do { \
665 struct page *__page = (_page); \
666 if (!test_and_set_bit(PG_uptodate, &__page->flags)) \
667 page_test_and_clear_dirty(_page); \
668 } while (0)
669
670#ifdef __s390x__
671
672#define pfn_pmd(pfn, pgprot) \
673({ \
674 pgprot_t __pgprot = (pgprot); \
675 unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \
676 pmd_t __pmd = __pmd(__physpage + pgprot_val(__pgprot)); \
677 __pmd; \
678})
679
680#endif
681
682#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
683#define pte_page(x) pfn_to_page(pte_pfn(x))
684
685#define pmd_page_kernel(pmd) (pmd_val(pmd) & PAGE_MASK)
686
687#define pmd_page(pmd) (mem_map+(pmd_val(pmd) >> PAGE_SHIFT))
688
689#define pgd_page_kernel(pgd) (pgd_val(pgd) & PAGE_MASK)
690
691
692#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
693#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
694
695
696#define pgd_offset_k(address) pgd_offset(&init_mm, address)
697
698#ifndef __s390x__
699
700
701extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
702{
703 return (pmd_t *) dir;
704}
705
706#else
707
708
709#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
710#define pmd_offset(dir,addr) \
711 ((pmd_t *) pgd_page_kernel(*(dir)) + pmd_index(addr))
712
713#endif
714
715
716#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
717#define pte_offset_kernel(pmd, address) \
718 ((pte_t *) pmd_page_kernel(*(pmd)) + pte_index(address))
719#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
720#define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
721#define pte_unmap(pte) do { } while (0)
722#define pte_unmap_nested(pte) do { } while (0)
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
760{
761 pte_t pte;
762 pte_val(pte) = _PAGE_INVALID_SWAP | ((type & 0x1f) << 2) |
763 ((offset & 1) << 7) | ((offset & 0xffffe) << 11);
764 return pte;
765}
766
767#define __swp_type(entry) (((entry).val >> 2) & 0x1f)
768#define __swp_offset(entry) (((entry).val >> 11) | (((entry).val >> 7) & 1))
769#define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) })
770
771#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
772#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
773
774#ifndef __s390x__
775# define PTE_FILE_MAX_BITS 26
776#else
777# define PTE_FILE_MAX_BITS 59
778#endif
779
780#define pte_to_pgoff(__pte) \
781 ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f))
782
783#define pgoff_to_pte(__off) \
784 ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \
785 | _PAGE_INVALID_FILE })
786
787#endif
788
789#define kern_addr_valid(addr) (1)
790
791
792
793
794#define pgtable_cache_init() do { } while (0)
795
796#define __HAVE_ARCH_PTEP_ESTABLISH
797#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
798#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
799#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
800#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
801#define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
802#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
803#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
804#define __HAVE_ARCH_PTEP_SET_WRPROTECT
805#define __HAVE_ARCH_PTEP_MKDIRTY
806#define __HAVE_ARCH_PTE_SAME
807#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
808#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
809#include <asm-generic/pgtable.h>
810
811#endif
812
813