aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-10-25 10:10:14 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:15 -0400
commite2b8d7af0e3a9234de06606f9151f28cf847a8d6 (patch)
tree64bc03271383a43c2097b84b6f0e25c34ed13553 /arch
parent92f842eac7ee321c8a0749aba2513541b4ac226f (diff)
[S390] add support for nonquiescing sske
Improve performance of the sske operation by using the nonquiescing variant if the affected page has no mappings established. On machines with no support for the new sske variant the mask bit will be ignored. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/page.h8
-rw-r--r--arch/s390/include/asm/pgtable.h8
-rw-r--r--arch/s390/kernel/early.c3
-rw-r--r--arch/s390/kernel/setup.c3
4 files changed, 14 insertions, 8 deletions
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index af650fb47206..a8729ea7e9ac 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -108,9 +108,13 @@ typedef pte_t *pgtable_t;
108#define __pgprot(x) ((pgprot_t) { (x) } ) 108#define __pgprot(x) ((pgprot_t) { (x) } )
109 109
110static inline void 110static inline void
111page_set_storage_key(unsigned long addr, unsigned int skey) 111page_set_storage_key(unsigned long addr, unsigned int skey, int mapped)
112{ 112{
113 asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); 113 if (!mapped)
114 asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
115 : : "d" (skey), "a" (addr));
116 else
117 asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
114} 118}
115 119
116static inline unsigned int 120static inline unsigned int
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 85cd4b039de6..f79e7bb9ae1e 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -590,7 +590,7 @@ static inline void rcp_unlock(pte_t *ptep)
590} 590}
591 591
592/* forward declaration for SetPageUptodate in page-flags.h*/ 592/* forward declaration for SetPageUptodate in page-flags.h*/
593static inline void page_clear_dirty(struct page *page); 593static inline void page_clear_dirty(struct page *page, int mapped);
594#include <linux/page-flags.h> 594#include <linux/page-flags.h>
595 595
596static inline void ptep_rcp_copy(pte_t *ptep) 596static inline void ptep_rcp_copy(pte_t *ptep)
@@ -800,7 +800,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm,
800 } 800 }
801 dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); 801 dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste);
802 if (skey & _PAGE_CHANGED) 802 if (skey & _PAGE_CHANGED)
803 page_clear_dirty(page); 803 page_clear_dirty(page, 1);
804 rcp_unlock(ptep); 804 rcp_unlock(ptep);
805 return dirty; 805 return dirty;
806} 806}
@@ -975,9 +975,9 @@ static inline int page_test_dirty(struct page *page)
975} 975}
976 976
977#define __HAVE_ARCH_PAGE_CLEAR_DIRTY 977#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
978static inline void page_clear_dirty(struct page *page) 978static inline void page_clear_dirty(struct page *page, int mapped)
979{ 979{
980 page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY); 980 page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped);
981} 981}
982 982
983/* 983/*
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c00856ad4e5a..0badc6344eb4 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -208,7 +208,8 @@ static noinline __init void init_kernel_storage_key(void)
208 end_pfn = PFN_UP(__pa(&_end)); 208 end_pfn = PFN_UP(__pa(&_end));
209 209
210 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) 210 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
211 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); 211 page_set_storage_key(init_pfn << PAGE_SHIFT,
212 PAGE_DEFAULT_KEY, 0);
212} 213}
213 214
214static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); 215static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c8e8e1354e1d..9071e984dcf1 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -627,7 +627,8 @@ setup_memory(void)
627 add_active_range(0, start_chunk, end_chunk); 627 add_active_range(0, start_chunk, end_chunk);
628 pfn = max(start_chunk, start_pfn); 628 pfn = max(start_chunk, start_pfn);
629 for (; pfn < end_chunk; pfn++) 629 for (; pfn < end_chunk; pfn++)
630 page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); 630 page_set_storage_key(PFN_PHYS(pfn),
631 PAGE_DEFAULT_KEY, 0);
631 } 632 }
632 633
633 psw_set_key(PAGE_DEFAULT_KEY); 634 psw_set_key(PAGE_DEFAULT_KEY);