mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-21 02:28:34 -04:00
Associate secure context with task handle
The secure side context management code now checks that the secure context being saved or restored belongs to the task being switched-out or switched-in respectively. Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
parent
66466793d5
commit
f87404b56f
53 changed files with 1796 additions and 1353 deletions
|
@ -35,6 +35,9 @@
|
|||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
|
||||
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||
|
||||
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
|
||||
{
|
||||
/* pxSecureContext value is in r0. */
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||
|
||||
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
|
||||
{
|
||||
/* pxSecureContext value is in r0. */
|
||||
|
|
|
@ -28,6 +28,13 @@
|
|||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
|
||||
/* Including FreeRTOSConfig.h here will cause build errors if the header file
|
||||
contains code not understood by the assembler - for example the 'extern' keyword.
|
||||
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
|
||||
the code is included in C files but excluded by the preprocessor in assembly
|
||||
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
PUBLIC SecureContext_LoadContextAsm
|
||||
PUBLIC SecureContext_SaveContextAsm
|
||||
|
||||
|
|
|
@ -28,6 +28,13 @@
|
|||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
|
||||
/* Including FreeRTOSConfig.h here will cause build errors if the header file
|
||||
contains code not understood by the assembler - for example the 'extern' keyword.
|
||||
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
|
||||
the code is included in C files but excluded by the preprocessor in assembly
|
||||
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
PUBLIC SecureContext_LoadContextAsm
|
||||
PUBLIC SecureContext_SaveContextAsm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -50,11 +50,6 @@
|
|||
*/
|
||||
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
|
||||
/**
|
||||
* @brief Maximum number of secure contexts.
|
||||
*/
|
||||
|
@ -70,11 +65,15 @@ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Get a free context from the secure context pool (xSecureContexts).
|
||||
* @brief Get a free secure context for a task from the secure context pool (xSecureContexts).
|
||||
*
|
||||
* @return Index of a free context in the xSecureContexts array.
|
||||
* This function ensures that only one secure context is allocated for a task.
|
||||
*
|
||||
* @param[in] pvTaskHandle The task handle for which the secure context is allocated.
|
||||
*
|
||||
* @return Index of a free secure context in the xSecureContexts array.
|
||||
*/
|
||||
static uint32_t ulGetSecureContext( void );
|
||||
static uint32_t ulGetSecureContext( void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Return the secure context to the secure context pool (xSecureContexts).
|
||||
|
@ -88,16 +87,26 @@ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
|
|||
extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static uint32_t ulGetSecureContext( void )
|
||||
static uint32_t ulGetSecureContext( void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulSecureContextIndex;
|
||||
/* Start with invalid index. */
|
||||
uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||
|
||||
for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ )
|
||||
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||
{
|
||||
if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) &&
|
||||
( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) &&
|
||||
( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) )
|
||||
if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) &&
|
||||
( xSecureContexts[ i ].pucStackLimit == NULL ) &&
|
||||
( xSecureContexts[ i ].pucStackStart == NULL ) &&
|
||||
( xSecureContexts[ i ].pvTaskHandle == NULL ) &&
|
||||
( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) )
|
||||
{
|
||||
ulSecureContextIndex = i;
|
||||
}
|
||||
else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle )
|
||||
{
|
||||
/* A task can only have one secure context. Do not allocate a second
|
||||
* context for the same task. */
|
||||
ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -111,20 +120,25 @@ static void vReturnSecureContext( uint32_t ulSecureContextIndex )
|
|||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
|
||||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
{
|
||||
uint32_t ulIPSR, i;
|
||||
static uint32_t ulSecureContextsInitialized = 0;
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) )
|
||||
{
|
||||
/* Ensure to initialize secure contexts only once. */
|
||||
ulSecureContextsInitialized = 1;
|
||||
|
||||
/* No stack for thread mode until a task's context is loaded. */
|
||||
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||
secureportSET_PSP( securecontextNO_STACK );
|
||||
|
@ -135,6 +149,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
xSecureContexts[ i ].pucCurrentStackPointer = NULL;
|
||||
xSecureContexts[ i ].pucStackLimit = NULL;
|
||||
xSecureContexts[ i ].pucStackStart = NULL;
|
||||
xSecureContexts[ i ].pvTaskHandle = NULL;
|
||||
}
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
@ -154,28 +169,35 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged )
|
||||
uint32_t ulIsTaskPrivileged,
|
||||
void * pvTaskHandle )
|
||||
#else /* configENABLE_MPU */
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
void * pvTaskHandle )
|
||||
#endif /* configENABLE_MPU */
|
||||
{
|
||||
uint8_t * pucStackMemory = NULL;
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
SecureContextHandle_t xSecureContextHandle;
|
||||
SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
uint32_t * pulCurrentStackPointer = NULL;
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
/* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
|
||||
* Register (PSPLIM) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
secureportREAD_PSPLIM( pucStackLimit );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
* when the processor is running in the Thread Mode.
|
||||
* Also do nothing, if a secure context us already loaded. PSPLIM is set to
|
||||
* securecontextNO_STACK when no secure context is loaded. */
|
||||
if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) )
|
||||
{
|
||||
/* Ontain a free secure context. */
|
||||
ulSecureContextIndex = ulGetSecureContext();
|
||||
ulSecureContextIndex = ulGetSecureContext( pvTaskHandle );
|
||||
|
||||
/* Were we able to get a free context? */
|
||||
if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
|
||||
|
@ -197,6 +219,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
* programmed in the PSPLIM register on context switch.*/
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
|
||||
|
||||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
|
@ -229,10 +253,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
/* Ensure to never return 0 as a valid context handle. */
|
||||
xSecureContextHandle = ulSecureContextIndex + 1UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +260,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
|
||||
|
@ -256,38 +276,61 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
|||
{
|
||||
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||
|
||||
/* Free the stack space. */
|
||||
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
|
||||
/* Ensure that the secure context being deleted is associated with
|
||||
* the task. */
|
||||
if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
|
||||
{
|
||||
/* Free the stack space. */
|
||||
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
|
||||
|
||||
/* Return the context back to the free contexts pool. */
|
||||
vReturnSecureContext( ulSecureContextIndex );
|
||||
/* Return the secure context back to the free secure contexts pool. */
|
||||
vReturnSecureContext( ulSecureContextIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
||||
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||
{
|
||||
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||
|
||||
SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||
secureportREAD_PSPLIM( pucStackLimit );
|
||||
|
||||
/* Ensure that no secure context is loaded and the task is loading it's
|
||||
* own context. */
|
||||
if( ( pucStackLimit == securecontextNO_STACK ) &&
|
||||
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||
{
|
||||
SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
||||
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||
{
|
||||
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||
|
||||
SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||
secureportREAD_PSPLIM( pucStackLimit );
|
||||
|
||||
/* Ensure that task's context is loaded and the task is saving it's own
|
||||
* context. */
|
||||
if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) &&
|
||||
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||
{
|
||||
SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -37,7 +37,12 @@
|
|||
/**
|
||||
* @brief PSP value when no secure context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
@ -51,6 +56,7 @@ typedef struct SecureContext
|
|||
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||
void * pvTaskHandle; /**< Task handle of the task this context is associated with. */
|
||||
} SecureContext_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -85,9 +91,11 @@ void SecureContext_Init( void );
|
|||
*/
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged );
|
||||
uint32_t ulIsTaskPrivileged,
|
||||
void * pvTaskHandle );
|
||||
#else /* configENABLE_MPU */
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
void * pvTaskHandle );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/**
|
||||
|
@ -99,7 +107,7 @@ void SecureContext_Init( void );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle );
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
|
@ -110,7 +118,7 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle );
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
|
@ -121,6 +129,6 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle );
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
||||
|
|
|
@ -448,9 +448,3 @@ size_t xPortGetMinimumEverFreeHeapSize( void )
|
|||
return xMinimumEverFreeBytesRemaining;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortInitialiseBlocks( void )
|
||||
{
|
||||
/* This just exists to keep the linker quiet. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -48,4 +48,18 @@ void * pvPortMalloc( size_t xWantedSize );
|
|||
*/
|
||||
void vPortFree( void * pv );
|
||||
|
||||
/**
|
||||
* @brief Get the free heap size.
|
||||
*
|
||||
* @return Free heap size.
|
||||
*/
|
||||
size_t xPortGetFreeHeapSize( void );
|
||||
|
||||
/**
|
||||
* @brief Get the minimum ever free heap size.
|
||||
*
|
||||
* @return Minimum ever free heap size.
|
||||
*/
|
||||
size_t xPortGetMinimumEverFreeHeapSize( void );
|
||||
|
||||
#endif /* __SECURE_HEAP_H__ */
|
||||
|
|
|
@ -67,6 +67,12 @@
|
|||
#define secureportSET_PSP( pucCurrentStackPointer ) \
|
||||
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
|
||||
|
||||
/**
|
||||
* @brief Read the PSPLIM value in the given variable.
|
||||
*/
|
||||
#define secureportREAD_PSPLIM( pucOutStackLimit ) \
|
||||
__asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) )
|
||||
|
||||
/**
|
||||
* @brief Set the PSPLIM to the given value.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue