aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/page.h14
-rw-r--r--arch/s390/include/asm/setup.h3
-rw-r--r--arch/s390/kernel/early.c2
-rw-r--r--arch/s390/kernel/setup.c38
4 files changed, 51 insertions, 6 deletions
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 27ab3c7c1e8b..6d5367060a56 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -30,12 +30,20 @@
30#include <asm/setup.h> 30#include <asm/setup.h>
31#ifndef __ASSEMBLY__ 31#ifndef __ASSEMBLY__
32 32
33static unsigned long pfmf(unsigned long function, unsigned long address)
34{
35 asm volatile(
36 " .insn rre,0xb9af0000,%[function],%[address]"
37 : [address] "+a" (address)
38 : [function] "d" (function)
39 : "memory");
40 return address;
41}
42
33static inline void clear_page(void *page) 43static inline void clear_page(void *page)
34{ 44{
35 if (MACHINE_HAS_PFMF) { 45 if (MACHINE_HAS_PFMF) {
36 asm volatile( 46 pfmf(0x10000, (unsigned long)page);
37 " .insn rre,0xb9af0000,%0,%1"
38 : : "d" (0x10000), "a" (page) : "memory", "cc");
39 } else { 47 } else {
40 register unsigned long reg1 asm ("1") = 0; 48 register unsigned long reg1 asm ("1") = 0;
41 register void *reg2 asm ("2") = page; 49 register void *reg2 asm ("2") = page;
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index a798985515b7..bc1b87b7453a 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -76,6 +76,7 @@ extern unsigned int s390_user_mode;
76#define MACHINE_FLAG_MVCOS (1UL << 8) 76#define MACHINE_FLAG_MVCOS (1UL << 8)
77#define MACHINE_FLAG_KVM (1UL << 9) 77#define MACHINE_FLAG_KVM (1UL << 9)
78#define MACHINE_FLAG_EDAT1 (1UL << 10) 78#define MACHINE_FLAG_EDAT1 (1UL << 10)
79#define MACHINE_FLAG_EDAT2 (1UL << 11)
79#define MACHINE_FLAG_LPAR (1UL << 12) 80#define MACHINE_FLAG_LPAR (1UL << 12)
80#define MACHINE_FLAG_SPP (1UL << 13) 81#define MACHINE_FLAG_SPP (1UL << 13)
81#define MACHINE_FLAG_TOPOLOGY (1UL << 14) 82#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
@@ -98,6 +99,7 @@ extern unsigned int s390_user_mode;
98#define MACHINE_HAS_MVPG (S390_lowcore.machine_flags & MACHINE_FLAG_MVPG) 99#define MACHINE_HAS_MVPG (S390_lowcore.machine_flags & MACHINE_FLAG_MVPG)
99#define MACHINE_HAS_MVCOS (0) 100#define MACHINE_HAS_MVCOS (0)
100#define MACHINE_HAS_EDAT1 (0) 101#define MACHINE_HAS_EDAT1 (0)
102#define MACHINE_HAS_EDAT2 (0)
101#define MACHINE_HAS_SPP (0) 103#define MACHINE_HAS_SPP (0)
102#define MACHINE_HAS_TOPOLOGY (0) 104#define MACHINE_HAS_TOPOLOGY (0)
103#define MACHINE_HAS_TE (0) 105#define MACHINE_HAS_TE (0)
@@ -110,6 +112,7 @@ extern unsigned int s390_user_mode;
110#define MACHINE_HAS_MVPG (1) 112#define MACHINE_HAS_MVPG (1)
111#define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS) 113#define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
112#define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1) 114#define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1)
115#define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2)
113#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) 116#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
114#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) 117#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
115#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) 118#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 4c91d078d091..1f0eee9e7daa 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -374,6 +374,8 @@ static __init void detect_machine_facilities(void)
374 S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT1; 374 S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT1;
375 __ctl_set_bit(0, 23); 375 __ctl_set_bit(0, 23);
376 } 376 }
377 if (test_facility(78))
378 S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2;
377 if (test_facility(3)) 379 if (test_facility(3))
378 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; 380 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
379 if (test_facility(27)) 381 if (test_facility(27))
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index afa9fdba200e..bfb48f18169c 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -768,6 +768,40 @@ static void __init reserve_crashkernel(void)
768#endif 768#endif
769} 769}
770 770
771static void __init init_storage_keys(unsigned long start, unsigned long end)
772{
773 unsigned long boundary, function, size;
774
775 while (start < end) {
776 if (MACHINE_HAS_EDAT2) {
777 /* set storage keys for a 2GB frame */
778 function = 0x22000 | PAGE_DEFAULT_KEY;
779 size = 1UL << 31;
780 boundary = (start + size) & ~(size - 1);
781 if (boundary <= end) {
782 do {
783 start = pfmf(function, start);
784 } while (start < boundary);
785 continue;
786 }
787 }
788 if (MACHINE_HAS_EDAT1) {
789 /* set storage keys for a 1MB frame */
790 function = 0x21000 | PAGE_DEFAULT_KEY;
791 size = 1UL << 20;
792 boundary = (start + size) & ~(size - 1);
793 if (boundary <= end) {
794 do {
795 start = pfmf(function, start);
796 } while (start < boundary);
797 continue;
798 }
799 }
800 page_set_storage_key(start, PAGE_DEFAULT_KEY, 0);
801 start += PAGE_SIZE;
802 }
803}
804
771static void __init setup_memory(void) 805static void __init setup_memory(void)
772{ 806{
773 unsigned long bootmap_size; 807 unsigned long bootmap_size;
@@ -846,9 +880,7 @@ static void __init setup_memory(void)
846 memblock_add_node(PFN_PHYS(start_chunk), 880 memblock_add_node(PFN_PHYS(start_chunk),
847 PFN_PHYS(end_chunk - start_chunk), 0); 881 PFN_PHYS(end_chunk - start_chunk), 0);
848 pfn = max(start_chunk, start_pfn); 882 pfn = max(start_chunk, start_pfn);
849 for (; pfn < end_chunk; pfn++) 883 init_storage_keys(PFN_PHYS(pfn), PFN_PHYS(end_chunk));
850 page_set_storage_key(PFN_PHYS(pfn),
851 PAGE_DEFAULT_KEY, 0);
852 } 884 }
853 885
854 psw_set_key(PAGE_DEFAULT_KEY); 886 psw_set_key(PAGE_DEFAULT_KEY);