diff options
Diffstat (limited to 'arch/s390/mm/pageattr.c')
-rw-r--r-- | arch/s390/mm/pageattr.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 73c3da393e88..29ccee3651f4 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c | |||
@@ -105,3 +105,46 @@ int set_memory_x(unsigned long addr, int numpages) | |||
105 | { | 105 | { |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | |||
109 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
110 | void kernel_map_pages(struct page *page, int numpages, int enable) | ||
111 | { | ||
112 | unsigned long address; | ||
113 | pgd_t *pgd; | ||
114 | pud_t *pud; | ||
115 | pmd_t *pmd; | ||
116 | pte_t *pte; | ||
117 | int i; | ||
118 | |||
119 | for (i = 0; i < numpages; i++) { | ||
120 | address = page_to_phys(page + i); | ||
121 | pgd = pgd_offset_k(address); | ||
122 | pud = pud_offset(pgd, address); | ||
123 | pmd = pmd_offset(pud, address); | ||
124 | pte = pte_offset_kernel(pmd, address); | ||
125 | if (!enable) { | ||
126 | __ptep_ipte(address, pte); | ||
127 | pte_val(*pte) = _PAGE_TYPE_EMPTY; | ||
128 | continue; | ||
129 | } | ||
130 | *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW)); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_HIBERNATION | ||
135 | bool kernel_page_present(struct page *page) | ||
136 | { | ||
137 | unsigned long addr; | ||
138 | int cc; | ||
139 | |||
140 | addr = page_to_phys(page); | ||
141 | asm volatile( | ||
142 | " lra %1,0(%1)\n" | ||
143 | " ipm %0\n" | ||
144 | " srl %0,28" | ||
145 | : "=d" (cc), "+a" (addr) : : "cc"); | ||
146 | return cc == 0; | ||
147 | } | ||
148 | #endif /* CONFIG_HIBERNATION */ | ||
149 | |||
150 | #endif /* CONFIG_DEBUG_PAGEALLOC */ | ||