diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:37 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:41 -0500 |
commit | 6252d702c5311ce916caf75ed82e5c8245171c92 (patch) | |
tree | 3490f27b5f888ff2c1ec915d4e7201000f37a771 /include/asm-s390/pgalloc.h | |
parent | 5a216a20837c5f5fa1ca4b8ae8991ffd96b08e6f (diff) |
[S390] dynamic page tables.
Add support for different number of page table levels dependent
on the highest address used for a process. This will cause a 31 bit
process to use a two level page table instead of the four level page
table that is the default after the pud has been introduced. Likewise
a normal 64 bit process will use three levels instead of four. Only
if a process runs out of the 4 tera bytes which can be addressed with
a three level page table the fourth level is dynamically added. Then
the process can use up to 8 peta byte.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'include/asm-s390/pgalloc.h')
-rw-r--r-- | include/asm-s390/pgalloc.h | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index cc47dd65a499..f5b2bf3d7c1d 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h | |||
@@ -73,9 +73,16 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) | |||
73 | 73 | ||
74 | static inline unsigned long pgd_entry_type(struct mm_struct *mm) | 74 | static inline unsigned long pgd_entry_type(struct mm_struct *mm) |
75 | { | 75 | { |
76 | if (mm->context.asce_limit <= (1UL << 31)) | ||
77 | return _SEGMENT_ENTRY_EMPTY; | ||
78 | if (mm->context.asce_limit <= (1UL << 42)) | ||
79 | return _REGION3_ENTRY_EMPTY; | ||
76 | return _REGION2_ENTRY_EMPTY; | 80 | return _REGION2_ENTRY_EMPTY; |
77 | } | 81 | } |
78 | 82 | ||
83 | int crst_table_upgrade(struct mm_struct *, unsigned long limit); | ||
84 | void crst_table_downgrade(struct mm_struct *, unsigned long limit); | ||
85 | |||
79 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) | 86 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) |
80 | { | 87 | { |
81 | unsigned long *table = crst_table_alloc(mm, mm->context.noexec); | 88 | unsigned long *table = crst_table_alloc(mm, mm->context.noexec); |
@@ -102,12 +109,12 @@ static inline void pgd_populate_kernel(struct mm_struct *mm, | |||
102 | 109 | ||
103 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) | 110 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) |
104 | { | 111 | { |
105 | pgd_t *shadow_pgd = get_shadow_table(pgd); | ||
106 | pud_t *shadow_pud = get_shadow_table(pud); | ||
107 | |||
108 | if (shadow_pgd && shadow_pud) | ||
109 | pgd_populate_kernel(mm, shadow_pgd, shadow_pud); | ||
110 | pgd_populate_kernel(mm, pgd, pud); | 112 | pgd_populate_kernel(mm, pgd, pud); |
113 | if (mm->context.noexec) { | ||
114 | pgd = get_shadow_table(pgd); | ||
115 | pud = get_shadow_table(pud); | ||
116 | pgd_populate_kernel(mm, pgd, pud); | ||
117 | } | ||
111 | } | 118 | } |
112 | 119 | ||
113 | static inline void pud_populate_kernel(struct mm_struct *mm, | 120 | static inline void pud_populate_kernel(struct mm_struct *mm, |
@@ -130,14 +137,9 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | |||
130 | 137 | ||
131 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 138 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
132 | { | 139 | { |
133 | unsigned long *crst; | ||
134 | |||
135 | INIT_LIST_HEAD(&mm->context.crst_list); | 140 | INIT_LIST_HEAD(&mm->context.crst_list); |
136 | INIT_LIST_HEAD(&mm->context.pgtable_list); | 141 | INIT_LIST_HEAD(&mm->context.pgtable_list); |
137 | crst = crst_table_alloc(mm, s390_noexec); | 142 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); |
138 | if (crst) | ||
139 | crst_table_init(crst, pgd_entry_type(mm)); | ||
140 | return (pgd_t *) crst; | ||
141 | } | 143 | } |
142 | #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) | 144 | #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) |
143 | 145 | ||