Skip to content

Commit df0aa5a

Browse files
authored
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 <[email protected]>
1 parent 1a1ae36 commit df0aa5a

File tree

23 files changed

+42
-150
lines changed

23 files changed

+42
-150
lines changed

include/portable.h

-4
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@
9393
#define portBASE_TYPE_EXIT_CRITICAL() taskEXIT_CRITICAL()
9494
#endif
9595

96-
#ifndef portGET_CURRENT_TOP_OF_STACK
97-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { pxCurrentTopOfStack = ( StackType_t * ) pxCurrentTCB->pxTopOfStack; }
98-
#endif
99-
10096
#ifndef configSTACK_DEPTH_TYPE
10197
#define configSTACK_DEPTH_TYPE StackType_t
10298
#endif

include/stack_macros.h

+42-41
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,25 @@
5353
#define portSTACK_LIMIT_PADDING 0
5454
#endif
5555

56-
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
56+
/* Stack overflow check is not straight forward to implement for MPU ports
57+
* because of the following reasons:
58+
* 1. The context is stored in TCB and as a result, pxTopOfStack member points
59+
* to the context location in TCB.
60+
* 2. System calls are executed on a separate privileged only stack.
61+
*
62+
* It is still okay because an MPU region is used to protect task stack which
63+
* means task stack overflow will trigger an MPU fault for unprivileged tasks.
64+
* Additionally, architectures with hardware stack overflow checking support
65+
* (such as Armv8-M) will trigger a fault when a task's stack overflows.
66+
*/
67+
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
5768

5869
/* Only the current stack state is to be checked. */
5970
#define taskCHECK_FOR_STACK_OVERFLOW() \
6071
do \
6172
{ \
62-
StackType_t * pxCurrentTopOfStack; \
63-
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
64-
\
6573
/* Is the currently saved stack pointer within the stack limit? */ \
66-
if( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
74+
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
6775
{ \
6876
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
6977
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
@@ -73,51 +81,46 @@
7381
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
7482
/*-----------------------------------------------------------*/
7583

76-
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
84+
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
7785

7886
/* Only the current stack state is to be checked. */
79-
#define taskCHECK_FOR_STACK_OVERFLOW() \
80-
do \
81-
{ \
82-
StackType_t * pxCurrentTopOfStack; \
83-
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
84-
\
85-
/* Is the currently saved stack pointer within the stack limit? */ \
86-
if( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
87-
{ \
88-
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
89-
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
90-
} \
87+
#define taskCHECK_FOR_STACK_OVERFLOW() \
88+
do \
89+
{ \
90+
/* Is the currently saved stack pointer within the stack limit? */ \
91+
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
92+
{ \
93+
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
94+
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
95+
} \
9196
} while( 0 )
9297

9398
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
9499
/*-----------------------------------------------------------*/
95100

96-
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
97-
98-
#define taskCHECK_FOR_STACK_OVERFLOW() \
99-
do \
100-
{ \
101-
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
102-
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
103-
StackType_t * pxCurrentTopOfStack; \
104-
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
105-
\
106-
if( ( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
107-
( pulStack[ 0 ] != ulCheckValue ) || \
108-
( pulStack[ 1 ] != ulCheckValue ) || \
109-
( pulStack[ 2 ] != ulCheckValue ) || \
110-
( pulStack[ 3 ] != ulCheckValue ) ) \
111-
{ \
112-
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
113-
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
114-
} \
101+
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
102+
103+
#define taskCHECK_FOR_STACK_OVERFLOW() \
104+
do \
105+
{ \
106+
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
107+
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
108+
\
109+
if( ( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
110+
( pulStack[ 0 ] != ulCheckValue ) || \
111+
( pulStack[ 1 ] != ulCheckValue ) || \
112+
( pulStack[ 2 ] != ulCheckValue ) || \
113+
( pulStack[ 3 ] != ulCheckValue ) ) \
114+
{ \
115+
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
116+
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
117+
} \
115118
} while( 0 )
116119

117120
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
118121
/*-----------------------------------------------------------*/
119122

120-
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
123+
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) )
121124

122125
#define taskCHECK_FOR_STACK_OVERFLOW() \
123126
do \
@@ -128,12 +131,10 @@
128131
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
129132
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
130133
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
131-
StackType_t * pxCurrentTopOfStack; \
132-
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
133134
\
134135
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
135136
\
136-
if( ( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \
137+
if( ( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \
137138
( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) ) \
138139
{ \
139140
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \

portable/ARMv8M/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM23/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM33/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM55/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM85/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/IAR/ARM_CM23/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h

-5
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,6 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
217217
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
218218
#endif
219219

220-
/* When MPU wrapper v2 is used, the task's context is stored in TCB and
221-
* pxTopOfStack member of TCB points to the context location in TCB. We,
222-
* therefore, need to read PSP to find the task's current top of stack. */
223-
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); }
224-
225220
/**
226221
* @brief System call stack.
227222
*/

0 commit comments

Comments
 (0)