aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2012-09-27 04:45:06 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-10-09 08:16:55 -0400
commit85e9d0e5ffabfede5facbac5b0d9b90768bc6e90 (patch)
treeb158c8bde347cd8cabd24265dfe65884a08db701 /arch/s390
parent3c7ef08bba65d1fef0b7486b30b5bbcdb42c5d9c (diff)
s390/mm: use pfmf instruction to initialize storage keys
Make use of the pfmf instruction, if available, to initialize storage keys of whole 1MB or 2GB frames instead of initializing every single page with the sske instruction. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
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);