From a63fd97de8e9d2ae47a20eea2ca6061b01973ac6 Mon Sep 17 00:00:00 2001 From: magicse7en Date: Thu, 13 Aug 2020 11:44:19 +0800 Subject: [PATCH] Xtensa: fix stack overlap coproc_area issue In function pxPortInitialiseStack of port.c: sp = ( StackType_t * ) ( ( ( UBaseType_t ) ( pxTopOfStack + 1 ) - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf ); We assume XT_CP_SIZE is 0xE4, XT_STK_FRMSZ is 0xA0, pxTopOfStack is 0xA0000000, sp is 0x9FFFFE80. From port.c, we know the frame->a1 as below: frame->a1 = ( UBaseType_t ) sp + XT_STK_FRMSZ; /* physical top of stack frame */ So frame->a1 is 0x9FFFFF20. Therefore the interrupt stack frame range is 0x9FFFFE80 ~ 0x9FFFFF20. The coproc_area is: p = ( uint32_t * ) ( ( ( uint32_t ) pxTopOfStack - XT_CP_SIZE ) & ~0xf ); So its value is 0x9FFFFF10. Obviously, the interrupt stack frame overlaps the coproc_area. --- portable/ThirdParty/XCC/Xtensa/port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/portable/ThirdParty/XCC/Xtensa/port.c b/portable/ThirdParty/XCC/Xtensa/port.c index 141263929..a3996138e 100644 --- a/portable/ThirdParty/XCC/Xtensa/port.c +++ b/portable/ThirdParty/XCC/Xtensa/port.c @@ -102,7 +102,7 @@ void _xt_user_exit( void ); #endif /* Create interrupt stack frame aligned to 16 byte boundary */ - sp = ( StackType_t * ) ( ( ( UBaseType_t ) ( pxTopOfStack + 1 ) - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf ); + sp = ( StackType_t * ) ( ( ( UBaseType_t ) pxTopOfStack - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf ); /* Clear the entire frame (do not use memset() because we don't depend on C library) */ for( tp = sp; tp <= pxTopOfStack; ++tp ) @@ -141,6 +141,7 @@ void _xt_user_exit( void ); * //p = (uint32_t *) xMPUSettings->coproc_area; */ p = ( uint32_t * ) ( ( ( uint32_t ) pxTopOfStack - XT_CP_SIZE ) & ~0xf ); + configASSERT( ( uint32_t ) p >= frame->a1 ); p[ 0 ] = 0; p[ 1 ] = 0; p[ 2 ] = ( ( ( uint32_t ) p ) + 12 + XCHAL_TOTAL_SA_ALIGN - 1 ) & -XCHAL_TOTAL_SA_ALIGN;