All of lore.kernel.org
 help / color / mirror / Atom feed
From: Balbir Singh <bsingharora@gmail.com>
To: linuxppc-dev@lists.ozlabs.org, mpe@ellerman.id.au
Cc: naveen.n.rao@linux.vnet.ibm.com, christophe.leroy@c-s.fr,
	paulus@samba.org, Balbir Singh <bsingharora@gmail.com>
Subject: [PATCH v3 9/9] powerpc/mm/radix: Implement mark_rodata_ro() for radix
Date: Tue,  6 Jun 2017 14:29:45 +1000	[thread overview]
Message-ID: <20170606042945.24997-10-bsingharora@gmail.com> (raw)
In-Reply-To: <20170606042945.24997-1-bsingharora@gmail.com>

The patch splits the linear page mapping such that
the ones with kernel text are mapped as 2M and others
are mapped with the largest possible size - 1G. The downside
of this is that we split a 1G mapping into 512 2M mappings
for the kernel, but in the absence of that we cannot support
R/O areas in 1G, the kernel size is much smaller and using
1G as the granularity will waste a lot of space at the cost
of optimizing the TLB. The text itself should fit into about
6-8 mappings, so the effect should not be all that bad.

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
 arch/powerpc/mm/pgtable-radix.c | 68 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 8f42309..7c46dbc 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -11,6 +11,7 @@
 #include <linux/sched/mm.h>
 #include <linux/memblock.h>
 #include <linux/of_fdt.h>
+#include <linux/mm.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -19,9 +20,12 @@
 #include <asm/mmu.h>
 #include <asm/firmware.h>
 #include <asm/powernv.h>
+#include <asm/sections.h>
 
 #include <trace/events/thp.h>
 
+int mmu_radix_linear_psize = PAGE_SIZE;
+
 static int native_register_process_table(unsigned long base, unsigned long pg_sz,
 					 unsigned long table_size)
 {
@@ -111,7 +115,52 @@ int radix__map_kernel_page(unsigned long ea, unsigned long pa,
 #ifdef CONFIG_STRICT_KERNEL_RWX
 void radix__mark_rodata_ro(void)
 {
-	pr_warn("Not yet implemented for radix\n");
+	unsigned long start = (unsigned long)_stext;
+	unsigned long end = (unsigned long)__init_begin;
+	unsigned long idx;
+	unsigned int step, shift;
+	pgd_t *pgdp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	if (!mmu_has_feature(MMU_FTR_KERNEL_RO)) {
+		pr_info("R/O rodata not supported\n");
+		return;
+	}
+
+	shift = mmu_psize_defs[mmu_radix_linear_psize].shift;
+	step = 1 << shift;
+
+	start = ((start + step - 1) >> shift) << shift;
+	end = (end >> shift) << shift;
+
+	pr_devel("marking ro start %lx, end %lx, step %x\n",
+			start, end, step);
+
+	for (idx = start; idx < end; idx += step) {
+		pgdp = pgd_offset_k(idx);
+		pudp = pud_alloc(&init_mm, pgdp, idx);
+		if (!pudp)
+			continue;
+		if (pud_huge(*pudp)) {
+			ptep = (pte_t *)pudp;
+			goto update_the_pte;
+		}
+		pmdp = pmd_alloc(&init_mm, pudp, idx);
+		if (!pmdp)
+			continue;
+		if (pmd_huge(*pmdp)) {
+			ptep = pmdp_ptep(pmdp);
+			goto update_the_pte;
+		}
+		ptep = pte_alloc_kernel(pmdp, idx);
+		if (!ptep)
+			continue;
+update_the_pte:
+		pte_update(&init_mm, idx, ptep, _PAGE_WRITE, 0, 0);
+	}
+
 }
 #endif
 
@@ -129,6 +178,7 @@ static int __meminit create_physical_mapping(unsigned long start,
 					     unsigned long end)
 {
 	unsigned long addr, mapping_size = 0;
+	unsigned long max_mapping_size;
 
 	start = _ALIGN_UP(start, PAGE_SIZE);
 	for (addr = start; addr < end; addr += mapping_size) {
@@ -137,9 +187,12 @@ static int __meminit create_physical_mapping(unsigned long start,
 
 		gap = end - addr;
 		previous_size = mapping_size;
+		max_mapping_size = PUD_SIZE;
 
+retry:
 		if (IS_ALIGNED(addr, PUD_SIZE) && gap >= PUD_SIZE &&
-		    mmu_psize_defs[MMU_PAGE_1G].shift)
+		    mmu_psize_defs[MMU_PAGE_1G].shift &&
+		    PUD_SIZE <= max_mapping_size)
 			mapping_size = PUD_SIZE;
 		else if (IS_ALIGNED(addr, PMD_SIZE) && gap >= PMD_SIZE &&
 			 mmu_psize_defs[MMU_PAGE_2M].shift)
@@ -147,6 +200,17 @@ static int __meminit create_physical_mapping(unsigned long start,
 		else
 			mapping_size = PAGE_SIZE;
 
+		if (mapping_size == PUD_SIZE &&
+			addr <= __pa_symbol(__init_begin) &&
+			(addr + mapping_size) >= __pa_symbol(_stext)) {
+			max_mapping_size = PMD_SIZE;
+			goto retry;
+		}
+
+		if (addr <= __pa_symbol(__init_begin) &&
+			(addr + mapping_size) >= __pa_symbol(_stext))
+			mmu_radix_linear_psize = mapping_size;
+
 		if (mapping_size != previous_size) {
 			print_mapping(start, addr, previous_size);
 			start = addr;
-- 
2.9.4

      parent reply	other threads:[~2017-06-06  4:30 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-06  4:29 [PATCH v3 0/9] Enable STRICT_KERNEL_RWX Balbir Singh
2017-06-06  4:29 ` [PATCH v3 1/9] powerpc/lib/code-patching: Enhance code patching Balbir Singh
2017-06-26  5:42   ` Michael Ellerman
2017-06-06  4:29 ` [PATCH v3 2/9] powerpc/kprobes: Move kprobes over to patch_instruction Balbir Singh
2017-06-06 19:05   ` Naveen N. Rao
2017-06-07  5:47     ` Balbir Singh
2017-06-26  5:00       ` Michael Ellerman
2017-06-06  4:29 ` [PATCH v3 3/9] powerpc/kprobes/optprobes: Move " Balbir Singh
2017-06-06 19:12   ` Naveen N. Rao
2017-06-07  5:46     ` Balbir Singh
2017-06-07 14:12       ` Naveen N. Rao
2017-06-26  6:12   ` Michael Ellerman
2017-06-06  4:29 ` [PATCH v3 4/9] powerpc/xmon: Add patch_instruction supporf for xmon Balbir Singh
2017-06-06  4:29 ` [PATCH v3 5/9] powerpc/vmlinux.lds: Align __init_begin to 16M Balbir Singh
2017-06-06  4:29 ` [PATCH v3 6/9] powerpc/platform/pseries/lpar: Fix updatepp and updateboltedpp Balbir Singh
2017-06-06  4:29 ` [PATCH v3 7/9] powerpc/mm/hash: Implement mark_rodata_ro() for hash Balbir Singh
2017-06-06  4:29 ` [PATCH v3 8/9] powerpc/Kconfig: Enable STRICT_KERNEL_RWX Balbir Singh
2017-06-06  4:29 ` Balbir Singh [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170606042945.24997-10-bsingharora@gmail.com \
    --to=bsingharora@gmail.com \
    --cc=christophe.leroy@c-s.fr \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=naveen.n.rao@linux.vnet.ibm.com \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.