[PATCH] Assembly suppport for context switch and bug fixes

utkarsh.rai60 at gmail.com utkarsh.rai60 at gmail.com
Mon Jun 29 14:47:34 UTC 2020


From: Utkarsh Rai <utkarsh.rai60 at 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



More information about the devel mailing list