aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/pgtable-hash64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/pgtable-hash64.c')
-rw-r--r--arch/powerpc/mm/pgtable-hash64.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c
index 188b4107584d..443a2c66a304 100644
--- a/arch/powerpc/mm/pgtable-hash64.c
+++ b/arch/powerpc/mm/pgtable-hash64.c
@@ -425,33 +425,51 @@ int hash__has_transparent_hugepage(void)
425#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 425#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
426 426
427#ifdef CONFIG_STRICT_KERNEL_RWX 427#ifdef CONFIG_STRICT_KERNEL_RWX
428void hash__mark_rodata_ro(void) 428static bool hash__change_memory_range(unsigned long start, unsigned long end,
429 unsigned long newpp)
429{ 430{
430 unsigned long start = (unsigned long)_stext;
431 unsigned long end = (unsigned long)__init_begin;
432 unsigned long idx; 431 unsigned long idx;
433 unsigned int step, shift; 432 unsigned int step, shift;
434 unsigned long newpp = PP_RXXX;
435 433
436 shift = mmu_psize_defs[mmu_linear_psize].shift; 434 shift = mmu_psize_defs[mmu_linear_psize].shift;
437 step = 1 << shift; 435 step = 1 << shift;
438 436
439 start = ((start + step - 1) >> shift) << shift; 437 start = ALIGN_DOWN(start, step);
440 end = (end >> shift) << shift; 438 end = ALIGN(end, step); // aligns up
441 439
442 pr_devel("marking ro start %lx, end %lx, step %x\n", 440 if (start >= end)
443 start, end, step); 441 return false;
444 442
445 if (start == end) { 443 pr_debug("Changing page protection on range 0x%lx-0x%lx, to 0x%lx, step 0x%x\n",
446 pr_warn("could not set rodata ro, relocate the start" 444 start, end, newpp, step);
447 " of the kernel to a 0x%x boundary\n", step);
448 return;
449 }
450 445
451 for (idx = start; idx < end; idx += step) 446 for (idx = start; idx < end; idx += step)
452 /* Not sure if we can do much with the return value */ 447 /* Not sure if we can do much with the return value */
453 mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize, 448 mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize,
454 mmu_kernel_ssize); 449 mmu_kernel_ssize);
455 450
451 return true;
452}
453
454void hash__mark_rodata_ro(void)
455{
456 unsigned long start, end;
457
458 start = (unsigned long)_stext;
459 end = (unsigned long)__init_begin;
460
461 WARN_ON(!hash__change_memory_range(start, end, PP_RXXX));
462}
463
464void hash__mark_initmem_nx(void)
465{
466 unsigned long start, end, pp;
467
468 start = (unsigned long)__init_begin;
469 end = (unsigned long)__init_end;
470
471 pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL));
472
473 WARN_ON(!hash__change_memory_range(start, end, pp));
456} 474}
457#endif 475#endif