arch: arm: cortex-m: hw stack protection under no multi-threading
This commit adds the support for HW Stack Protection when building Zephyr without support for multi-threading. The single MPU guard (if the feature is enabled) is set to guard the Main stack area. The stack fail check is also updated. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
parent
4338552175
commit
fa04bf615c
|
@ -46,6 +46,10 @@ LOG_MODULE_REGISTER(mpu);
|
|||
#define _MPU_DYNAMIC_REGIONS_AREA_SIZE ((uint32_t)&__kernel_ram_end - \
|
||||
_MPU_DYNAMIC_REGIONS_AREA_START)
|
||||
|
||||
#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_MPU_STACK_GUARD)
|
||||
extern K_THREAD_STACK_DEFINE(z_main_stack, CONFIG_MAIN_STACK_SIZE);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Use the HW-specific MPU driver to program
|
||||
* the static MPU regions.
|
||||
|
@ -86,6 +90,21 @@ void z_arm_configure_static_mpu_regions(void)
|
|||
};
|
||||
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
|
||||
|
||||
#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_MPU_STACK_GUARD)
|
||||
/* Main stack MPU guard to detect overflow.
|
||||
* Note:
|
||||
* FPU_SHARING and USERSPACE are not supported features
|
||||
* under CONFIG_MULTITHREADING=n, so the MPU guard (if
|
||||
* exists) is reserved aside of CONFIG_MAIN_STACK_SIZE
|
||||
* and there is no requirement for larger guard area (FP
|
||||
* context is not stacked).
|
||||
*/
|
||||
const struct k_mem_partition main_stack_guard_region = {
|
||||
.start = (uint32_t)z_main_stack,
|
||||
.size = (uint32_t)MPU_GUARD_ALIGN_AND_SIZE,
|
||||
.attr = K_MEM_PARTITION_P_RO_U_NA,
|
||||
};
|
||||
#endif /* !CONFIG_MULTITHREADING && CONFIG_MPU_STACK_GUARD */
|
||||
/* Define a constant array of k_mem_partition objects
|
||||
* to hold the configuration of the respective static
|
||||
* MPU regions.
|
||||
|
@ -97,6 +116,9 @@ void z_arm_configure_static_mpu_regions(void)
|
|||
#if defined(CONFIG_NOCACHE_MEMORY)
|
||||
&nocache_region,
|
||||
#endif /* CONFIG_NOCACHE_MEMORY */
|
||||
#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_MPU_STACK_GUARD)
|
||||
&main_stack_guard_region,
|
||||
#endif /* !CONFIG_MULTITHREADING && CONFIG_MPU_STACK_GUARD */
|
||||
#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
|
||||
&ramfunc_region
|
||||
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
|
||||
|
@ -112,7 +134,8 @@ void z_arm_configure_static_mpu_regions(void)
|
|||
(uint32_t)&_image_ram_start,
|
||||
(uint32_t)&__kernel_ram_end);
|
||||
|
||||
#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS)
|
||||
#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) && \
|
||||
defined(CONFIG_MULTITHREADING)
|
||||
/* Define a constant array of k_mem_partition objects that holds the
|
||||
* boundaries of the areas, inside which dynamic region programming
|
||||
* is allowed. The information is passed to the underlying driver at
|
||||
|
|
|
@ -256,11 +256,13 @@ void configure_builtin_stack_guard(struct k_thread *thread)
|
|||
*/
|
||||
uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp)
|
||||
{
|
||||
#if defined(CONFIG_MULTITHREADING)
|
||||
const struct k_thread *thread = _current;
|
||||
|
||||
if (!thread) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
|
||||
uint32_t guard_len = (thread->base.user_options & K_FP_REGS) ?
|
||||
|
@ -298,12 +300,21 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp
|
|||
}
|
||||
}
|
||||
#else /* CONFIG_USERSPACE */
|
||||
#if defined(CONFIG_MULTITHREADING)
|
||||
if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len,
|
||||
guard_len,
|
||||
fault_addr, psp)) {
|
||||
/* Thread stack corruption */
|
||||
return thread->stack_info.start;
|
||||
}
|
||||
#else
|
||||
if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack,
|
||||
guard_len,
|
||||
fault_addr, psp)) {
|
||||
/* Thread stack corruption */
|
||||
return (uint32_t)Z_THREAD_STACK_BUFFER(z_main_stack);
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue