Changeset 4221d93 in rtems


Ignore:
Timestamp:
Sep 20, 2018, 6:47:44 AM (15 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
7d1acc03
Parents:
a75a7d3
git-author:
Sebastian Huber <sebastian.huber@…> (09/20/18 06:47:44)
git-committer:
Sebastian Huber <sebastian.huber@…> (09/21/18 05:59:03)
Message:

stackchk: Improve support for interrupt stacks

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/stackchk/check.c

    ra75a7d3 r4221d93  
    3434#include <rtems/printer.h>
    3535#include <rtems/stackchk.h>
     36#include <rtems/sysinit.h>
     37#include <rtems/score/address.h>
    3638#include <rtems/score/percpu.h>
     39#include <rtems/score/smp.h>
    3740#include <rtems/score/threadimpl.h>
    3841
     
    6669 *  The "magic pattern" used to mark the end of the stack.
    6770 */
    68 static const uint32_t Stack_check_Pattern[] =
     71static const uint32_t Stack_check_Sanity_pattern[] =
    6972  CPU_STACK_CHECK_PATTERN_INITIALIZER;
    7073
    71 #define PATTERN_SIZE_BYTES sizeof(Stack_check_Pattern)
    72 
    73 #define PATTERN_SIZE_WORDS RTEMS_ARRAY_SIZE(Stack_check_Pattern)
     74#define SANITY_PATTERN_SIZE_BYTES sizeof(Stack_check_Sanity_pattern)
     75
     76#define SANITY_PATTERN_SIZE_WORDS RTEMS_ARRAY_SIZE(Stack_check_Sanity_pattern)
    7477
    7578/*
     
    105108  #define Stack_check_Get_pattern( _the_stack ) \
    106109    ((char *)(_the_stack)->area + \
    107          (_the_stack)->size - PATTERN_SIZE_BYTES )
     110         (_the_stack)->size - SANITY_PATTERN_SIZE_BYTES )
    108111
    109112  #define Stack_check_Calculate_used( _low, _size, _high_water ) \
    110113      ((char *)(_high_water) - (char *)(_low))
    111114
    112   #define Stack_check_usable_stack_start(_the_stack) \
     115  #define Stack_check_Usable_stack_start(_the_stack) \
    113116    ((_the_stack)->area)
    114117
     
    120123      ( ((char *)(_low) + (_size)) - (char *)(_high_water) )
    121124
    122   #define Stack_check_usable_stack_start(_the_stack) \
    123       ((char *)(_the_stack)->area + PATTERN_SIZE_BYTES)
     125  #define Stack_check_Usable_stack_start(_the_stack) \
     126      ((char *)(_the_stack)->area + SANITY_PATTERN_SIZE_BYTES)
    124127
    125128#endif
     
    129132 *  is too close.  This defines the usable stack memory.
    130133 */
    131 #define Stack_check_usable_stack_size(_the_stack) \
    132     ((_the_stack)->size - PATTERN_SIZE_BYTES)
     134#define Stack_check_Usable_stack_size(_the_stack) \
     135    ((_the_stack)->size - SANITY_PATTERN_SIZE_BYTES)
    133136
    134137#if defined(RTEMS_SMP)
     
    142145 *  to check for amount of actual stack used.
    143146 */
    144 #define Stack_check_Dope_stack(_stack) \
    145   memset((_stack)->area, BYTE_PATTERN, (_stack)->size)
    146 
    147 static bool Stack_check_Is_pattern_valid(const Thread_Control *the_thread)
     147static void Stack_check_Dope_stack( Stack_Control *stack )
     148{
     149  memset(
     150    Stack_check_Usable_stack_start( stack ),
     151    BYTE_PATTERN,
     152    Stack_check_Usable_stack_size( stack )
     153  );
     154}
     155
     156static void Stack_check_Add_sanity_pattern( Stack_Control *stack )
     157{
     158  memcpy(
     159    Stack_check_Get_pattern( stack ),
     160    Stack_check_Sanity_pattern,
     161    SANITY_PATTERN_SIZE_BYTES
     162  );
     163}
     164
     165static bool Stack_check_Is_sanity_pattern_valid( const Stack_Control *stack )
    148166{
    149167  return memcmp(
    150     Stack_check_Get_pattern(&the_thread->Start.Initial_stack),
    151     Stack_check_Pattern,
    152     PATTERN_SIZE_BYTES
     168    Stack_check_Get_pattern( stack ),
     169    Stack_check_Sanity_pattern,
     170    SANITY_PATTERN_SIZE_BYTES
    153171  ) == 0;
    154172}
     
    164182  Stack_check_Initialized = true;
    165183
    166   Stack_check_Dope_stack(&the_thread->Start.Initial_stack);
    167   memcpy(
    168     Stack_check_Get_pattern(&the_thread->Start.Initial_stack),
    169     Stack_check_Pattern,
    170     PATTERN_SIZE_BYTES
    171   );
     184  Stack_check_Dope_stack( &the_thread->Start.Initial_stack );
     185  Stack_check_Add_sanity_pattern( &the_thread->Start.Initial_stack );
    172186
    173187  return true;
     
    202216    stack->size = (size_t) ( (char *) cpu_self->interrupt_stack_high -
    203217      (char *) cpu_self->interrupt_stack_low );
     218
     219    /*
     220     * Sanity pattern has been added by Stack_check_Prepare_interrupt_stack()
     221     */
     222    if ( !Stack_check_Is_sanity_pattern_valid( stack ) ) {
     223      rtems_fatal(
     224        RTEMS_FATAL_SOURCE_STACK_CHECKER,
     225        rtems_build_name( 'I', 'N', 'T', 'R' )
     226      );
     227    }
     228
    204229    Stack_check_Dope_stack( stack );
    205230  }
     
    246271    printk(
    247272      "damaged pattern area (%lu Bytes): 0x%08" PRIxPTR " .. 0x%08" PRIxPTR "\n",
    248       (unsigned long) PATTERN_SIZE_BYTES,
     273      (unsigned long) SANITY_PATTERN_SIZE_BYTES,
    249274      (intptr_t) pattern_area,
    250       (intptr_t) (pattern_area + PATTERN_SIZE_BYTES)
     275      (intptr_t) (pattern_area + SANITY_PATTERN_SIZE_BYTES)
    251276    );
    252277  }
     
    277302  bool sp_ok;
    278303  bool pattern_ok;
     304  const Stack_Control *stack;
    279305
    280306  /*
     
    283309  sp_ok = Stack_check_Frame_pointer_in_range( running );
    284310
    285   pattern_ok = Stack_check_Is_pattern_valid( running );
     311  pattern_ok = Stack_check_Is_sanity_pattern_valid( &running->Start.Initial_stack );
    286312
    287313  if ( !sp_ok || !pattern_ok ) {
    288314    Stack_check_report_blown_task( running, pattern_ok );
     315  }
     316
     317  stack = &Stack_check_Interrupt_stack[ _SMP_Get_current_processor() ];
     318
     319  if ( stack->area != NULL && !Stack_check_Is_sanity_pattern_valid( stack ) ) {
     320    rtems_fatal(
     321      RTEMS_FATAL_SOURCE_STACK_CHECKER,
     322      rtems_build_name( 'I', 'N', 'T', 'R' )
     323    );
    289324  }
    290325}
     
    306341 * Stack_check_find_high_water_mark
    307342 */
    308 static inline void *Stack_check_find_high_water_mark(
     343static inline void *Stack_check_Find_high_water_mark(
    309344  const void *s,
    310345  size_t      n
     
    333368     */
    334369
    335     base += PATTERN_SIZE_WORDS;
     370    base += SANITY_PATTERN_SIZE_WORDS;
    336371    for (ebase = base + length; base < ebase; base++)
    337372      if (*base != U32_PATTERN)
     
    355390  void     *high_water_mark;
    356391
    357   low  = Stack_check_usable_stack_start(stack);
    358   size = Stack_check_usable_stack_size(stack);
    359 
    360   high_water_mark = Stack_check_find_high_water_mark(low, size);
     392  low  = Stack_check_Usable_stack_start(stack);
     393  size = Stack_check_Usable_stack_size(stack);
     394
     395  high_water_mark = Stack_check_Find_high_water_mark(low, size);
    361396
    362397  if ( high_water_mark )
     
    460495  rtems_stack_checker_report_usage_with_plugin( &printer );
    461496}
     497
     498static void Stack_check_Prepare_interrupt_stack( void )
     499{
     500  uint32_t      cpu_self_index;
     501  Stack_Control stack;
     502
     503  cpu_self_index = _SMP_Get_current_processor();
     504  stack.size = rtems_configuration_get_interrupt_stack_size();
     505  stack.area = _Addresses_Add_offset(
     506    _Configuration_Interrupt_stack_area_begin,
     507    cpu_self_index * stack.size
     508  );
     509  Stack_check_Add_sanity_pattern( &stack );
     510}
     511
     512RTEMS_SYSINIT_ITEM(
     513  Stack_check_Prepare_interrupt_stack,
     514  RTEMS_SYSINIT_BSP_WORK_AREAS,
     515  RTEMS_SYSINIT_ORDER_SECOND
     516);
Note: See TracChangeset for help on using the changeset viewer.