diff options
author | Gerald Schaefer <geraldsc@de.ibm.com> | 2008-04-30 07:38:46 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-04-30 07:38:47 -0400 |
commit | 53492b1de46a7576170e865062ffcfc93bb5650b (patch) | |
tree | bee94e5b2e8c19c1a094a25023cb82572707feb4 /arch/s390/kernel | |
parent | 2e5061e40af88070984e3769eafb5a06022375fd (diff) |
[S390] System z large page support.
This adds hugetlbfs support on System z, using both hardware large page
support if available and software large page emulation on older hardware.
Shared (large) page tables are implemented in software emulation mode,
by using page->index of the first tail page from a compound large page
to store page table information.
Signed-off-by: Gerald Schaefer <geraldsc@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/early.c | 16 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 10 |
3 files changed, 24 insertions, 4 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index bd188f6bd0e2..d0e09684b9ce 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -268,6 +268,19 @@ static noinline __init void setup_lowcore_early(void) | |||
268 | s390_base_pgm_handler_fn = early_pgm_check_handler; | 268 | s390_base_pgm_handler_fn = early_pgm_check_handler; |
269 | } | 269 | } |
270 | 270 | ||
271 | static noinline __init void setup_hpage(void) | ||
272 | { | ||
273 | #ifndef CONFIG_DEBUG_PAGEALLOC | ||
274 | unsigned int facilities; | ||
275 | |||
276 | facilities = stfl(); | ||
277 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | ||
278 | return; | ||
279 | machine_flags |= MACHINE_FLAG_HPAGE; | ||
280 | __ctl_set_bit(0, 23); | ||
281 | #endif | ||
282 | } | ||
283 | |||
271 | static __init void detect_mvpg(void) | 284 | static __init void detect_mvpg(void) |
272 | { | 285 | { |
273 | #ifndef CONFIG_64BIT | 286 | #ifndef CONFIG_64BIT |
@@ -360,6 +373,8 @@ static __init void detect_machine_facilities(void) | |||
360 | facilities = stfl(); | 373 | facilities = stfl(); |
361 | if (facilities & (1 << 28)) | 374 | if (facilities & (1 << 28)) |
362 | machine_flags |= MACHINE_FLAG_IDTE; | 375 | machine_flags |= MACHINE_FLAG_IDTE; |
376 | if (facilities & (1 << 23)) | ||
377 | machine_flags |= MACHINE_FLAG_PFMF; | ||
363 | if (facilities & (1 << 4)) | 378 | if (facilities & (1 << 4)) |
364 | machine_flags |= MACHINE_FLAG_MVCOS; | 379 | machine_flags |= MACHINE_FLAG_MVCOS; |
365 | #endif | 380 | #endif |
@@ -388,6 +403,7 @@ void __init startup_init(void) | |||
388 | detect_diag9c(); | 403 | detect_diag9c(); |
389 | detect_diag44(); | 404 | detect_diag44(); |
390 | detect_machine_facilities(); | 405 | detect_machine_facilities(); |
406 | setup_hpage(); | ||
391 | sclp_read_info_early(); | 407 | sclp_read_info_early(); |
392 | sclp_facilities_detect(); | 408 | sclp_facilities_detect(); |
393 | memsize = sclp_memory_detect(); | 409 | memsize = sclp_memory_detect(); |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 9c2c6f7d37e7..1d06961e87b3 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -129,7 +129,7 @@ startup_continue: | |||
129 | # virtual and never return ... | 129 | # virtual and never return ... |
130 | .align 16 | 130 | .align 16 |
131 | .Lentry:.quad 0x0000000180000000,_stext | 131 | .Lentry:.quad 0x0000000180000000,_stext |
132 | .Lctl: .quad 0x04b50002 # cr0: various things | 132 | .Lctl: .quad 0x04350002 # cr0: various things |
133 | .quad 0 # cr1: primary space segment table | 133 | .quad 0 # cr1: primary space segment table |
134 | .quad .Lduct # cr2: dispatchable unit control table | 134 | .quad .Lduct # cr2: dispatchable unit control table |
135 | .quad 0 # cr3: instruction authorization | 135 | .quad 0 # cr3: instruction authorization |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 694c6546ce64..2bc70b6e876a 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -749,6 +749,9 @@ static void __init setup_hwcaps(void) | |||
749 | elf_hwcap |= 1UL << 6; | 749 | elf_hwcap |= 1UL << 6; |
750 | } | 750 | } |
751 | 751 | ||
752 | if (MACHINE_HAS_HPAGE) | ||
753 | elf_hwcap |= 1UL << 7; | ||
754 | |||
752 | switch (cpuinfo->cpu_id.machine) { | 755 | switch (cpuinfo->cpu_id.machine) { |
753 | case 0x9672: | 756 | case 0x9672: |
754 | #if !defined(CONFIG_64BIT) | 757 | #if !defined(CONFIG_64BIT) |
@@ -872,8 +875,9 @@ void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) | |||
872 | 875 | ||
873 | static int show_cpuinfo(struct seq_file *m, void *v) | 876 | static int show_cpuinfo(struct seq_file *m, void *v) |
874 | { | 877 | { |
875 | static const char *hwcap_str[7] = { | 878 | static const char *hwcap_str[8] = { |
876 | "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp" | 879 | "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", |
880 | "edat" | ||
877 | }; | 881 | }; |
878 | struct cpuinfo_S390 *cpuinfo; | 882 | struct cpuinfo_S390 *cpuinfo; |
879 | unsigned long n = (unsigned long) v - 1; | 883 | unsigned long n = (unsigned long) v - 1; |
@@ -888,7 +892,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
888 | num_online_cpus(), loops_per_jiffy/(500000/HZ), | 892 | num_online_cpus(), loops_per_jiffy/(500000/HZ), |
889 | (loops_per_jiffy/(5000/HZ))%100); | 893 | (loops_per_jiffy/(5000/HZ))%100); |
890 | seq_puts(m, "features\t: "); | 894 | seq_puts(m, "features\t: "); |
891 | for (i = 0; i < 7; i++) | 895 | for (i = 0; i < 8; i++) |
892 | if (hwcap_str[i] && (elf_hwcap & (1UL << i))) | 896 | if (hwcap_str[i] && (elf_hwcap & (1UL << i))) |
893 | seq_printf(m, "%s ", hwcap_str[i]); | 897 | seq_printf(m, "%s ", hwcap_str[i]); |
894 | seq_puts(m, "\n"); | 898 | seq_puts(m, "\n"); |