Changeset 5248395 in rtems


Ignore:
Timestamp:
Mar 3, 2021, 8:23:20 AM (7 weeks ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
61d688bf
Parents:
1de00d6
git-author:
Sebastian Huber <sebastian.huber@…> (03/03/21 08:23:20)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/05/21 05:58:33)
Message:

score: Ensure stack alignment requirement

Make sure that a user-provided stack size is the minimum size allocated
for the stack.

Make sure we meet the stack alignment requirement also for CPU ports
with CPU_STACK_ALIGNMENT > CPU_HEAP_ALIGNMENT.

Location:
cpukit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/include/rtems/score/context.h

    r1de00d6 r5248395  
    5050#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    5151  #define CONTEXT_FP_SIZE \
    52     ( ( CPU_CONTEXT_FP_SIZE + CPU_HEAP_ALIGNMENT - 1 ) \
    53       & ~( CPU_HEAP_ALIGNMENT - 1 ) )
     52    RTEMS_ALIGN_UP( CPU_CONTEXT_FP_SIZE, CPU_STACK_ALIGNMENT )
    5453#else
    5554  #define CONTEXT_FP_SIZE 0
  • cpukit/include/rtems/score/stackimpl.h

    r1de00d6 r5248395  
    136136{
    137137  size_t extra_size;
     138  size_t alignment_overhead;
    138139
    139140  extra_size = _TLS_Get_allocation_size();
     
    148149#endif
    149150
    150   stack_size += extra_size;
    151 
    152   if ( stack_size < extra_size ) {
     151  /*
     152   * In order to make sure that a user-provided stack size is the minimum which
     153   * can be allocated for the stack, we have to align it up to the next stack
     154   * boundary.
     155   */
     156  alignment_overhead = CPU_STACK_ALIGNMENT - 1;
     157
     158#if CPU_STACK_ALIGNMENT > CPU_HEAP_ALIGNMENT
     159  /*
     160   * If the heap allocator does not meet the stack alignment requirement, then
     161   * we have to do the stack alignment manually in _Thread_Initialize() and
     162   * need to allocate extra space for this.
     163   */
     164  alignment_overhead += CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT;
     165#endif
     166
     167  if ( stack_size > SIZE_MAX - extra_size - alignment_overhead ) {
    153168    /*
    154169     * In case of an unsigned integer overflow, saturate at the maximum value.
    155170     */
    156     stack_size = SIZE_MAX;
     171    return SIZE_MAX;
    157172  }
     173
     174  stack_size += extra_size;
     175  stack_size = RTEMS_ALIGN_UP( stack_size, CPU_STACK_ALIGNMENT );
    158176
    159177  return stack_size;
  • cpukit/include/rtems/score/tls.h

    r1de00d6 r5248395  
    123123
    124124/**
    125  * @brief Returns the value aligned up to the heap alignment.
     125 * @brief Returns the value aligned up to the stack alignment.
    126126 *
    127127 * @param val The value to align.
    128128 *
    129  * @return The value aligned to the heap alignment.
    130  */
    131 static inline uintptr_t _TLS_Heap_align_up( uintptr_t val )
    132 {
    133   uintptr_t msk = CPU_HEAP_ALIGNMENT - 1;
    134 
    135   return (val + msk) & ~msk;
     129 * @return The value aligned to the stack alignment.
     130 */
     131static inline uintptr_t _TLS_Align_up( uintptr_t val )
     132{
     133  uintptr_t alignment = CPU_STACK_ALIGNMENT;
     134
     135  return RTEMS_ALIGN_UP( val, alignment );
    136136}
    137137
     
    230230    + _TLS_Get_thread_control_block_area_size( (uintptr_t) _TLS_Alignment );
    231231  TLS_Thread_control_block *tcb = tls_area;
    232   uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
     232  uintptr_t aligned_size = _TLS_Align_up( (uintptr_t) _TLS_Size );
    233233  TLS_Dynamic_thread_vector *dtv = (TLS_Dynamic_thread_vector *)
    234234    ((char *) tls_block + aligned_size);
     
    254254  TLS_Thread_control_block *tcb = (TLS_Thread_control_block *)
    255255    ((char *) tls_block - sizeof(*tcb));
    256   uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
     256  uintptr_t aligned_size = _TLS_Align_up( (uintptr_t) _TLS_Size );
    257257  TLS_Dynamic_thread_vector *dtv = (TLS_Dynamic_thread_vector *)
    258258    ((char *) tls_block + aligned_size);
     
    277277  uintptr_t tls_align = (uintptr_t) _TLS_Alignment;
    278278  uintptr_t tls_mask = tls_align - 1;
    279   uintptr_t heap_align = _TLS_Heap_align_up( tls_align );
     279  uintptr_t heap_align = _TLS_Align_up( tls_align );
    280280  uintptr_t heap_mask = heap_align - 1;
    281281  TLS_Thread_control_block *tcb = (TLS_Thread_control_block *)
  • cpukit/score/src/threadinitialize.c

    r1de00d6 r5248395  
    108108  char                    *stack_begin;
    109109  char                    *stack_end;
     110  uintptr_t                stack_align;
    110111  Scheduler_Node          *scheduler_node;
    111112#if defined(RTEMS_SMP)
     
    129130  }
    130131
     132  /* Set up the properly aligned stack area begin and end */
    131133  stack_begin = config->stack_area;
    132134  stack_end = stack_begin + config->stack_size;
     135  stack_align = CPU_STACK_ALIGNMENT;
     136  stack_begin = (char *) RTEMS_ALIGN_UP( (uintptr_t) stack_begin, stack_align );
     137  stack_end = (char *) RTEMS_ALIGN_DOWN( (uintptr_t) stack_end, stack_align );
    133138
    134139  /* Allocate floating-point context in stack area */
  • cpukit/score/src/tlsallocsize.c

    r1de00d6 r5248395  
    4949  uintptr_t size;
    5050  uintptr_t allocation_size;
    51   uintptr_t alignment;
    5251
    5352  size = _TLS_Get_size();
     
    6059
    6160  if ( allocation_size == 0 ) {
    62     allocation_size = _TLS_Heap_align_up( size );
    63     alignment = _TLS_Heap_align_up( (uintptr_t) _TLS_Alignment );
     61    uintptr_t alignment;
     62
     63    alignment = _TLS_Align_up( (uintptr_t) _TLS_Alignment );
     64
     65    allocation_size = size;
     66    allocation_size += _TLS_Get_thread_control_block_area_size( alignment );
     67#ifndef __i386__
     68    allocation_size += sizeof( TLS_Dynamic_thread_vector );
     69#endif
     70
     71    /*
     72     * The TLS area is allocated in the thread storage area.  Each allocation
     73     * shall meet the stack alignment requirement.
     74     */
     75    allocation_size = _TLS_Align_up( allocation_size );
    6476
    6577    /*
     
    6779     * enough to do the alignment manually.
    6880     */
    69     if ( alignment > CPU_HEAP_ALIGNMENT ) {
    70       allocation_size += alignment;
     81    if ( alignment > CPU_STACK_ALIGNMENT ) {
     82      _Assert( alignment % CPU_STACK_ALIGNMENT == 0 );
     83      allocation_size += alignment - CPU_STACK_ALIGNMENT;
    7184    }
    72 
    73     allocation_size += _TLS_Get_thread_control_block_area_size( alignment );
    74 
    75 #ifndef __i386__
    76     allocation_size += sizeof(TLS_Dynamic_thread_vector);
    77 #endif
    7885
    7986    if ( _Thread_Maximum_TLS_size != 0 ) {
    8087      if ( allocation_size <= _Thread_Maximum_TLS_size ) {
     88        _Assert( _Thread_Maximum_TLS_size % CPU_STACK_ALIGNMENT == 0 );
    8189        allocation_size = _Thread_Maximum_TLS_size;
    8290      } else {
Note: See TracChangeset for help on using the changeset viewer.