aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390/pgalloc.h
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2008-02-09 12:24:37 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-02-09 12:24:41 -0500
commit6252d702c5311ce916caf75ed82e5c8245171c92 (patch)
tree3490f27b5f888ff2c1ec915d4e7201000f37a771 /include/asm-s390/pgalloc.h
parent5a216a20837c5f5fa1ca4b8ae8991ffd96b08e6f (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.h24
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
74static inline unsigned long pgd_entry_type(struct mm_struct *mm) 74static 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
83int crst_table_upgrade(struct mm_struct *, unsigned long limit);
84void crst_table_downgrade(struct mm_struct *, unsigned long limit);
85
79static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) 86static 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
103static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) 110static 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
113static inline void pud_populate_kernel(struct mm_struct *mm, 120static 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
131static inline pgd_t *pgd_alloc(struct mm_struct *mm) 138static 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