diff --git a/include/sys/arch_interface.h b/include/sys/arch_interface.h index c9e99ec94ba..b27aeb94d37 100644 --- a/include/sys/arch_interface.h +++ b/include/sys/arch_interface.h @@ -126,6 +126,29 @@ static inline uint32_t arch_k_cycle_get_32(void); * * @see Z_THREAD_STACK_OBJ_ALIGN */ + +/** + * @def ARCH_THREAD_STACK_SIZE_ADJUST(size) + * @brief Round up a stack buffer size to alignment constraints + * + * Adjust a requested stack buffer size to the true size of its underlying + * buffer, defined as the area usable for thread stack context and thread- + * local storage. + * + * The size value passed here does not include storage reserved for platform + * data. + * + * The returned value is either the same size provided (if already properly + * aligned), or rounded up to satisfy alignment constraints. Calculations + * performed here *must* be idempotent. + * + * Optional definition. If undefined, stack buffer sizes are either: + * - Rounded up to the next power of two if user mode is enabled on an arch + * with an MPU that requires such alignment + * - Rounded up to ARCH_STACK_PTR_ALIGN + * + * @see Z_THREAD_STACK_SIZE_ADJUST + */ /** @} */ /** diff --git a/include/sys/thread_stack.h b/include/sys/thread_stack.h index a1b70de846c..ff60153d07c 100644 --- a/include/sys/thread_stack.h +++ b/include/sys/thread_stack.h @@ -113,6 +113,41 @@ static inline char *z_stack_ptr_align(char *ptr) #define Z_THREAD_STACK_OBJ_ALIGN(size) ARCH_STACK_PTR_ALIGN #endif /* ARCH_THREAD_STACK_OBJ_ALIGN */ +/** + * @def Z_THREAD_STACK_SIZE_ADJUST + * @brief Round up a requested stack size to satisfy constraints + * + * Given a requested stack buffer size, return an adjusted size value for + * the entire stack object which takes into consideration: + * + * - Reserved memory for platform data + * - Alignment of stack buffer bounds to CPU/ABI constraints + * - Alignment of stack buffer bounds to satisfy memory management hardware + * constraints such that a protection region can cover the stack buffer area + * + * If CONFIG_USERSPACE is enabled, this determines the size of stack objects + * which may be used by user mode threads, or threads running in supervisor + * mode which may later drop privileges to user mode. + * + * Arches define this with ARCH_THREAD_STACK_SIZE_ADJUST(). + * + * If ARCH_THREAD_STACK_SIZE_ADJUST is not defined, assume rounding up to + * ARCH_STACK_PTR_ALIGN is appropriate. + * + * Any memory reserved for platform data is also included in the total + * returned. + * + * @param size Requested size of the stack buffer + * @return Adjusted size of the stack object + */ +#if defined(ARCH_THREAD_STACK_SIZE_ADJUST) +#define Z_THREAD_STACK_SIZE_ADJUST(size) \ + (ARCH_THREAD_STACK_SIZE_ADJUST(size) + K_THREAD_STACK_RESERVED) +#else +#define Z_THREAD_STACK_SIZE_ADJUST(size) \ + (ROUND_UP((size), ARCH_STACK_PTR_ALIGN) + K_THREAD_STACK_RESERVED) +#endif /* ARCH_THREAD_STACK_SIZE_ADJUST */ + /** * @brief Obtain an extern reference to a stack *