Skip to content

Commit cd65d69

Browse files
bsingharorampe
authored andcommitted
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 <[email protected]> [mpe: Make the warning louder when we don't have MMU_FTR_KERNEL_RO] Signed-off-by: Michael Ellerman <[email protected]>
1 parent d924cc3 commit cd65d69

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

arch/powerpc/include/asm/book3s/64/hash.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ static inline int hash__pgd_bad(pgd_t pgd)
8989
{
9090
return (pgd_val(pgd) == 0);
9191
}
92+
#ifdef CONFIG_STRICT_KERNEL_RWX
93+
extern void hash__mark_rodata_ro(void);
94+
#endif
9295

9396
extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
9497
pte_t *ptep, unsigned long pte, int huge);

arch/powerpc/include/asm/book3s/64/radix.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@
116116
#define RADIX_PUD_TABLE_SIZE (sizeof(pud_t) << RADIX_PUD_INDEX_SIZE)
117117
#define RADIX_PGD_TABLE_SIZE (sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE)
118118

119+
#ifdef CONFIG_STRICT_KERNEL_RWX
120+
extern void radix__mark_rodata_ro(void);
121+
#endif
122+
119123
static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
120124
unsigned long set)
121125
{

arch/powerpc/mm/pgtable-hash64.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@
1111

1212
#include <linux/sched.h>
1313
#include <linux/mm_types.h>
14+
#include <linux/mm.h>
1415

1516
#include <asm/pgalloc.h>
17+
#include <asm/pgtable.h>
18+
#include <asm/sections.h>
19+
#include <asm/mmu.h>
1620
#include <asm/tlb.h>
1721

1822
#include "mmu_decl.h"
@@ -419,3 +423,35 @@ int hash__has_transparent_hugepage(void)
419423
return 1;
420424
}
421425
#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

arch/powerpc/mm/pgtable_64.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,16 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
491491
}
492492
EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry);
493493
#endif /* CONFIG_PPC_BOOK3S_64 */
494+
495+
#ifdef CONFIG_STRICT_KERNEL_RWX
496+
void mark_rodata_ro(void)
497+
{
498+
if (!mmu_has_feature(MMU_FTR_KERNEL_RO)) {
499+
pr_warn("Warning: Unable to mark rodata read only on this CPU.\n");
500+
return;
501+
}
502+
503+
if (!radix_enabled())
504+
hash__mark_rodata_ro();
505+
}
506+
#endif

0 commit comments

Comments
 (0)