From a0ab1c2acd51cef934e33a1328ef391ad1078e93 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Mon, 4 Jul 2022 15:23:30 +0800 Subject: [PATCH] freertos: Fix stack and TCB allocation order in SMP FreeRTOS This commit fixes the allocation order of task stacks and TCBs in order to reduce the chance of a stack overflow overwriting a TCB. --- .../FreeRTOS-Kernel-SMP/portable/riscv/port.c | 34 ++++++++++++------- .../portable/xtensa/port.c | 32 +++++++++++------ 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 118b940cf5..f8ff4bf047 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -455,16 +455,21 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { - StaticTask_t *pxTCBBufferTemp; StackType_t *pxStackBufferTemp; - //Allocate TCB and stack buffer in internal memory - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); + StaticTask_t *pxTCBBufferTemp; + /* Stack always grows downwards (from high address to low address) on all + * ESP RISC-V targets. Given that the heap allocator likely allocates memory + * from low to high address, we allocate the stack first and then the TCB so + * that the stack does not grow downwards into the TCB. + * + * Allocate TCB and stack buffer in internal memory. */ pxStackBufferTemp = pvPortMalloc(CONFIG_FREERTOS_IDLE_TASK_STACKSIZE); - assert(pxTCBBufferTemp != NULL); + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); assert(pxStackBufferTemp != NULL); - //Write back pointers - *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; + assert(pxTCBBufferTemp != NULL); + // Write back pointers *ppxIdleTaskStackBuffer = pxStackBufferTemp; + *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; *pulIdleTaskStackSize = CONFIG_FREERTOS_IDLE_TASK_STACKSIZE; } @@ -472,16 +477,21 @@ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) { - StaticTask_t *pxTCBBufferTemp; StackType_t *pxStackBufferTemp; - //Allocate TCB and stack buffer in internal memory - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); + StaticTask_t *pxTCBBufferTemp; + /* Stack always grows downwards (from high address to low address) on all + * ESP RISC-V targets. Given that the heap allocator likely allocates memory + * from low to high address, we allocate the stack first and then the TCB so + * that the stack does not grow downwards into the TCB. + * + * Allocate TCB and stack buffer in internal memory. */ pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); - assert(pxTCBBufferTemp != NULL); + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); assert(pxStackBufferTemp != NULL); - //Write back pointers - *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; + assert(pxTCBBufferTemp != NULL); + // Write back pointers *ppxTimerTaskStackBuffer = pxStackBufferTemp; + *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } #endif //( configSUPPORT_STATIC_ALLOCATION == 1 ) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index bbd091efe5..e83354167a 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -508,16 +508,21 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { - StaticTask_t *pxTCBBufferTemp; StackType_t *pxStackBufferTemp; - //Allocate TCB and stack buffer in internal memory - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); + StaticTask_t *pxTCBBufferTemp; + /* Stack always grows downwards (from high address to low address) on all + * ESP Xtensa targets. Given that the heap allocator likely allocates memory + * from low to high address, we allocate the stack first and then the TCB so + * that the stack does not grow downwards into the TCB. + * + * Allocate TCB and stack buffer in internal memory. */ pxStackBufferTemp = pvPortMalloc(CONFIG_FREERTOS_IDLE_TASK_STACKSIZE); - assert(pxTCBBufferTemp != NULL); + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); assert(pxStackBufferTemp != NULL); - //Write back pointers - *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; + assert(pxTCBBufferTemp != NULL); + // Write back pointers *ppxIdleTaskStackBuffer = pxStackBufferTemp; + *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; *pulIdleTaskStackSize = CONFIG_FREERTOS_IDLE_TASK_STACKSIZE; } @@ -527,14 +532,19 @@ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, { StaticTask_t *pxTCBBufferTemp; StackType_t *pxStackBufferTemp; - //Allocate TCB and stack buffer in internal memory - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); + /* Stack always grows downwards (from high address to low address) on all + * ESP Xtensa targets. Given that the heap allocator likely allocates memory + * from low to high address, we allocate the stack first and then the TCB so + * that the stack does not grow downwards into the TCB. + * + * Allocate TCB and stack buffer in internal memory. */ pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); - assert(pxTCBBufferTemp != NULL); + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); assert(pxStackBufferTemp != NULL); - //Write back pointers - *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; + assert(pxTCBBufferTemp != NULL); + // Write back pointers *ppxTimerTaskStackBuffer = pxStackBufferTemp; + *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } #endif //( configSUPPORT_STATIC_ALLOCATION == 1 )