riscv: pgtable: Add custom protection_map init

A patch from »svpbmt and t-head memory types« in state Mainline for linux-kernel

From: Heiko Stuebner <heiko@...> Date: Sun, 6 Jun 2021 09:04:03 +0000

Commit-Message

Some RISC-V CPU vendors have defined their own PTE attributes to solve non-coherent DMA bus problems. That makes _P/SXXX definitions contain global variables which could be initialized at the early boot stage before setup_vm. This patch is similar to 316d097c4cd4 (x86/pti: Filter at vma->vm_page_prot population) which give a choice for arch custom implementation. Signed-off-by: Heiko Stuebner <heiko@...>

Patch-Comment

arch/riscv/Kconfig | 4 ++++ arch/riscv/mm/init.c | 22 ++++++++++++++++++++++ mm/mmap.c | 4 ++++ 3 files changed, 30 insertions(+)

Statistics

  • 30 lines added
  • 0 lines removed

Changes

------------------------------ arch/riscv/Kconfig ------------------------------
index 821252b65f89..07543b9add8e 100644
@@ -23,6 +23,7 @@ config RISCV
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
select ARCH_HAS_MMIOWB
+ select ARCH_HAS_PROTECTION_MAP_INIT
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SET_DIRECT_MAP if MMU
select ARCH_HAS_SET_MEMORY if MMU
@@ -210,6 +211,9 @@ config GENERIC_HWEIGHT
config FIX_EARLYCON_MEM
def_bool MMU
+config ARCH_HAS_PROTECTION_MAP_INIT
+ def_bool y
+
config PGTABLE_LEVELS
int
default 3 if 64BIT
----------------------------- arch/riscv/mm/init.c -----------------------------
index 24b2b8044602..60a1b26a956c 100644
@@ -588,6 +588,26 @@ static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa)
dtb_early_pa = dtb_pa;
}
+static void __init setup_protection_map(void)
+{
+ protection_map[0] = __P000;
+ protection_map[1] = __P001;
+ protection_map[2] = __P010;
+ protection_map[3] = __P011;
+ protection_map[4] = __P100;
+ protection_map[5] = __P101;
+ protection_map[6] = __P110;
+ protection_map[7] = __P111;
+ protection_map[8] = __S000;
+ protection_map[9] = __S001;
+ protection_map[10] = __S010;
+ protection_map[11] = __S011;
+ protection_map[12] = __S100;
+ protection_map[13] = __S101;
+ protection_map[14] = __S110;
+ protection_map[15] = __S111;
+}
+
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
{
pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd;
@@ -624,6 +644,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
BUG_ON((kernel_map.virt_addr + kernel_map.size) > ADDRESS_SPACE_END - SZ_4K);
#endif
+ setup_protection_map();
+
pt_ops.alloc_pte = alloc_pte_early;
pt_ops.get_pte_virt = get_pte_virt_early;
#ifndef __PAGETABLE_PMD_FOLDED
---------------------------------- mm/mmap.c -----------------------------------
index bfb0ea164a90..33f4a5936ac9 100644
@@ -100,10 +100,14 @@ static void unmap_region(struct mm_struct *mm,
* w: (no) no
* x: (yes) yes
*/
+#ifdef CONFIG_ARCH_HAS_PROTECTION_MAP_INIT
+pgprot_t protection_map[16] __ro_after_init;
+#else
pgprot_t protection_map[16] __ro_after_init = {
__P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
};
+#endif
#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...