aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include/asm/page.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/include/asm/page.h')
-rw-r--r--arch/s390/include/asm/page.h56
1 files changed, 50 insertions, 6 deletions
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 3c987e9ec8d..81ee2776088 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -107,8 +107,8 @@ typedef pte_t *pgtable_t;
107#define __pgd(x) ((pgd_t) { (x) } ) 107#define __pgd(x) ((pgd_t) { (x) } )
108#define __pgprot(x) ((pgprot_t) { (x) } ) 108#define __pgprot(x) ((pgprot_t) { (x) } )
109 109
110static inline void 110static inline void page_set_storage_key(unsigned long addr,
111page_set_storage_key(unsigned long addr, unsigned int skey, int mapped) 111 unsigned char skey, int mapped)
112{ 112{
113 if (!mapped) 113 if (!mapped)
114 asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0" 114 asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
@@ -117,15 +117,59 @@ page_set_storage_key(unsigned long addr, unsigned int skey, int mapped)
117 asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); 117 asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
118} 118}
119 119
120static inline unsigned int 120static inline unsigned char page_get_storage_key(unsigned long addr)
121page_get_storage_key(unsigned long addr)
122{ 121{
123 unsigned int skey; 122 unsigned char skey;
124 123
125 asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0)); 124 asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr));
126 return skey; 125 return skey;
127} 126}
128 127
128static inline int page_reset_referenced(unsigned long addr)
129{
130 unsigned int ipm;
131
132 asm volatile(
133 " rrbe 0,%1\n"
134 " ipm %0\n"
135 : "=d" (ipm) : "a" (addr) : "cc");
136 return !!(ipm & 0x20000000);
137}
138
139/* Bits int the storage key */
140#define _PAGE_CHANGED 0x02 /* HW changed bit */
141#define _PAGE_REFERENCED 0x04 /* HW referenced bit */
142#define _PAGE_FP_BIT 0x08 /* HW fetch protection bit */
143#define _PAGE_ACC_BITS 0xf0 /* HW access control bits */
144
145/*
146 * Test and clear dirty bit in storage key.
147 * We can't clear the changed bit atomically. This is a potential
148 * race against modification of the referenced bit. This function
149 * should therefore only be called if it is not mapped in any
150 * address space.
151 */
152#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
153static inline int page_test_and_clear_dirty(unsigned long pfn, int mapped)
154{
155 unsigned char skey;
156
157 skey = page_get_storage_key(pfn << PAGE_SHIFT);
158 if (!(skey & _PAGE_CHANGED))
159 return 0;
160 page_set_storage_key(pfn << PAGE_SHIFT, skey & ~_PAGE_CHANGED, mapped);
161 return 1;
162}
163
164/*
165 * Test and clear referenced bit in storage key.
166 */
167#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
168static inline int page_test_and_clear_young(unsigned long pfn)
169{
170 return page_reset_referenced(pfn << PAGE_SHIFT);
171}
172
129struct page; 173struct page;
130void arch_free_page(struct page *page, int order); 174void arch_free_page(struct page *page, int order);
131void arch_alloc_page(struct page *page, int order); 175void arch_alloc_page(struct page *page, int order);