Implement MicroBlazeV9 stack protection (#523)

* Implement stack protection for MicroBlaze (without MPU wrappers)
This commit is contained in:
Gavin Lambert 2022-08-03 18:31:18 +12:00 committed by GitHub
parent bfe057367d
commit 63f86fc7a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 11 deletions

View File

@ -105,7 +105,11 @@ static XIntc xInterruptControllerInstance;
*
* See the portable.h header file.
*/
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters )
#else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
#endif
{
extern void *_SDA2_BASE_, *_SDA_BASE_;
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
@ -122,6 +126,14 @@ extern void _start1( void );
*pxTopOfStack = ( StackType_t ) 0x00000000;
pxTopOfStack--;
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
/* Store the stack limits. */
*pxTopOfStack = (StackType_t) (pxTopOfStack + 3);
pxTopOfStack--;
*pxTopOfStack = (StackType_t) pxEndOfStack;
pxTopOfStack--;
#endif
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
/* The FSR value placed in the initial task context is just 0. */
*pxTopOfStack = portINITIAL_FSR;

View File

@ -33,16 +33,6 @@
#include "microblaze_exceptions_g.h"
#include "xparameters.h"
/* The context is oversized to allow functions called from the ISR to write
back into the caller stack. */
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
#define portCONTEXT_SIZE 136
#define portMINUS_CONTEXT_SIZE -136
#else
#define portCONTEXT_SIZE 132
#define portMINUS_CONTEXT_SIZE -132
#endif
/* Offsets from the stack pointer at which saved registers are placed. */
#define portR31_OFFSET 4
#define portR30_OFFSET 8
@ -76,7 +66,31 @@ back into the caller stack. */
#define portR2_OFFSET 120
#define portCRITICAL_NESTING_OFFSET 124
#define portMSR_OFFSET 128
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
#define portFSR_OFFSET 132
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
#define portSLR_OFFSET 136
#define portSHR_OFFSET 140
#define portCONTEXT_SIZE 144
#define portMINUS_CONTEXT_SIZE -144
#else
#define portCONTEXT_SIZE 136
#define portMINUS_CONTEXT_SIZE -136
#endif
#else
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
#define portSLR_OFFSET 132
#define portSHR_OFFSET 136
#define portCONTEXT_SIZE 140
#define portMINUS_CONTEXT_SIZE -140
#else
#define portCONTEXT_SIZE 132
#define portMINUS_CONTEXT_SIZE -132
#endif
#endif
.extern pxCurrentTCB
.extern XIntc_DeviceInterruptHandler
@ -144,6 +158,14 @@ back into the caller stack. */
swi r18, r1, portFSR_OFFSET
#endif
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
/* Save the stack limits */
mfs r18, rslr
swi r18, r1, portSLR_OFFSET
mfs r18, rshr
swi r18, r1, portSHR_OFFSET
#endif
/* Save the top of stack value to the TCB. */
lwi r3, r0, pxCurrentTCB
sw r1, r0, r3
@ -156,6 +178,17 @@ back into the caller stack. */
lwi r18, r0, pxCurrentTCB
lw r1, r0, r18
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
/* Restore the stack limits -- must not load from r1 (Stack Pointer)
because if the address of load or store instruction is out of range,
it will trigger Stack Protection Violation exception. */
or r18, r0, r1
lwi r12, r18, portSLR_OFFSET
mts rslr, r12
lwi r12, r18, portSHR_OFFSET
mts rshr, r12
#endif
/* Restore the general registers. */
lwi r31, r1, portR31_OFFSET
lwi r30, r1, portR30_OFFSET
@ -252,6 +285,13 @@ _interrupt_handler:
/* Switch to the ISR stack. */
lwi r1, r0, pulISRStack
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
ori r18, r0, _stack_end
mts rslr, r18
ori r18, r0, _stack
mts rshr, r18
#endif
/* The parameter to the interrupt handler. */
ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE
@ -296,6 +336,13 @@ VPortYieldASM:
/* Switch to use the ISR stack. */
lwi r1, r0, pulISRStack
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
ori r18, r0, _stack_end
mts rslr, r18
ori r18, r0, _stack
mts rshr, r18
#endif
/* Select the next task to execute. */
bralid r15, vTaskSwitchContext
or r0, r0, r0

View File

@ -152,6 +152,11 @@ extern volatile uint32_t ulTaskSwitchRequested;
#define portNOP() asm volatile ( "NOP" )
/*-----------------------------------------------------------*/
#if( XPAR_MICROBLAZE_USE_STACK_PROTECTION )
#define portHAS_STACK_OVERFLOW_CHECKING 1
#endif
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )