forked from Imagelibrary/rtems
score: Fix race condition in SMP startup
Do not use the Per_CPU_Control::started in _SMP_Start_multitasking_on_secondary_processor() since this field may be not up to date when a secondary processor reads it. Use the read-only scheduler assignment instead. Add a new fatal error SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR. This prevents out-of-bounds access. It is currently not possible to test these fatal errors. One option would be to fake values of the _CPU_SMP_Get_current_processor(), but unfortunately this function is inline on some architectures.
This commit is contained in:
@@ -60,7 +60,8 @@ typedef enum {
|
|||||||
SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
|
SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
|
||||||
SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
|
SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
|
||||||
SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED,
|
SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED,
|
||||||
SMP_FATAL_SHUTDOWN_RESPONSE
|
SMP_FATAL_SHUTDOWN_RESPONSE,
|
||||||
|
SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR
|
||||||
} SMP_Fatal_code;
|
} SMP_Fatal_code;
|
||||||
|
|
||||||
static inline void _SMP_Fatal( SMP_Fatal_code code )
|
static inline void _SMP_Fatal( SMP_Fatal_code code )
|
||||||
|
|||||||
@@ -121,8 +121,15 @@ void _SMP_Request_start_multitasking( void )
|
|||||||
void _SMP_Start_multitasking_on_secondary_processor( void )
|
void _SMP_Start_multitasking_on_secondary_processor( void )
|
||||||
{
|
{
|
||||||
Per_CPU_Control *self_cpu = _Per_CPU_Get();
|
Per_CPU_Control *self_cpu = _Per_CPU_Get();
|
||||||
|
uint32_t cpu_index_self = _Per_CPU_Get_index( self_cpu );
|
||||||
|
const Scheduler_Assignment *assignment =
|
||||||
|
_Scheduler_Get_assignment( cpu_index_self );
|
||||||
|
|
||||||
if ( !_Per_CPU_Is_processor_started( self_cpu ) ) {
|
if ( cpu_index_self >= rtems_configuration_get_maximum_processors() ) {
|
||||||
|
_SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !_Scheduler_Should_start_processor( assignment ) ) {
|
||||||
_SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR );
|
_SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ SUBDIRS += smpfatal02
|
|||||||
SUBDIRS += smpfatal03
|
SUBDIRS += smpfatal03
|
||||||
SUBDIRS += smpfatal04
|
SUBDIRS += smpfatal04
|
||||||
SUBDIRS += smpfatal05
|
SUBDIRS += smpfatal05
|
||||||
SUBDIRS += smpfatal07
|
|
||||||
SUBDIRS += smpfatal08
|
SUBDIRS += smpfatal08
|
||||||
SUBDIRS += smpipi01
|
SUBDIRS += smpipi01
|
||||||
SUBDIRS += smpload01
|
SUBDIRS += smpload01
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ smpfatal02/Makefile
|
|||||||
smpfatal03/Makefile
|
smpfatal03/Makefile
|
||||||
smpfatal04/Makefile
|
smpfatal04/Makefile
|
||||||
smpfatal05/Makefile
|
smpfatal05/Makefile
|
||||||
smpfatal07/Makefile
|
|
||||||
smpfatal08/Makefile
|
smpfatal08/Makefile
|
||||||
smpipi01/Makefile
|
smpipi01/Makefile
|
||||||
smpload01/Makefile
|
smpload01/Makefile
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
rtems_tests_PROGRAMS = smpfatal07
|
|
||||||
smpfatal07_SOURCES = init.c
|
|
||||||
|
|
||||||
dist_rtems_tests_DATA = smpfatal07.scn smpfatal07.doc
|
|
||||||
|
|
||||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
|
||||||
include $(top_srcdir)/../automake/compile.am
|
|
||||||
include $(top_srcdir)/../automake/leaf.am
|
|
||||||
|
|
||||||
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
|
||||||
|
|
||||||
LINK_OBJS = $(smpfatal07_OBJECTS)
|
|
||||||
LINK_LIBS = $(smpfatal07_LDLIBS)
|
|
||||||
|
|
||||||
smpfatal07$(EXEEXT): $(smpfatal07_OBJECTS) $(smpfatal07_DEPENDENCIES)
|
|
||||||
@rm -f smpfatal07$(EXEEXT)
|
|
||||||
$(make-exe)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../automake/local.am
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Dornierstr. 4
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.org/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/test.h>
|
|
||||||
#include <rtems/score/smpimpl.h>
|
|
||||||
#include <rtems/score/threadimpl.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
const char rtems_test_name[] = "SMPFATAL 7";
|
|
||||||
|
|
||||||
static void Init(rtems_task_argument arg)
|
|
||||||
{
|
|
||||||
Per_CPU_Control *cpu_self;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
cpu_self = _Per_CPU_Get();
|
|
||||||
cpu_self->started = false;
|
|
||||||
_SMP_Start_multitasking_on_secondary_processor();
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fatal_extension(
|
|
||||||
rtems_fatal_source source,
|
|
||||||
bool is_internal,
|
|
||||||
rtems_fatal_code code
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_test_begink();
|
|
||||||
|
|
||||||
if (
|
|
||||||
source == RTEMS_FATAL_SOURCE_SMP
|
|
||||||
&& !is_internal
|
|
||||||
&& code == SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR
|
|
||||||
) {
|
|
||||||
rtems_test_endk();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
|
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
|
||||||
|
|
||||||
#define CONFIGURE_INITIAL_EXTENSIONS \
|
|
||||||
{ .fatal = fatal_extension }, \
|
|
||||||
RTEMS_TEST_INITIAL_EXTENSION
|
|
||||||
|
|
||||||
#define CONFIGURE_SMP_APPLICATION
|
|
||||||
|
|
||||||
#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 1
|
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_TASKS 1
|
|
||||||
|
|
||||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
|
||||||
|
|
||||||
#include <rtems/confdefs.h>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
This file describes the directives and concepts tested by this test set.
|
|
||||||
|
|
||||||
test set name: smpfatal07
|
|
||||||
|
|
||||||
directives:
|
|
||||||
|
|
||||||
- _SMP_Start_multitasking_on_secondary_processor()
|
|
||||||
|
|
||||||
concepts:
|
|
||||||
|
|
||||||
- Ensure that a multitasking start on an unassigned processor leads to a
|
|
||||||
fatal error.
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
*** TEST SMPFATAL 7 ***
|
|
||||||
*** END OF TEST SMPFATAL 7 ***
|
|
||||||
Reference in New Issue
Block a user