For armv8 we are adding proper page permissions for the relocated U-Boot binary. Add a weak function that can be used across architectures to change the page permissions
Tested-by: Neil Armstrong <neil.armstr...@linaro.org> # on AML-S905X-CC Signed-off-by: Ilias Apalodimas <ilias.apalodi...@linaro.org> --- arch/arc/lib/cache.c | 6 ++++++ arch/arm/cpu/arm926ejs/cache.c | 6 ++++++ arch/arm/cpu/armv7/cache_v7.c | 6 ++++++ arch/arm/cpu/armv7m/cache.c | 6 ++++++ arch/arm/cpu/armv8/cache_v8.c | 25 +++++++++++++++++++++++++ arch/arm/lib/cache.c | 6 ++++++ arch/m68k/lib/cache.c | 6 ++++++ arch/nios2/lib/cache.c | 6 ++++++ arch/powerpc/lib/cache.c | 6 ++++++ arch/riscv/lib/cache.c | 6 ++++++ arch/sh/cpu/sh4/cache.c | 6 ++++++ arch/xtensa/lib/cache.c | 6 ++++++ include/cpu_func.h | 17 +++++++++++++++++ 13 files changed, 108 insertions(+) diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 5169fc627fa5..2f8b14f77b55 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -8,6 +8,7 @@ #include <asm/global_data.h> #include <linux/bitops.h> #include <linux/compiler.h> +#include <linux/errno.h> #include <linux/kernel.h> #include <linux/log2.h> #include <asm/arcregs.h> @@ -819,3 +820,8 @@ void sync_n_cleanup_cache_all(void) __ic_entire_invalidate(); } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/arm/cpu/arm926ejs/cache.c b/arch/arm/cpu/arm926ejs/cache.c index 5b87a3af91b2..6051fd47c449 100644 --- a/arch/arm/cpu/arm926ejs/cache.c +++ b/arch/arm/cpu/arm926ejs/cache.c @@ -5,6 +5,7 @@ */ #include <cpu_func.h> #include <asm/cache.h> +#include <linux/errno.h> #include <linux/types.h> #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) @@ -88,3 +89,8 @@ void enable_caches(void) dcache_enable(); #endif } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index d11420d2fdd0..937b32a7f136 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -6,6 +6,7 @@ */ #include <cpu_func.h> #include <asm/cache.h> +#include <linux/errno.h> #include <linux/types.h> #include <asm/armv7.h> #include <asm/utils.h> @@ -209,3 +210,8 @@ __weak void v7_outer_cache_flush_all(void) {} __weak void v7_outer_cache_inval_all(void) {} __weak void v7_outer_cache_flush_range(u32 start, u32 end) {} __weak void v7_outer_cache_inval_range(u32 start, u32 end) {} + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/arm/cpu/armv7m/cache.c b/arch/arm/cpu/armv7m/cache.c index b6d08b7aad73..b16a9c8f723b 100644 --- a/arch/arm/cpu/armv7m/cache.c +++ b/arch/arm/cpu/armv7m/cache.c @@ -11,6 +11,7 @@ #include <asm/cache.h> #include <asm/io.h> #include <linux/bitops.h> +#include <linux/errno.h> /* Cache maintenance operation registers */ @@ -370,3 +371,8 @@ void enable_caches(void) dcache_enable(); #endif } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 670379e17b7a..b6ea7efc7b75 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -14,6 +14,7 @@ #include <asm/global_data.h> #include <asm/system.h> #include <asm/armv8/mmu.h> +#include <linux/errno.h> DECLARE_GLOBAL_DATA_PTR; @@ -1028,6 +1029,30 @@ skip_break: __asm_invalidate_tlb_all(); } +int pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + u64 attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE | PTE_TYPE_VALID; + + switch (perm) { + case MMU_ATTR_RO: + attrs |= PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_RO; + break; + case MMU_ATTR_RX: + attrs |= PTE_BLOCK_RO; + break; + case MMU_ATTR_RW: + attrs |= PTE_BLOCK_PXN | PTE_BLOCK_UXN; + break; + default: + log_err("Unknown attribute %llx\n", perm); + return -EINVAL; + } + + mmu_change_region_attr(addr, size, attrs, false); + + return 0; +} + #else /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */ /* diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 516754caeaf9..d4f1528b453d 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -10,6 +10,7 @@ #include <malloc.h> #include <asm/cache.h> #include <asm/global_data.h> +#include <linux/errno.h> DECLARE_GLOBAL_DATA_PTR; @@ -170,3 +171,8 @@ __weak int arm_reserve_mmu(void) return 0; } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/m68k/lib/cache.c b/arch/m68k/lib/cache.c index 370ad40f1423..fce852db2988 100644 --- a/arch/m68k/lib/cache.c +++ b/arch/m68k/lib/cache.c @@ -8,6 +8,7 @@ #include <cpu_func.h> #include <asm/immap.h> #include <asm/cache.h> +#include <linux/errno.h> volatile int *cf_icache_status = (int *)ICACHE_STATUS; volatile int *cf_dcache_status = (int *)DCACHE_STATUS; @@ -151,3 +152,8 @@ __weak void flush_dcache_range(unsigned long start, unsigned long stop) { /* An empty stub, real implementation should be in platform code */ } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/nios2/lib/cache.c b/arch/nios2/lib/cache.c index 8f543f2a2f26..70f258a1760b 100644 --- a/arch/nios2/lib/cache.c +++ b/arch/nios2/lib/cache.c @@ -8,6 +8,7 @@ #include <cpu_func.h> #include <asm/cache.h> #include <asm/global_data.h> +#include <linux/errno.h> DECLARE_GLOBAL_DATA_PTR; @@ -127,3 +128,8 @@ void dcache_disable(void) { flush_dcache_all(); } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/powerpc/lib/cache.c b/arch/powerpc/lib/cache.c index a9cd7b8d30ac..b434fbc4b4a5 100644 --- a/arch/powerpc/lib/cache.c +++ b/arch/powerpc/lib/cache.c @@ -8,6 +8,7 @@ #include <stdio.h> #include <asm/cache.h> #include <watchdog.h> +#include <linux/errno.h> static ulong maybe_watchdog_reset(ulong flushed) { @@ -58,3 +59,8 @@ void invalidate_icache_all(void) { puts("No arch specific invalidate_icache_all available!\n"); } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c index 71e4937ab542..d3ec9d460259 100644 --- a/arch/riscv/lib/cache.c +++ b/arch/riscv/lib/cache.c @@ -8,6 +8,7 @@ #include <dm.h> #include <asm/insn-def.h> #include <linux/const.h> +#include <linux/errno.h> #define CBO_INVAL(base) \ INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \ @@ -151,3 +152,8 @@ __weak void enable_caches(void) if (!zicbom_block_size) log_debug("Zicbom not initialized.\n"); } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/sh/cpu/sh4/cache.c b/arch/sh/cpu/sh4/cache.c index 99acc5999652..4e6751bfd2f5 100644 --- a/arch/sh/cpu/sh4/cache.c +++ b/arch/sh/cpu/sh4/cache.c @@ -11,6 +11,7 @@ #include <asm/io.h> #include <asm/processor.h> #include <asm/system.h> +#include <linux/errno.h> #define CACHE_VALID 1 #define CACHE_UPDATED 2 @@ -126,3 +127,8 @@ int dcache_status(void) { return 0; } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/arch/xtensa/lib/cache.c b/arch/xtensa/lib/cache.c index e6a7f6827fc2..17e1e21f28b9 100644 --- a/arch/xtensa/lib/cache.c +++ b/arch/xtensa/lib/cache.c @@ -6,6 +6,7 @@ #include <cpu_func.h> #include <asm/cache.h> +#include <linux/errno.h> /* * We currently run always with caches enabled when running from memory. @@ -57,3 +58,8 @@ void invalidate_icache_all(void) { __invalidate_icache_all(); } + +int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm) +{ + return -ENOSYS; +} diff --git a/include/cpu_func.h b/include/cpu_func.h index 7e81c4364a73..ed21bf71293f 100644 --- a/include/cpu_func.h +++ b/include/cpu_func.h @@ -69,6 +69,23 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); + +enum pgprot_attrs { + MMU_ATTR_RO, + MMU_ATTR_RX, + MMU_ATTR_RW, +}; + +/** pgprot_set_attrs() - Set page table permissions + * + * @addr: Physical address start + * @size: size of memory to change + * @perm: New permissions + * + * Return: 0 on success, error otherwise. + **/ +int pgprot_set_attrs(phys_addr_t addr, size_t size, u64 perm); + /** * noncached_init() - Initialize non-cached memory region * -- 2.47.2