Disable stack overflow check for MPU ports (#1231)

Disable stack overflow check for MPU ports

Stack overflow check is not straight forward to implement for MPU ports
because of the following reasons:
1. The context is stroed in TCB and as a result, pxTopOfStack member
   points to the context location in TCB.
2. System calls are executed on a separate privileged only stack.

It is still okay because an MPU region is used to protect task stack
which means task stack overflow will trigger an MPU fault.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
Gaurav-Aggarwal-AWS
2025-02-24 21:54:15 +05:30
committed by GitHub
parent 1a1ae36f9a
commit df0aa5a815
23 changed files with 41 additions and 149 deletions

View File

@ -53,17 +53,25 @@
#define portSTACK_LIMIT_PADDING 0
#endif
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
/* Stack overflow check is not straight forward to implement for MPU ports
* because of the following reasons:
* 1. The context is stored in TCB and as a result, pxTopOfStack member points
* to the context location in TCB.
* 2. System calls are executed on a separate privileged only stack.
*
* It is still okay because an MPU region is used to protect task stack which
* means task stack overflow will trigger an MPU fault for unprivileged tasks.
* Additionally, architectures with hardware stack overflow checking support
* (such as Armv8-M) will trigger a fault when a task's stack overflows.
*/
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
/* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \
do \
{ \
StackType_t * pxCurrentTopOfStack; \
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
{ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
@ -73,51 +81,46 @@
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
/* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \
do \
{ \
StackType_t * pxCurrentTopOfStack; \
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
{ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
} \
#define taskCHECK_FOR_STACK_OVERFLOW() \
do \
{ \
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
{ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
} \
} while( 0 )
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \
do \
{ \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
StackType_t * pxCurrentTopOfStack; \
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
\
if( ( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
( pulStack[ 0 ] != ulCheckValue ) || \
( pulStack[ 1 ] != ulCheckValue ) || \
( pulStack[ 2 ] != ulCheckValue ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \
{ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
} \
#define taskCHECK_FOR_STACK_OVERFLOW() \
do \
{ \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
\
if( ( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
( pulStack[ 0 ] != ulCheckValue ) || \
( pulStack[ 1 ] != ulCheckValue ) || \
( pulStack[ 2 ] != ulCheckValue ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \
{ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
} \
} while( 0 )
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \
do \
@ -128,12 +131,10 @@
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
StackType_t * pxCurrentTopOfStack; \
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
\
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\
if( ( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \
if( ( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \
( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) ) \
{ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \