[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