Skip to content

Commit

Permalink
Associate secure context with task handle
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
aggarg committed Sep 10, 2021
1 parent ccaa0f4 commit 61f7560
Show file tree
Hide file tree
Showing 53 changed files with 1,800 additions and 1,357 deletions.
17 changes: 10 additions & 7 deletions portable/ARMv8M/non_secure/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulPC;

#if ( configENABLE_TRUSTZONE == 1 )
uint32_t ulR0;
uint32_t ulR0, ulR1;
extern TaskHandle_t pxCurrentTCB;
#if ( configENABLE_MPU == 1 )
uint32_t ulControl, ulIsTaskPrivileged;
#endif /* configENABLE_MPU */
Expand Down Expand Up @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 );

/* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB );
}
#else /* if ( configENABLE_MPU == 1 ) */
{
/* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0 );
xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB );
}
#endif /* configENABLE_MPU */

configASSERT( xSecureContext != NULL );
SecureContext_LoadContext( xSecureContext );
configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID );
SecureContext_LoadContext( xSecureContext, pxCurrentTCB );
break;

case portSVC_FREE_SECURE_CONTEXT:
/* R0 contains the secure context handle to be freed. */
/* R0 contains TCB being freed and R1 contains the secure
* context handle to be freed. */
ulR0 = pulCallerStackAddress[ 0 ];
ulR1 = pulCallerStackAddress[ 1 ];

/* Free the secure context. */
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
break;
#endif /* configENABLE_TRUSTZONE */

Expand Down
386 changes: 196 additions & 190 deletions portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c

Large diffs are not rendered by default.

319 changes: 163 additions & 156 deletions portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c

Large diffs are not rendered by default.

195 changes: 104 additions & 91 deletions portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
* https://github.com/FreeRTOS
*
*/
/* 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"

EXTERN pxCurrentTCB
EXTERN vTaskSwitchContext
Expand Down
165 changes: 86 additions & 79 deletions portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s
Original file line number Diff line number Diff line change
Expand Up @@ -184,62 +184,65 @@ vClearInterruptMask:
/*-----------------------------------------------------------*/

PendSV_Handler:
mrs r1, psp /* Read PSP in r1. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
mrs r2, psp /* Read PSP in r2. */

cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14}
bl SecureContext_SaveContext
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r0-r3} /* LR is now in r3. */
mov lr, r3 /* LR = r3. */
lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
bpl save_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */

ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r2, [r3] /* Read pxCurrentTCB. */
ldr r1, [r3] /* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 )
subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */
mrs r2, psplim /* r2 = PSPLIM. */
subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
str r2, [r1] /* Save the new top of stack in TCB. */
mrs r1, psplim /* r1 = PSPLIM. */
mrs r3, control /* r3 = CONTROL. */
mov r4, lr /* r4 = LR/EXC_RETURN. */
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */
subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */
mrs r2, psplim /* r2 = PSPLIM. */
subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */
str r2, [r1] /* Save the new top of stack in TCB. */
mrs r1, psplim /* r1 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
#endif /* configENABLE_MPU */
b select_next_task

save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r2, [r3] /* Read pxCurrentTCB. */
ldr r1, [r3] /* Read pxCurrentTCB. */
#if ( configENABLE_FPU == 1 )
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq
vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
vstmdbeq r2!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 )
subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */
adds r1, r1, #16 /* r1 = r1 + 16. */
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
mrs r2, psplim /* r2 = PSPLIM. */
subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #16 /* r2 = r2 + 16. */
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */
mrs r1, psplim /* r1 = PSPLIM. */
mrs r3, control /* r3 = CONTROL. */
mov r4, lr /* r4 = LR/EXC_RETURN. */
subs r1, r1, #16 /* r1 = r1 - 16. */
stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
subs r2, r2, #16 /* r2 = r2 - 16. */
stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */
subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */
adds r1, r1, #12 /* r1 = r1 + 12. */
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
mrs r2, psplim /* r2 = PSPLIM. */
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #12 /* r2 = r2 + 12. */
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */
mrs r1, psplim /* r1 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */
subs r1, r1, #12 /* r1 = r1 - 12. */
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
subs r2, r2, #12 /* r2 = r2 - 12. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
#endif /* configENABLE_MPU */

select_next_task:
Expand All @@ -251,77 +254,81 @@ PendSV_Handler:
mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */

ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read pxCurrentTCB. */
ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */

#if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */
ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r3] /* Read the value of MPU_CTRL. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
str r4, [r2] /* Disable MPU. */
str r4, [r3] /* Disable MPU. */

adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */
ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r3] /* Program MAIR0. */
ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */
movs r4, #4 /* r4 = 4. */
str r4, [r2] /* Program RNR = 4. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */

ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */
str r4, [r3] /* Program RNR = 4. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */

ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r3] /* Read the value of MPU_CTRL. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
str r4, [r2] /* Enable MPU. */
str r4, [r3] /* Enable MPU. */
dsb /* Force memory writes before continuing. */
#endif /* configENABLE_MPU */

#if ( configENABLE_MPU == 1 )
ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */
ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */
msr psplim, r1 /* Restore the PSPLIM register value for the task. */
msr control, r3 /* Restore the CONTROL register value for the task. */
mov lr, r4 /* LR = r4. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r2] /* Restore the task's xSecureContext. */
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's xSecureContext. */
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
push {r1,r4}
bl SecureContext_LoadContext /* Restore the secure context. */
pop {r1,r4}
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read pxCurrentTCB. */
push {r2, r4}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4}
mov lr, r4 /* LR = r4. */
lsls r2, r4, #25 /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
msr psp, r1 /* Remember the new top of stack for the task. */
lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
msr psp, r2 /* Remember the new top of stack for the task. */
bx lr
#else /* configENABLE_MPU */
ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */
mov lr, r3 /* LR = r3. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r2] /* Restore the task's xSecureContext. */
ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
msr psplim, r1 /* Restore the PSPLIM register value for the task. */
mov lr, r4 /* LR = r4. */
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's xSecureContext. */
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
push {r1,r3}
bl SecureContext_LoadContext /* Restore the secure context. */
pop {r1,r3}
mov lr, r3 /* LR = r3. */
lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
msr psp, r1 /* Remember the new top of stack for the task. */
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read pxCurrentTCB. */
push {r2, r4}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4}
mov lr, r4 /* LR = r4. */
lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
msr psp, r2 /* Remember the new top of stack for the task. */
bx lr
#endif /* configENABLE_MPU */

restore_ns_context:
ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */
ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( configENABLE_FPU == 1 )
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq
vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
vldmiaeq r2!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
#endif /* configENABLE_FPU */
msr psp, r1 /* Remember the new top of stack for the task. */
msr psp, r2 /* Remember the new top of stack for the task. */
bx lr
/*-----------------------------------------------------------*/

Expand All @@ -335,9 +342,9 @@ SVC_Handler:

vPortFreeSecureContext:
/* r0 = uint32_t *pulTCB. */
ldr r1, [r0] /* The first item in the TCB is the top of the stack. */
ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */
cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */
ldr r2, [r0] /* The first item in the TCB is the top of the stack. */
ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */
cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */
it ne
svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */
bx lr /* Return. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,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. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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
/*-----------------------------------------------------------*/
Expand Down
Loading

0 comments on commit 61f7560

Please sign in to comment.