From: Utkarsh Rai <utkarsh.ra...@gmail.com> --- cpukit/score/cpu/arm/cpu.c | 3 +- cpukit/score/cpu/arm/cpu_asm.S | 14 ++- .../score/cpu/arm/include/rtems/score/cpu.h | 12 ++- cpukit/score/src/stackmanagement.c | 98 +++++++++++-------- cpukit/score/src/threadloadenv.c | 11 +++ 5 files changed, 92 insertions(+), 46 deletions(-)
diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c index 5ee1acede2..39b5a33c03 100644 --- a/cpukit/score/cpu/arm/cpu.c +++ b/cpukit/score/cpu/arm/cpu.c @@ -97,8 +97,9 @@ void _CPU_Context_Initialize( ) { (void) new_level; - + #if defined (USE_THREAD_STACK_PROTECTION) the_context->stack_attr = prot_stack_context_initialize(); + #endif the_context->register_sp = (uint32_t) stack_area_begin + stack_area_size; the_context->register_lr = (uint32_t) entry_point; the_context->isr_dispatch_disable = 0; diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S index e7cdd24c2f..2678589483 100644 --- a/cpukit/score/cpu/arm/cpu_asm.S +++ b/cpukit/score/cpu/arm/cpu_asm.S @@ -65,9 +65,13 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch) #endif str r3, [r0, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE] - str r0, [r0, #44] +#if defined ( USE_THREAD_STACK_PROTECTION ) + mov r2, r0 + ldr r0, [r0, #ARM_STACK_PROT_ATTR_OFFSET] bl prot_stack_context_switch - + mov r0, r2 +#endif + #ifdef RTEMS_SMP /* * The executing thread no longer executes on this processor. Switch @@ -135,6 +139,12 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch) */ DEFINE_FUNCTION_ARM(_CPU_Context_restore) mov r1, r0 +#if defined( USE_THREAD_STACK_PROTECTION ) + ldr r2, [lr] + ldr r0, [r0, #ARM_STACK_PROT_ATTR_OFFSET] + bl prot_stack_context_restore + ldr lr, [r2] +#endif GET_SELF_CPU_CONTROL r2 b .L_restore diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h b/cpukit/score/cpu/arm/include/rtems/score/cpu.h index 481d50f427..f0af63e532 100644 --- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h +++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h @@ -160,6 +160,16 @@ #define ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET 44 #endif +#ifdef USE_THREAD_STACK_PROTECTION + #if defined ARM_MULITLIB_VFP + #define ARM_STACK_PROT_ATTR_OFFSET 112 + #elif ARM_MULTILIB_HAS_THREAD_ID_REGISTER + #define ARM_STACK_PROT_ATTR_OFFSET 48 + #else + #define ARM_STACK_PROT_ATTR_OFFSET 44 + #endif +#endif + #ifdef ARM_MULTILIB_VFP #define ARM_CONTEXT_CONTROL_D8_OFFSET 48 #endif @@ -184,8 +194,6 @@ #define ARM_EXCEPTION_FRAME_VFP_CONTEXT_OFFSET 72 -#define ARM_STACK_PROT_ATTR_OFFSET 44 - #define ARM_VFP_CONTEXT_SIZE 264 diff --git a/cpukit/score/src/stackmanagement.c b/cpukit/score/src/stackmanagement.c index 5ed8242c50..eff1b59add 100644 --- a/cpukit/score/src/stackmanagement.c +++ b/cpukit/score/src/stackmanagement.c @@ -1,7 +1,8 @@ #include <rtems/score/stackmanagement.h> #include <rtems/score/chainimpl.h> +#include <rtems/score/basedefs.h> -Chain_Control *node_control; +Chain_Control prot_node_control = CHAIN_INITIALIZER_EMPTY(prot_node_control); Chain_Control *shared_node_control; @@ -20,71 +21,82 @@ static void shared_stack_entry_remove(stack_attr_shared *shared_stack) memory_entries_unset(shared_stack->Base.stack_address, shared_stack->Base.size); node = node->next; } - } } -static void prot_stack_prev_entry_remove(stack_attr_prot *stack_attr) +static void prot_stack_prev_entry_remove(void) { - + Chain_Node *node; -/* - if(node_control == NULL) { - _Chain_Initialize_empty(node_control); + stack_attr_prot *stack_attr; + + if( _Chain_Is_empty(&prot_node_control) == true ) { + _Chain_Initialize_empty(&prot_node_control); } - */ - while(!_Chain_Is_tail(node_control, node)) { - stack_attr = (stack_attr_prot*) node; + node = _Chain_First( &prot_node_control ); + + while(_Chain_Is_tail(&prot_node_control, node) == false) { - if( stack_attr->current_stack == false ) { + stack_attr = RTEMS_CONTAINER_OF(node,stack_attr_prot, Base.node); + + if( stack_attr->current_stack == false && _Chain_Is_head(&prot_node_control, node) == false ) { memory_entries_unset(stack_attr->Base.stack_address, stack_attr->Base.size); - shared_stack_entry_remove(stack_attr->shared_stacks); - node = node->next; + // shared_stack_entry_remove(stack_attr->shared_stacks); + } + node = _Chain_Immutable_next( node ); } - - + + return ; } -static void prot_stack_chain_append (Chain_Control *control, stack_attr_prot *stack_attr) //maybe we don't need the chain control parameter to be passed +static void prot_stack_chain_append (Chain_Control *control, stack_attr_prot *stack_append_attr) //maybe we don't need the chain control parameter to be passed { Chain_Node *node; + stack_attr_prot *present_stacks_attr; + + if(_Chain_Is_empty(&prot_node_control) == true ) { - if( control == NULL ) { - _Chain_Initialize_one(control, &stack_attr->Base.node); + _Chain_Initialize_one(&prot_node_control, &stack_append_attr->Base.node); } else { - node = _Chain_Head(control); + node = _Chain_First(&prot_node_control); /* This is done to ensure that we mark all the remaining entries as not-current so that they can be removed. */ - while(!_Chain_Is_tail(control,node)) { - stack_attr = (stack_attr_prot*) node; - stack_attr->current_stack = false; - node = node->next; + while(_Chain_Is_tail(&prot_node_control,node) == false) { + + present_stacks_attr = RTEMS_CONTAINER_OF(node, stack_attr_prot, Base.node); + present_stacks_attr->current_stack = false; + node = _Chain_Immutable_next( node ); } - _Chain_Append_unprotected(control, &stack_attr->Base.node); + _Chain_Append_unprotected(&prot_node_control, &stack_append_attr->Base.node); } - + return ; } void prot_stack_allocate(uint32_t *stack_address, size_t size, uint32_t *page_table_base) { stack_attr_prot *stack_attr; - stack_attr = malloc(sizeof(stack_attr_prot)); + // Have a condition for the case when the same stack is allocated twice, do not allocate a new node, will cause memory leaks. + stack_attr = malloc(sizeof(stack_attr_prot)); + + if(stack_attr != NULL) { stack_attr->Base.stack_address = stack_address; stack_attr->Base.size = size; stack_attr->Base.page_table_base = page_table_base; stack_attr->Base.access_flags = READ_WRITE_CACHED; stack_attr->current_stack = true; - - prot_stack_chain_append( node_control, stack_attr ); // Add the stack attr. at the end of the chain - prot_stack_prev_entry_remove( stack_attr ); // Remove the previous stack entry + } + prot_stack_chain_append(&prot_node_control, stack_attr ); // Add the stack attr. at the end of the chain + prot_stack_prev_entry_remove(); // Remove the previous stack entry + + memory_entries_set(stack_address, size, READ_WRITE_CACHED); - memory_entries_set(stack_address, size, READ_WRITE); + return; } @@ -93,16 +105,16 @@ stack_attr_prot *prot_stack_context_initialize(void) Chain_Node *node; stack_attr_prot *stack_attr; - if( node_control != NULL && _Chain_Is_empty(node_control) == false ) { - node = _Chain_Head( node_control ); + if( _Chain_Is_empty(&prot_node_control) == false ) { + node = _Chain_First( &prot_node_control ); - while( _Chain_Is_tail( node_control, node ) == false) { - stack_attr = (stack_attr_prot*) node; + while( _Chain_Is_tail(&prot_node_control, node ) == false) { + stack_attr = RTEMS_CONTAINER_OF( node, stack_attr_prot, Base.node); if(stack_attr->current_stack == true) { return stack_attr; } else { - node = node->next; + node = _Chain_Immutable_next( node ); } } } @@ -132,8 +144,10 @@ void prot_stack_context_switch(stack_attr_prot *stack_attr) shared_node_control = &stack_attr->shared_stacks->shared_node_control; } +/* + + The shared node control structure will be initialized during stack sharing - if( shared_node_control != NULL && _Chain_Is_empty( shared_node_control ) == false) { node = _Chain_Head(shared_node_control); @@ -147,7 +161,7 @@ void prot_stack_context_switch(stack_attr_prot *stack_attr) node = node->next; } } - +*/ } void prot_stack_context_restore(stack_attr_prot *stack_attr) @@ -162,16 +176,18 @@ void prot_stack_context_restore(stack_attr_prot *stack_attr) */ if(stack_attr != NULL){ - stack_attr->current_stack = true; + /* stack_attr->current_stack = true; stack_address = stack_attr->Base.stack_address; size = stack_attr->Base.size; - + */ if(stack_attr->current_stack == true) { memory_entries_set(stack_address, size, READ_WRITE_CACHED); } + return ; - shared_node_control = &stack_attr->shared_stacks->shared_node_control; + // shared_node_control = &stack_attr->shared_stacks->shared_node_control; } +/* The shared node control structure will be initialized during stack sharing if( shared_node_control !=NULL && _Chain_Is_empty( shared_node_control ) == false ) { node = _Chain_Head( shared_node_control ); @@ -188,7 +204,7 @@ void prot_stack_context_restore(stack_attr_prot *stack_attr) } } // Possible bug - + */ } /* diff --git a/cpukit/score/src/threadloadenv.c b/cpukit/score/src/threadloadenv.c index 9b0808cbf8..44ff5c3a28 100644 --- a/cpukit/score/src/threadloadenv.c +++ b/cpukit/score/src/threadloadenv.c @@ -21,6 +21,10 @@ #include <rtems/score/threadimpl.h> +//#if defined( THREAD_STACK_PROTECTION ) +#include <rtems/score/stackmanagement.h> +//#endif + void _Thread_Load_environment( Thread_Control *the_thread ) @@ -35,6 +39,13 @@ void _Thread_Load_environment( the_thread->is_preemptible = the_thread->Start.is_preemptible; the_thread->budget_algorithm = the_thread->Start.budget_algorithm; the_thread->budget_callout = the_thread->Start.budget_callout; + + // #if defined ( USE_THREAD_STACK_PROTECTION ) + /*prot_stack_allocate( + the_thread->Start.Initial_stack.area, + the_thread->Start.Initial_stack.size, + (uint32_t *) 0x1000);*/ + // #endif _Context_Initialize( &the_thread->Registers, -- 2.17.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel