Skip to content

Commit e5a16d4

Browse files
committed
arch: indirect executable RAM symbol
Instead of marking RAM regions as executable when `CONFIG_XIP=n`, add a dedicated symbol to control the behaviour. XIP is the most obvious case that requires this, but LLEXT for example can also load code into RAM that is then executed. The addition of `XIP_NOT` forces `EXECUTABLE_RAM` when `XIP` is disabled in order to prevent users from accidently turning it off. Signed-off-by: Jordan Yates <jordan@embeint.com>
1 parent df8b43d commit e5a16d4

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

‎arch/Kconfig‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,19 @@ config XIP
241241
supply a linker command file when building your image. Enabling this
242242
option increases both the code and data footprint of the image.
243243

244+
config XIP_NOT
245+
bool
246+
default y if !XIP
247+
select EXECUTABLE_RAM if (MMU || MPU)
248+
help
249+
Helper symbol that forces EXECUTABLE_RAM if !XIP.
250+
251+
config EXECUTABLE_RAM
252+
bool "Configure RAM to be executable"
253+
depends on (MMU || MPU)
254+
default y if LLEXT
255+
help
256+
Configure RAM to be executable. Changes the attributes of REGION_RAM_ATTR.
244257

245258
if ARC || ARM || ARM64 || X86 || RISCV || RX || ARCH_POSIX
246259

‎include/zephyr/arch/arm/mpu/arm_mpu_v7m.h‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,12 @@
111111

112112
/* Some helper defines for common regions */
113113

114-
/* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When
115-
* CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep
116-
* the SRAM region XN bit clear or the application code will not be executable.
117-
*/
114+
/* Executable flag for RAM */
115+
#define RAM_EXEC COND_CODE_1(CONFIG_EXECUTABLE_RAM, (0), (NOT_EXEC))
116+
118117
#define REGION_RAM_ATTR(size) \
119118
{(NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \
120-
IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk)}
119+
RAM_EXEC | size | P_RW_U_NA_Msk)}
121120
#define REGION_RAM_NOCACHE_ATTR(size) \
122121
{(NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE | MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk)}
123122
#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)

‎include/zephyr/arch/arm/mpu/arm_mpu_v8.h‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
/* Attribute flag for not-allowing execution (eXecute Never) */
6868
#define NOT_EXEC MPU_RBAR_XN_Msk
6969

70+
/* Executable flag for RAM */
71+
#define RAM_EXEC COND_CODE_1(CONFIG_EXECUTABLE_RAM, (0), (NOT_EXEC))
72+
7073
/* To prevent execution of MPU region in privileged mode */
7174
#define PRIV_EXEC_NEVER (1)
7275

@@ -236,17 +239,12 @@
236239
.attr = p_attr(p_base, p_size), \
237240
}
238241

239-
/* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When
240-
* CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep
241-
* the SRAM region XN bit clear or the application code will not be executable.
242-
*/
243242
/* clang-format off */
244243
#define REGION_RAM_ATTR(base, size) \
245244
{ \
246-
.rbar = IF_ENABLED(CONFIG_XIP, (NOT_EXEC |)) P_RW_U_NA_Msk | \
247-
NON_SHAREABLE_Msk, /* AP, XN, SH */ \
248-
.mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \
249-
.r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
245+
.rbar = RAM_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
246+
.mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \
247+
.r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
250248
IF_ENABLED(CONFIG_ARM_MPU_PXN, (.pxn = !PRIV_EXEC_NEVER,)) \
251249
}
252250

0 commit comments

Comments
 (0)