aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390/pgtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-s390/pgtable.h')
-rw-r--r--include/asm-s390/pgtable.h123
1 files changed, 62 insertions, 61 deletions
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index f9f59a805e5d..f2cc25b74adf 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