diff options
author | Balbir Singh <bsingharora@gmail.com> | 2017-06-28 13:04:08 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-07-03 21:35:16 -0400 |
commit | cd65d69713349fc7b33fa9de2b32989b99c9fb39 (patch) | |
tree | 31d67b092228886108a0339c6953064c01b2a3b0 /arch/powerpc/mm/pgtable-hash64.c | |
parent | d924cc3feda9c2bea8164930899f367ce249cbbf (diff) |
powerpc/mm/hash: Implement mark_rodata_ro() for hash
With hash we update the bolted pte to mark it read-only. We rely
on the MMU_FTR_KERNEL_RO to generate the correct permissions
for read-only text. The radix implementation just prints a warning
in this implementation
Signed-off-by: Balbir Singh <bsingharora@gmail.com>
[mpe: Make the warning louder when we don't have MMU_FTR_KERNEL_RO]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/mm/pgtable-hash64.c')
-rw-r--r-- | arch/powerpc/mm/pgtable-hash64.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c index a0facee58811..188b4107584d 100644 --- a/arch/powerpc/mm/pgtable-hash64.c +++ b/arch/powerpc/mm/pgtable-hash64.c | |||
@@ -11,8 +11,12 @@ | |||
11 | 11 | ||
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/mm_types.h> | 13 | #include <linux/mm_types.h> |
14 | #include <linux/mm.h> | ||
14 | 15 | ||
15 | #include <asm/pgalloc.h> | 16 | #include <asm/pgalloc.h> |
17 | #include <asm/pgtable.h> | ||
18 | #include <asm/sections.h> | ||
19 | #include <asm/mmu.h> | ||
16 | #include <asm/tlb.h> | 20 | #include <asm/tlb.h> |
17 | 21 | ||
18 | #include "mmu_decl.h" | 22 | #include "mmu_decl.h" |
@@ -419,3 +423,35 @@ int hash__has_transparent_hugepage(void) | |||
419 | return 1; | 423 | return 1; |
420 | } | 424 | } |
421 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 425 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
426 | |||
427 | #ifdef CONFIG_STRICT_KERNEL_RWX | ||
428 | void hash__mark_rodata_ro(void) | ||
429 | { | ||
430 | unsigned long start = (unsigned long)_stext; | ||
431 | unsigned long end = (unsigned long)__init_begin; | ||
432 | unsigned long idx; | ||
433 | unsigned int step, shift; | ||
434 | unsigned long newpp = PP_RXXX; | ||
435 | |||
436 | shift = mmu_psize_defs[mmu_linear_psize].shift; | ||
437 | step = 1 << shift; | ||
438 | |||
439 | start = ((start + step - 1) >> shift) << shift; | ||
440 | end = (end >> shift) << shift; | ||
441 | |||
442 | pr_devel("marking ro start %lx, end %lx, step %x\n", | ||
443 | start, end, step); | ||
444 | |||
445 | if (start == end) { | ||
446 | pr_warn("could not set rodata ro, relocate the start" | ||
447 | " of the kernel to a 0x%x boundary\n", step); | ||
448 | return; | ||
449 | } | ||
450 | |||
451 | for (idx = start; idx < end; idx += step) | ||
452 | /* Not sure if we can do much with the return value */ | ||
453 | mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize, | ||
454 | mmu_kernel_ssize); | ||
455 | |||
456 | } | ||
457 | #endif | ||