diff --git a/arch/Kconfig b/arch/Kconfig index a801946ed82..6cf29205dfc 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -449,6 +449,29 @@ config MPU_REQUIRES_NON_OVERLAPPING_REGIONS This option is enabled when the MPU requires the active (i.e. enabled) MPU regions to be non-overlapping with each other. +config MPU_GAP_FILLING + bool "Force MPU to be filling in background memory regions" + depends on MPU_REQUIRES_NON_OVERLAPPING_REGIONS + depends on USERSPACE + help + This Kconfig option instructs the MPU driver to enforce + a full kernel SRAM partitioning, when it programs the + dynamic MPU regions (user thread stack, PRIV stack guard + and application memory domains) during context-switch. We + allow this to be a configurable option, in order to be able + to switch the option off and have an increased number of MPU + regions available for application memory domain programming. + + Notes: + An increased number of MPU regions should only be required, + when building with USERSPACE support. + + When the option is switched off, access to memory areas not + covered by explicit MPU regions is restricted to privileged + code on an ARCH-specific basis. Refer to ARCH-specific + documentation for more information on how this option is + used. + menuconfig FLOAT bool "Floating point" depends on CPU_HAS_FPU diff --git a/arch/arm/core/cortex_m/mpu/Kconfig b/arch/arm/core/cortex_m/mpu/Kconfig index f55604edc7e..c0dbae36e6c 100644 --- a/arch/arm/core/cortex_m/mpu/Kconfig +++ b/arch/arm/core/cortex_m/mpu/Kconfig @@ -14,10 +14,33 @@ config ARM_MPU select MPU_REQUIRES_NON_OVERLAPPING_REGIONS if CPU_HAS_ARM_MPU && (ARMV8_M_BASELINE || ARMV8_M_MAINLINE) help MCU implements Memory Protection Unit. - Note that NXP MPU as well as ARMv8-M MPU does not require MPU regions + + Notes: + The ARMv6-M and ARMv8-M MPU architecture requires a power-of-two + alignment of MPU region base address and size. + + The NXP MPU as well as the ARMv8-M MPU do not require MPU regions to have power-of-two alignment for base address and region size. - In addition to the above, ARMv8-M MPU requires the active MPU regions - be non-overlapping. + + The ARMv8-M MPU requires the active MPU regions be non-overlapping. + As a result of this, the ARMv8-M MPU needs to fully partition the + memory map when programming dynamic memory regions (e.g. PRIV stack + guard, user thread stack, and application memory domains), if the + system requires PRIV access policy different from the access policy + of the ARMv8-M background memory map. The allication developer may + enforce full PRIV (kernel) memory partition by enabling the + CONFIG_MPU_GAP_FILLING option. + By not enforcing full partition, MPU may leave part of kernel + SRAM area covered only by the default ARMv8-M memory map. This + is fine for User Mode, since the background ARM map does not + allow nPRIV access at all. However, since the background map + policy allows instruction fetches by privileged code, forcing + this Kconfig option off prevents the system from directly + triggering MemManage exceptions upon accidental attempts to + execute code from SRAM in XIP builds. + Since this does not compromise User Mode, we make the skipping + of full partitioning the default behavior for the ARMv8-M MPU + driver. config ARM_MPU_REGION_MIN_ALIGN_AND_SIZE int diff --git a/arch/arm/core/cortex_m/mpu/arm_core_mpu_dev.h b/arch/arm/core/cortex_m/mpu/arm_core_mpu_dev.h index d55a06a9366..4b4df5ddc84 100644 --- a/arch/arm/core/cortex_m/mpu/arm_core_mpu_dev.h +++ b/arch/arm/core/cortex_m/mpu/arm_core_mpu_dev.h @@ -28,7 +28,8 @@ struct k_thread; * * @param mpu_regions_num the number of available HW MPU regions. */ -#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) +#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) && \ + !defined(CONFIG_MPU_SKIP_BACKGROUND_SRAM_FILLING) /* * For ARM MPU architectures, where the domain partitions cannot be defined * on top of the statically configured memory regions, the maximum number of @@ -53,7 +54,8 @@ struct k_thread; * @brief Maximum number of MPU regions required to configure a * memory region for (user) Thread Stack. */ -#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) +#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) && \ + !defined(CONFIG_MPU_SKIP_BACKGROUND_SRAM_FILLING) /* When dynamic regions may not be defined on top of statically * allocated memory regions, defining a region for a thread stack * requires two additional MPU regions to be configured; one for @@ -73,7 +75,8 @@ struct k_thread; * @brief Maximum number of MPU regions required to configure a * memory region for a (supervisor) Thread Stack Guard. */ -#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) \ +#if (defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) && \ + !defined(CONFIG_MPU_SKIP_BACKGROUND_SRAM_FILLING)) \ || defined(CONFIG_CPU_HAS_NXP_MPU) /* * When dynamic regions may not be defined on top of statically