[PATCH 2/2] Improve stack checker support for interrupt stacks

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Sep 20 07:20:53 UTC 2018


Prepare the interrupt stack which may be used by the boot processor as
initialization stack with the stack sanity pattern.  Check the interrupt
stack of the current processor in the thread begin and switch extension.

Update #3459.
---
 cpukit/libmisc/stackchk/check.c | 51 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c
index bc4a7fc478..1604479366 100644
--- a/cpukit/libmisc/stackchk/check.c
+++ b/cpukit/libmisc/stackchk/check.c
@@ -33,7 +33,10 @@
 #include <rtems/bspIo.h>
 #include <rtems/printer.h>
 #include <rtems/stackchk.h>
+#include <rtems/sysinit.h>
+#include <rtems/score/address.h>
 #include <rtems/score/percpu.h>
+#include <rtems/score/smp.h>
 #include <rtems/score/threadimpl.h>
 
 /*
@@ -150,10 +153,10 @@ static Stack_Control Stack_check_Interrupt_stack[ 1 ];
 #define Stack_check_Dope_stack(_stack) \
   memset((_stack)->area, BYTE_PATTERN, (_stack)->size)
 
-static bool Stack_check_Is_pattern_valid(const Thread_Control *the_thread)
+static bool Stack_check_Is_pattern_valid( const Stack_Control *stack )
 {
   return memcmp(
-    Stack_check_Get_pattern(&the_thread->Start.Initial_stack),
+    Stack_check_Get_pattern( stack ),
     Stack_check_Pattern,
     PATTERN_SIZE_BYTES
   ) == 0;
@@ -208,6 +211,11 @@ void rtems_stack_checker_begin_extension( Thread_Control *executing )
     stack->size = (size_t) ( (char *) cpu_self->interrupt_stack_high -
       (char *) cpu_self->interrupt_stack_low );
     Stack_check_Dope_stack( stack );
+  } else if ( !Stack_check_Is_pattern_valid( stack ) ) {
+    rtems_fatal(
+      RTEMS_FATAL_SOURCE_STACK_CHECKER,
+      rtems_build_name( 'I', 'N', 'T', 'R' )
+    );
   }
 
 #if defined(RTEMS_SMP)
@@ -282,17 +290,27 @@ void rtems_stack_checker_switch_extension(
 {
   bool sp_ok;
   bool pattern_ok;
+  const Stack_Control *stack;
 
   /*
    *  Check for an out of bounds stack pointer or an overwrite
    */
   sp_ok = Stack_check_Frame_pointer_in_range( running );
 
-  pattern_ok = Stack_check_Is_pattern_valid( running );
+  pattern_ok = Stack_check_Is_pattern_valid( &running->Start.Initial_stack );
 
   if ( !sp_ok || !pattern_ok ) {
     Stack_check_report_blown_task( running, pattern_ok );
   }
+
+  stack = &Stack_check_Interrupt_stack[ _SMP_Get_current_processor() ];
+
+  if ( stack->area != NULL && !Stack_check_Is_pattern_valid( stack ) ) {
+    rtems_fatal(
+      RTEMS_FATAL_SOURCE_STACK_CHECKER,
+      rtems_build_name( 'I', 'N', 'T', 'R' )
+    );
+  }
 }
 
 /*
@@ -465,3 +483,30 @@ void rtems_stack_checker_report_usage( void )
   rtems_print_printer_printk(&printer);
   rtems_stack_checker_report_usage_with_plugin( &printer );
 }
+
+static void Stack_check_Prepare_initialization_stack( void )
+{
+  uint32_t       cpu_self_index;
+  size_t         stack_size;
+  Stack_Control *stack;
+
+  cpu_self_index = _SMP_Get_current_processor();
+  stack = &Stack_check_Interrupt_stack[ cpu_self_index ];
+  stack_size = rtems_configuration_get_interrupt_stack_size();
+  stack->size = stack_size;
+  stack->area = _Addresses_Add_offset(
+    _Configuration_Interrupt_stack_area_begin,
+    cpu_self_index * stack_size
+  );
+  memcpy(
+    Stack_check_Get_pattern( stack ),
+    Stack_check_Pattern,
+    PATTERN_SIZE_BYTES
+  );
+}
+
+RTEMS_SYSINIT_ITEM(
+  Stack_check_Prepare_initialization_stack,
+  RTEMS_SYSINIT_BSP_WORK_AREAS,
+  RTEMS_SYSINIT_ORDER_SECOND
+);
-- 
2.13.7




More information about the devel mailing list