pageattr.c (eadcbfa58ae8693f0d6a0f591d8f51d55cf068e1) pageattr.c (1aea9b3f921003f0880f0676ae85d87c9f1cb4a2)
1/*
2 * Copyright IBM Corp. 2011
3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
4 */
5#include <linux/hugetlb.h>
6#include <linux/mm.h>
7#include <asm/cacheflush.h>
8#include <asm/facility.h>

--- 215 unchanged lines hidden (view full) ---

224 new = pud_mkwrite(pud_mkdirty(new));
225 if (flags & SET_MEMORY_NX)
226 pud_val(new) |= _REGION_ENTRY_NOEXEC;
227 else if (flags & SET_MEMORY_X)
228 pud_val(new) &= ~_REGION_ENTRY_NOEXEC;
229 pgt_set((unsigned long *)pudp, pud_val(new), addr, CRDTE_DTT_REGION3);
230}
231
1/*
2 * Copyright IBM Corp. 2011
3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
4 */
5#include <linux/hugetlb.h>
6#include <linux/mm.h>
7#include <asm/cacheflush.h>
8#include <asm/facility.h>

--- 215 unchanged lines hidden (view full) ---

224 new = pud_mkwrite(pud_mkdirty(new));
225 if (flags & SET_MEMORY_NX)
226 pud_val(new) |= _REGION_ENTRY_NOEXEC;
227 else if (flags & SET_MEMORY_X)
228 pud_val(new) &= ~_REGION_ENTRY_NOEXEC;
229 pgt_set((unsigned long *)pudp, pud_val(new), addr, CRDTE_DTT_REGION3);
230}
231
232static int walk_pud_level(pgd_t *pgd, unsigned long addr, unsigned long end,
232static int walk_pud_level(p4d_t *p4d, unsigned long addr, unsigned long end,
233 unsigned long flags)
234{
235 unsigned long next;
236 pud_t *pudp;
237 int rc = 0;
238
233 unsigned long flags)
234{
235 unsigned long next;
236 pud_t *pudp;
237 int rc = 0;
238
239 pudp = pud_offset(pgd, addr);
239 pudp = pud_offset(p4d, addr);
240 do {
241 if (pud_none(*pudp))
242 return -EINVAL;
243 next = pud_addr_end(addr, end);
244 if (pud_large(*pudp)) {
245 if (addr & ~PUD_MASK || addr + PUD_SIZE > next) {
246 rc = split_pud_page(pudp, addr);
247 if (rc)

--- 6 unchanged lines hidden (view full) ---

254 }
255 pudp++;
256 addr = next;
257 cond_resched();
258 } while (addr < end && !rc);
259 return rc;
260}
261
240 do {
241 if (pud_none(*pudp))
242 return -EINVAL;
243 next = pud_addr_end(addr, end);
244 if (pud_large(*pudp)) {
245 if (addr & ~PUD_MASK || addr + PUD_SIZE > next) {
246 rc = split_pud_page(pudp, addr);
247 if (rc)

--- 6 unchanged lines hidden (view full) ---

254 }
255 pudp++;
256 addr = next;
257 cond_resched();
258 } while (addr < end && !rc);
259 return rc;
260}
261
262static int walk_p4d_level(pgd_t *pgd, unsigned long addr, unsigned long end,
263 unsigned long flags)
264{
265 unsigned long next;
266 p4d_t *p4dp;
267 int rc = 0;
268
269 p4dp = p4d_offset(pgd, addr);
270 do {
271 if (p4d_none(*p4dp))
272 return -EINVAL;
273 next = p4d_addr_end(addr, end);
274 rc = walk_pud_level(p4dp, addr, next, flags);
275 p4dp++;
276 addr = next;
277 cond_resched();
278 } while (addr < end && !rc);
279 return rc;
280}
281
262static DEFINE_MUTEX(cpa_mutex);
263
264static int change_page_attr(unsigned long addr, unsigned long end,
265 unsigned long flags)
266{
267 unsigned long next;
268 int rc = -EINVAL;
269 pgd_t *pgdp;
270
271 if (addr == end)
272 return 0;
273 if (end >= MODULES_END)
274 return -EINVAL;
275 mutex_lock(&cpa_mutex);
276 pgdp = pgd_offset_k(addr);
277 do {
278 if (pgd_none(*pgdp))
279 break;
280 next = pgd_addr_end(addr, end);
282static DEFINE_MUTEX(cpa_mutex);
283
284static int change_page_attr(unsigned long addr, unsigned long end,
285 unsigned long flags)
286{
287 unsigned long next;
288 int rc = -EINVAL;
289 pgd_t *pgdp;
290
291 if (addr == end)
292 return 0;
293 if (end >= MODULES_END)
294 return -EINVAL;
295 mutex_lock(&cpa_mutex);
296 pgdp = pgd_offset_k(addr);
297 do {
298 if (pgd_none(*pgdp))
299 break;
300 next = pgd_addr_end(addr, end);
281 rc = walk_pud_level(pgdp, addr, next, flags);
301 rc = walk_p4d_level(pgdp, addr, next, flags);
282 if (rc)
283 break;
284 cond_resched();
285 } while (pgdp++, addr = next, addr < end && !rc);
286 mutex_unlock(&cpa_mutex);
287 return rc;
288}
289

--- 24 unchanged lines hidden (view full) ---

314 }
315}
316
317void __kernel_map_pages(struct page *page, int numpages, int enable)
318{
319 unsigned long address;
320 int nr, i, j;
321 pgd_t *pgd;
302 if (rc)
303 break;
304 cond_resched();
305 } while (pgdp++, addr = next, addr < end && !rc);
306 mutex_unlock(&cpa_mutex);
307 return rc;
308}
309

--- 24 unchanged lines hidden (view full) ---

334 }
335}
336
337void __kernel_map_pages(struct page *page, int numpages, int enable)
338{
339 unsigned long address;
340 int nr, i, j;
341 pgd_t *pgd;
342 p4d_t *p4d;
322 pud_t *pud;
323 pmd_t *pmd;
324 pte_t *pte;
325
326 for (i = 0; i < numpages;) {
327 address = page_to_phys(page + i);
328 pgd = pgd_offset_k(address);
343 pud_t *pud;
344 pmd_t *pmd;
345 pte_t *pte;
346
347 for (i = 0; i < numpages;) {
348 address = page_to_phys(page + i);
349 pgd = pgd_offset_k(address);
329 pud = pud_offset(pgd, address);
350 p4d = p4d_offset(pgd, address);
351 pud = pud_offset(p4d, address);
330 pmd = pmd_offset(pud, address);
331 pte = pte_offset_kernel(pmd, address);
332 nr = (unsigned long)pte >> ilog2(sizeof(long));
333 nr = PTRS_PER_PTE - (nr & (PTRS_PER_PTE - 1));
334 nr = min(numpages - i, nr);
335 if (enable) {
336 for (j = 0; j < nr; j++) {
337 pte_val(*pte) &= ~_PAGE_INVALID;

--- 27 unchanged lines hidden ---
352 pmd = pmd_offset(pud, address);
353 pte = pte_offset_kernel(pmd, address);
354 nr = (unsigned long)pte >> ilog2(sizeof(long));
355 nr = PTRS_PER_PTE - (nr & (PTRS_PER_PTE - 1));
356 nr = min(numpages - i, nr);
357 if (enable) {
358 for (j = 0; j < nr; j++) {
359 pte_val(*pte) &= ~_PAGE_INVALID;

--- 27 unchanged lines hidden ---