diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 06:48:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 06:48:33 -0400 |
commit | e1b28147f684af67bfac989756c27c19859d3d4e (patch) | |
tree | 11b09d6801b94acf4511b06fb36933e3a163329a /arch/s390/kernel/setup.c | |
parent | ba7067651083bdcc37223d8879478cbc51cca923 (diff) | |
parent | ab08ff34b44f752b664ebb312d2e110cf37a7f5e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull second s390 update from Martin Schwidefsky:
"The big thing in this pull request is the UAPI patch from David, and
worth mentioning is the page table dumper. The rest are small
improvements and bug fixes."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/entry: fix svc number for TIF_SYSCALL system call restart
s390/mm,vmem: fix vmem_add_mem()/vmem_remove_range()
s390/vmalloc: have separate modules area
s390/zcrypt: remove duplicated include from zcrypt_pcixcc.c
s390/css_chars: remove superfluous ifdef
s390/chsc: make headers usable
s390/mm: let kernel text section always begin at 1MB
s390/mm: fix mapping of read-only kernel text section
s390/mm: add page table dumper
s390: add support to start the kernel in 64 bit mode.
s390/mm,pageattr: remove superfluous EXPORT_SYMBOLs
s390/mm,pageattr: add more page table walk sanity checks
s390/mm: fix pmd_huge() usage for kernel mapping
s390/dcssblk: cleanup device attribute usage
s390/mm: use pfmf instruction to initialize storage keys
s390/facilities: cleanup PFMF and HPAGE machine facility detection
UAPI: (Scripted) Disintegrate arch/s390/include/asm
Diffstat (limited to 'arch/s390/kernel/setup.c')
-rw-r--r-- | arch/s390/kernel/setup.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index afa9fdba200e..b1f2be9aaaad 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -105,6 +105,11 @@ EXPORT_SYMBOL(VMALLOC_END); | |||
105 | struct page *vmemmap; | 105 | struct page *vmemmap; |
106 | EXPORT_SYMBOL(vmemmap); | 106 | EXPORT_SYMBOL(vmemmap); |
107 | 107 | ||
108 | #ifdef CONFIG_64BIT | ||
109 | unsigned long MODULES_VADDR; | ||
110 | unsigned long MODULES_END; | ||
111 | #endif | ||
112 | |||
108 | /* An array with a pointer to the lowcore of every CPU. */ | 113 | /* An array with a pointer to the lowcore of every CPU. */ |
109 | struct _lowcore *lowcore_ptr[NR_CPUS]; | 114 | struct _lowcore *lowcore_ptr[NR_CPUS]; |
110 | EXPORT_SYMBOL(lowcore_ptr); | 115 | EXPORT_SYMBOL(lowcore_ptr); |
@@ -544,19 +549,23 @@ static void __init setup_memory_end(void) | |||
544 | 549 | ||
545 | /* Choose kernel address space layout: 2, 3, or 4 levels. */ | 550 | /* Choose kernel address space layout: 2, 3, or 4 levels. */ |
546 | #ifdef CONFIG_64BIT | 551 | #ifdef CONFIG_64BIT |
547 | vmalloc_size = VMALLOC_END ?: 128UL << 30; | 552 | vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN; |
548 | tmp = (memory_end ?: real_memory_size) / PAGE_SIZE; | 553 | tmp = (memory_end ?: real_memory_size) / PAGE_SIZE; |
549 | tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size; | 554 | tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size; |
550 | if (tmp <= (1UL << 42)) | 555 | if (tmp <= (1UL << 42)) |
551 | vmax = 1UL << 42; /* 3-level kernel page table */ | 556 | vmax = 1UL << 42; /* 3-level kernel page table */ |
552 | else | 557 | else |
553 | vmax = 1UL << 53; /* 4-level kernel page table */ | 558 | vmax = 1UL << 53; /* 4-level kernel page table */ |
559 | /* module area is at the end of the kernel address space. */ | ||
560 | MODULES_END = vmax; | ||
561 | MODULES_VADDR = MODULES_END - MODULES_LEN; | ||
562 | VMALLOC_END = MODULES_VADDR; | ||
554 | #else | 563 | #else |
555 | vmalloc_size = VMALLOC_END ?: 96UL << 20; | 564 | vmalloc_size = VMALLOC_END ?: 96UL << 20; |
556 | vmax = 1UL << 31; /* 2-level kernel page table */ | 565 | vmax = 1UL << 31; /* 2-level kernel page table */ |
557 | #endif | ||
558 | /* vmalloc area is at the end of the kernel address space. */ | 566 | /* vmalloc area is at the end of the kernel address space. */ |
559 | VMALLOC_END = vmax; | 567 | VMALLOC_END = vmax; |
568 | #endif | ||
560 | VMALLOC_START = vmax - vmalloc_size; | 569 | VMALLOC_START = vmax - vmalloc_size; |
561 | 570 | ||
562 | /* Split remaining virtual space between 1:1 mapping & vmemmap array */ | 571 | /* Split remaining virtual space between 1:1 mapping & vmemmap array */ |
@@ -768,6 +777,40 @@ static void __init reserve_crashkernel(void) | |||
768 | #endif | 777 | #endif |
769 | } | 778 | } |
770 | 779 | ||
780 | static void __init init_storage_keys(unsigned long start, unsigned long end) | ||
781 | { | ||
782 | unsigned long boundary, function, size; | ||
783 | |||
784 | while (start < end) { | ||
785 | if (MACHINE_HAS_EDAT2) { | ||
786 | /* set storage keys for a 2GB frame */ | ||
787 | function = 0x22000 | PAGE_DEFAULT_KEY; | ||
788 | size = 1UL << 31; | ||
789 | boundary = (start + size) & ~(size - 1); | ||
790 | if (boundary <= end) { | ||
791 | do { | ||
792 | start = pfmf(function, start); | ||
793 | } while (start < boundary); | ||
794 | continue; | ||
795 | } | ||
796 | } | ||
797 | if (MACHINE_HAS_EDAT1) { | ||
798 | /* set storage keys for a 1MB frame */ | ||
799 | function = 0x21000 | PAGE_DEFAULT_KEY; | ||
800 | size = 1UL << 20; | ||
801 | boundary = (start + size) & ~(size - 1); | ||
802 | if (boundary <= end) { | ||
803 | do { | ||
804 | start = pfmf(function, start); | ||
805 | } while (start < boundary); | ||
806 | continue; | ||
807 | } | ||
808 | } | ||
809 | page_set_storage_key(start, PAGE_DEFAULT_KEY, 0); | ||
810 | start += PAGE_SIZE; | ||
811 | } | ||
812 | } | ||
813 | |||
771 | static void __init setup_memory(void) | 814 | static void __init setup_memory(void) |
772 | { | 815 | { |
773 | unsigned long bootmap_size; | 816 | unsigned long bootmap_size; |
@@ -846,9 +889,7 @@ static void __init setup_memory(void) | |||
846 | memblock_add_node(PFN_PHYS(start_chunk), | 889 | memblock_add_node(PFN_PHYS(start_chunk), |
847 | PFN_PHYS(end_chunk - start_chunk), 0); | 890 | PFN_PHYS(end_chunk - start_chunk), 0); |
848 | pfn = max(start_chunk, start_pfn); | 891 | pfn = max(start_chunk, start_pfn); |
849 | for (; pfn < end_chunk; pfn++) | 892 | init_storage_keys(PFN_PHYS(pfn), PFN_PHYS(end_chunk)); |
850 | page_set_storage_key(PFN_PHYS(pfn), | ||
851 | PAGE_DEFAULT_KEY, 0); | ||
852 | } | 893 | } |
853 | 894 | ||
854 | psw_set_key(PAGE_DEFAULT_KEY); | 895 | psw_set_key(PAGE_DEFAULT_KEY); |