aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-s390')
-rw-r--r--include/asm-s390/page.h4
-rw-r--r--include/asm-s390/pgalloc.h32
-rw-r--r--include/asm-s390/pgtable.h123
-rw-r--r--include/asm-s390/tlb.h2
4 files changed, 90 insertions, 71 deletions
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index ceec3826a67..584d0ee3c7f 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -82,6 +82,7 @@ typedef struct { unsigned long pte; } pte_t;
82#ifndef __s390x__ 82#ifndef __s390x__
83 83
84typedef struct { unsigned long pmd; } pmd_t; 84typedef struct { unsigned long pmd; } pmd_t;
85typedef struct { unsigned long pud; } pud_t;
85typedef struct { 86typedef struct {
86 unsigned long pgd0; 87 unsigned long pgd0;
87 unsigned long pgd1; 88 unsigned long pgd1;
@@ -90,6 +91,7 @@ typedef struct {
90 } pgd_t; 91 } pgd_t;
91 92
92#define pmd_val(x) ((x).pmd) 93#define pmd_val(x) ((x).pmd)
94#define pud_val(x) ((x).pud)
93#define pgd_val(x) ((x).pgd0) 95#define pgd_val(x) ((x).pgd0)
94 96
95#else /* __s390x__ */ 97#else /* __s390x__ */
@@ -98,10 +100,12 @@ typedef struct {
98 unsigned long pmd0; 100 unsigned long pmd0;
99 unsigned long pmd1; 101 unsigned long pmd1;
100 } pmd_t; 102 } pmd_t;
103typedef struct { unsigned long pud; } pud_t;
101typedef struct { unsigned long pgd; } pgd_t; 104typedef struct { unsigned long pgd; } pgd_t;
102 105
103#define pmd_val(x) ((x).pmd0) 106#define pmd_val(x) ((x).pmd0)
104#define pmd_val1(x) ((x).pmd1) 107#define pmd_val1(x) ((x).pmd1)
108#define pud_val(x) ((x).pud)
105#define pgd_val(x) ((x).pgd) 109#define pgd_val(x) ((x).pgd)
106 110
107#endif /* __s390x__ */ 111#endif /* __s390x__ */
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index 229b0bd5933..709dd174095 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -56,11 +56,17 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm)
56 return _SEGMENT_ENTRY_EMPTY; 56 return _SEGMENT_ENTRY_EMPTY;
57} 57}
58 58
59#define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); })
60#define pud_free(x) do { } while (0)
61
59#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) 62#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); })
60#define pmd_free(x) do { } while (0) 63#define pmd_free(x) do { } while (0)
61 64
62#define pgd_populate(mm, pmd, pte) BUG() 65#define pgd_populate(mm, pgd, pud) BUG()
63#define pgd_populate_kernel(mm, pmd, pte) BUG() 66#define pgd_populate_kernel(mm, pgd, pud) BUG()
67
68#define pud_populate(mm, pud, pmd) BUG()
69#define pud_populate_kernel(mm, pud, pmd) BUG()
64 70
65#else /* __s390x__ */ 71#else /* __s390x__ */
66 72
@@ -69,6 +75,9 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm)
69 return _REGION3_ENTRY_EMPTY; 75 return _REGION3_ENTRY_EMPTY;
70} 76}
71 77
78#define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); })
79#define pud_free(x) do { } while (0)
80
72static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 81static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
73{ 82{
74 unsigned long *crst = crst_table_alloc(mm, s390_noexec); 83 unsigned long *crst = crst_table_alloc(mm, s390_noexec);
@@ -78,20 +87,23 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
78} 87}
79#define pmd_free(pmd) crst_table_free((unsigned long *) pmd) 88#define pmd_free(pmd) crst_table_free((unsigned long *) pmd)
80 89
81static inline void pgd_populate_kernel(struct mm_struct *mm, 90#define pgd_populate(mm, pgd, pud) BUG()
82 pgd_t *pgd, pmd_t *pmd) 91#define pgd_populate_kernel(mm, pgd, pud) BUG()
92
93static inline void pud_populate_kernel(struct mm_struct *mm,
94 pud_t *pud, pmd_t *pmd)
83{ 95{
84 pgd_val(*pgd) = _REGION3_ENTRY | __pa(pmd); 96 pud_val(*pud) = _REGION3_ENTRY | __pa(pmd);
85} 97}
86 98
87static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) 99static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
88{ 100{
89 pgd_t *shadow_pgd = get_shadow_table(pgd); 101 pud_t *shadow_pud = get_shadow_table(pud);
90 pmd_t *shadow_pmd = get_shadow_table(pmd); 102 pmd_t *shadow_pmd = get_shadow_table(pmd);
91 103
92 if (shadow_pgd && shadow_pmd) 104 if (shadow_pud && shadow_pmd)
93 pgd_populate_kernel(mm, shadow_pgd, shadow_pmd); 105 pud_populate_kernel(mm, shadow_pud, shadow_pmd);
94 pgd_populate_kernel(mm, pgd, pmd); 106 pud_populate_kernel(mm, pud, pmd);
95} 107}
96 108
97#endif /* __s390x__ */ 109#endif /* __s390x__ */
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index f9f59a805e5..f2cc25b74ad 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -13,8 +13,6 @@
13#ifndef _ASM_S390_PGTABLE_H 13#ifndef _ASM_S390_PGTABLE_H
14#define _ASM_S390_PGTABLE_H 14#define _ASM_S390_PGTABLE_H
15 15
16#include <asm-generic/4level-fixup.h>
17
18/* 16/*
19 * The Linux memory management assumes a three-level page table setup. For 17 * The Linux memory management assumes a three-level page table setup. For
20 * s390 31 bit we "fold" the mid level into the top-level page table, so 18 * s390 31 bit we "fold" the mid level into the top-level page table, so
@@ -60,14 +58,18 @@ extern char empty_zero_page[PAGE_SIZE];
60 */ 58 */
61#ifndef __s390x__ 59#ifndef __s390x__
62# define PMD_SHIFT 22 60# define PMD_SHIFT 22
61# define PUD_SHIFT 22
63# define PGDIR_SHIFT 22 62# define PGDIR_SHIFT 22
64#else /* __s390x__ */ 63#else /* __s390x__ */
65# define PMD_SHIFT 21 64# define PMD_SHIFT 21
65# define PUD_SHIFT 31
66# define PGDIR_SHIFT 31 66# define PGDIR_SHIFT 31
67#endif /* __s390x__ */ 67#endif /* __s390x__ */
68 68
69#define PMD_SIZE (1UL << PMD_SHIFT) 69#define PMD_SIZE (1UL << PMD_SHIFT)
70#define PMD_MASK (~(PMD_SIZE-1)) 70#define PMD_MASK (~(PMD_SIZE-1))
71#define PUD_SIZE (1UL << PUD_SHIFT)
72#define PUD_MASK (~(PUD_SIZE-1))
71#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 73#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
72#define PGDIR_MASK (~(PGDIR_SIZE-1)) 74#define PGDIR_MASK (~(PGDIR_SIZE-1))
73 75
@@ -80,10 +82,12 @@ extern char empty_zero_page[PAGE_SIZE];
80#ifndef __s390x__ 82#ifndef __s390x__
81# define PTRS_PER_PTE 1024 83# define PTRS_PER_PTE 1024
82# define PTRS_PER_PMD 1 84# define PTRS_PER_PMD 1
85# define PTRS_PER_PUD 1
83# define PTRS_PER_PGD 512 86# define PTRS_PER_PGD 512
84#else /* __s390x__ */ 87#else /* __s390x__ */
85# define PTRS_PER_PTE 512 88# define PTRS_PER_PTE 512
86# define PTRS_PER_PMD 1024 89# define PTRS_PER_PMD 1024
90# define PTRS_PER_PUD 1
87# define PTRS_PER_PGD 2048 91# define PTRS_PER_PGD 2048
88#endif /* __s390x__ */ 92#endif /* __s390x__ */
89 93
@@ -93,6 +97,8 @@ extern char empty_zero_page[PAGE_SIZE];
93 printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e)) 97 printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
94#define pmd_ERROR(e) \ 98#define pmd_ERROR(e) \
95 printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) 99 printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
100#define pud_ERROR(e) \
101 printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e))
96#define pgd_ERROR(e) \ 102#define pgd_ERROR(e) \
97 printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) 103 printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
98 104
@@ -192,7 +198,7 @@ extern unsigned long vmalloc_end;
192 * I Segment-Invalid Bit: Segment is not available for address-translation 198 * I Segment-Invalid Bit: Segment is not available for address-translation
193 * TT Type 01 199 * TT Type 01
194 * TF 200 * TF
195 * TL Table lenght 201 * TL Table length
196 * 202 *
197 * The 64 bit regiontable origin of S390 has following format: 203 * The 64 bit regiontable origin of S390 has following format:
198 * | region table origon | DTTL 204 * | region table origon | DTTL
@@ -435,22 +441,30 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
435static inline int pgd_none(pgd_t pgd) { return 0; } 441static inline int pgd_none(pgd_t pgd) { return 0; }
436static inline int pgd_bad(pgd_t pgd) { return 0; } 442static inline int pgd_bad(pgd_t pgd) { return 0; }
437 443
444static inline int pud_present(pud_t pud) { return 1; }
445static inline int pud_none(pud_t pud) { return 0; }
446static inline int pud_bad(pud_t pud) { return 0; }
447
438#else /* __s390x__ */ 448#else /* __s390x__ */
439 449
440static inline int pgd_present(pgd_t pgd) 450static inline int pgd_present(pgd_t pgd) { return 1; }
451static inline int pgd_none(pgd_t pgd) { return 0; }
452static inline int pgd_bad(pgd_t pgd) { return 0; }
453
454static inline int pud_present(pud_t pud)
441{ 455{
442 return pgd_val(pgd) & _REGION_ENTRY_ORIGIN; 456 return pud_val(pud) & _REGION_ENTRY_ORIGIN;
443} 457}
444 458
445static inline int pgd_none(pgd_t pgd) 459static inline int pud_none(pud_t pud)
446{ 460{
447 return pgd_val(pgd) & _REGION_ENTRY_INV; 461 return pud_val(pud) & _REGION_ENTRY_INV;
448} 462}
449 463
450static inline int pgd_bad(pgd_t pgd) 464static inline int pud_bad(pud_t pud)
451{ 465{
452 unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV; 466 unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV;
453 return (pgd_val(pgd) & mask) != _REGION3_ENTRY; 467 return (pud_val(pud) & mask) != _REGION3_ENTRY;
454} 468}
455 469
456#endif /* __s390x__ */ 470#endif /* __s390x__ */
@@ -526,7 +540,8 @@ static inline int pte_young(pte_t pte)
526 540
527#ifndef __s390x__ 541#ifndef __s390x__
528 542
529static inline void pgd_clear(pgd_t * pgdp) { } 543#define pgd_clear(pgd) do { } while (0)
544#define pud_clear(pud) do { } while (0)
530 545
531static inline void pmd_clear_kernel(pmd_t * pmdp) 546static inline void pmd_clear_kernel(pmd_t * pmdp)
532{ 547{
@@ -538,18 +553,20 @@ static inline void pmd_clear_kernel(pmd_t * pmdp)
538 553
539#else /* __s390x__ */ 554#else /* __s390x__ */
540 555
541static inline void pgd_clear_kernel(pgd_t * pgdp) 556#define pgd_clear(pgd) do { } while (0)
557
558static inline void pud_clear_kernel(pud_t *pud)
542{ 559{
543 pgd_val(*pgdp) = _REGION3_ENTRY_EMPTY; 560 pud_val(*pud) = _REGION3_ENTRY_EMPTY;
544} 561}
545 562
546static inline void pgd_clear(pgd_t * pgdp) 563static inline void pud_clear(pud_t * pud)
547{ 564{
548 pgd_t *shadow_pgd = get_shadow_table(pgdp); 565 pud_t *shadow = get_shadow_table(pud);
549 566
550 pgd_clear_kernel(pgdp); 567 pud_clear_kernel(pud);
551 if (shadow_pgd) 568 if (shadow)
552 pgd_clear_kernel(shadow_pgd); 569 pud_clear_kernel(shadow);
553} 570}
554 571
555static inline void pmd_clear_kernel(pmd_t * pmdp) 572static inline void pmd_clear_kernel(pmd_t * pmdp)
@@ -810,63 +827,48 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
810 return mk_pte_phys(physpage, pgprot); 827 return mk_pte_phys(physpage, pgprot);
811} 828}
812 829
813static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) 830#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
814{ 831#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
815 unsigned long physpage = __pa((pfn) << PAGE_SHIFT); 832#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
816 833#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
817 return mk_pte_phys(physpage, pgprot);
818}
819
820#ifdef __s390x__
821
822static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
823{
824 unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
825
826 return __pmd(physpage + pgprot_val(pgprot));
827}
828
829#endif /* __s390x__ */
830
831#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
832#define pte_page(x) pfn_to_page(pte_pfn(x))
833 834
834#define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK) 835#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
836#define pgd_offset_k(address) pgd_offset(&init_mm, address)
835 837
836#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) 838#ifndef __s390x__
837 839
838#define pgd_page_vaddr(pgd) (pgd_val(pgd) & PAGE_MASK) 840#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
841#define pud_deref(pmd) ({ BUG(); 0UL; })
842#define pgd_deref(pmd) ({ BUG(); 0UL; })
839 843
840#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) 844#define pud_offset(pgd, address) ((pud_t *) pgd)
845#define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address))
841 846
842/* to find an entry in a page-table-directory */ 847#else /* __s390x__ */
843#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
844#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
845 848
846/* to find an entry in a kernel page-table-directory */ 849#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
847#define pgd_offset_k(address) pgd_offset(&init_mm, address) 850#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN)
851#define pgd_deref(pgd) ({ BUG(); 0UL; })
848 852
849#ifndef __s390x__ 853#define pud_offset(pgd, address) ((pud_t *) pgd)
850 854
851/* Find an entry in the second-level page table.. */ 855static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
852static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
853{ 856{
854 return (pmd_t *) dir; 857 pmd_t *pmd = (pmd_t *) pud_deref(*pud);
858 return pmd + pmd_index(address);
855} 859}
856 860
857#else /* __s390x__ */ 861#endif /* __s390x__ */
858 862
859/* Find an entry in the second-level page table.. */ 863#define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot))
860#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) 864#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
861#define pmd_offset(dir,addr) \ 865#define pte_page(x) pfn_to_page(pte_pfn(x))
862 ((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(addr))
863 866
864#endif /* __s390x__ */ 867#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
865 868
866/* Find an entry in the third-level page table.. */ 869/* Find an entry in the lowest level page table.. */
867#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) 870#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr))
868#define pte_offset_kernel(pmd, address) \ 871#define pte_offset_kernel(pmd, address) pte_offset(pmd,address)
869 ((pte_t *) pmd_page_vaddr(*(pmd)) + pte_index(address))
870#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address) 872#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
871#define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address) 873#define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
872#define pte_unmap(pte) do { } while (0) 874#define pte_unmap(pte) do { } while (0)
@@ -959,4 +961,3 @@ extern void memmap_init(unsigned long, int, unsigned long, unsigned long);
959#include <asm-generic/pgtable.h> 961#include <asm-generic/pgtable.h>
960 962
961#endif /* _S390_PAGE_H */ 963#endif /* _S390_PAGE_H */
962
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h
index 55ae45ef31b..618693cfc10 100644
--- a/include/asm-s390/tlb.h
+++ b/include/asm-s390/tlb.h
@@ -121,6 +121,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
121#endif 121#endif
122} 122}
123 123
124#define pud_free_tlb(tlb, pud) do { } while (0)
125
124#define tlb_start_vma(tlb, vma) do { } while (0) 126#define tlb_start_vma(tlb, vma) do { } while (0)
125#define tlb_end_vma(tlb, vma) do { } while (0) 127#define tlb_end_vma(tlb, vma) do { } while (0)
126#define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0) 128#define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0)