]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
treewide: Add a function to change page permissions
authorIlias Apalodimas <ilias.apalodimas@linaro.org>
Thu, 20 Feb 2025 13:54:42 +0000 (15:54 +0200)
committerIlias Apalodimas <ilias.apalodimas@linaro.org>
Fri, 14 Mar 2025 11:37:54 +0000 (13:37 +0200)
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.armstrong@linaro.org> # on AML-S905X-CC
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
13 files changed:
arch/arc/lib/cache.c
arch/arm/cpu/arm926ejs/cache.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7m/cache.c
arch/arm/cpu/armv8/cache_v8.c
arch/arm/lib/cache.c
arch/m68k/lib/cache.c
arch/nios2/lib/cache.c
arch/powerpc/lib/cache.c
arch/riscv/lib/cache.c
arch/sh/cpu/sh4/cache.c
arch/xtensa/lib/cache.c
include/cpu_func.h

index 5169fc627fa5f49c8ae4b8e9ddf62a631dd9b442..08f9e7dceac00a5f473451a4144d1fb5b2217acd 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index 5b87a3af91b22a19cd607a51dea1eef27d20bae6..71b8ad0f71d8a8169c3b28124a71fe1be1c81777 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index d11420d2fdd02a4934340523148d4c5a93c45e95..371dc92cd46cdbeb21468096527501764a987976 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index b6d08b7aad737c93958aaf4534f6868ba7f57dbb..8e7db7340557802f7bc81238299d331546dc23dc 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index c9948e99e2ea85fd113ee766893709e37b31d84c..12ae9bd06039347eebad050f4532d7bac1cf0fbb 100644 (file)
@@ -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;
 
@@ -1032,6 +1033,30 @@ void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
        mmu_change_region_attr_nobreak(addr, siz, attrs);
 }
 
+int pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs 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 %d\n", perm);
+               return -EINVAL;
+       }
+
+       mmu_change_region_attr_nobreak(addr, size, attrs);
+
+       return 0;
+}
+
 #else  /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
 
 /*
index 516754caeaf919e4ba87711da4639d1832c56f31..dd19bd3e4fb33086d5447b09652f106fa5d2a219 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index 370ad40f1423d08300b5c1bd7d44d67c4c662162..a21fe3279440b1a9251a91801f61d66f52b734a7 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index 8f543f2a2f2664f227b5ba9ed99e0ff87af423c1..d7fd9ca8bd4afedb4c2af139c84e423d5f076d80 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index a9cd7b8d30acb2886367d7b2bf546f809900c62f..e4d9546039d825284dfaee7152c9d10cab91a5ff 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index 71e4937ab54268560bda6f700296253dfb1546a7..31aa30bc7d723ade3b337d8bc5a13ada89fe1da4 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index 99acc599965241f8977f1d8cbf9d69702a17c6b4..56161ee72e4bcd19d2f2b8e1de9ea04263f9a2b3 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index e6a7f6827fc2541fa6756f90191203e427ba1d94..1229b407783504024c658d51e1384c1392b75db9 100644 (file)
@@ -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, enum pgprot_attrs perm)
+{
+       return -ENOSYS;
+}
index 7e81c4364a73ca7b533c4b075407232b40e4eb5c..70a41ead3f73608ab2f694ef91e99f01e0b97b77 100644 (file)
@@ -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, enum pgprot_attrs perm);
+
 /**
  * noncached_init() - Initialize non-cached memory region
  *