diff --git a/bsps/shared/start/bspfatal-default.c b/bsps/shared/start/bspfatal-default.c index 411cf1d81d..1c105fbd92 100644 --- a/bsps/shared/start/bspfatal-default.c +++ b/bsps/shared/start/bspfatal-default.c @@ -50,16 +50,6 @@ void bsp_fatal_extension( rtems_fatal_code code ) { - rtems_interrupt_level level; - - /* - * Make sure that interrupts don't interfere with the fatal error handling on - * this processor. This reduces the likelihood to end up in a recursive - * fatal error handling sequence. - */ - rtems_interrupt_local_disable( level ); - (void) level; - #if defined(RTEMS_SMP) if ( source == RTEMS_FATAL_SOURCE_SMP && diff --git a/cpukit/include/rtems/extension.h b/cpukit/include/rtems/extension.h index 46cf11d2e8..ea8e468a78 100644 --- a/cpukit/include/rtems/extension.h +++ b/cpukit/include/rtems/extension.h @@ -133,7 +133,8 @@ rtems_status_code rtems_extension_delete( rtems_id id ); * * @par Notes * @parblock - * The fatal extensions are invoked in extension forward order. + * The fatal extensions are invoked in extension forward order and with + * maskable interrupts disabled. * * The fatal extension should be extremely careful with respect to the RTEMS * directives it calls. Depending on the system termination source, the system diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c index b3105c6a4d..7fe2363c5f 100644 --- a/cpukit/score/src/interr.c +++ b/cpukit/score/src/interr.c @@ -55,6 +55,14 @@ void _Terminate( { ISR_Level level; + /* + * Make sure that interrupts don't interfere with the fatal error handling on + * this processor. This reduces the likelihood to end up in a recursive + * fatal error handling sequence. + */ + _ISR_Local_disable( level ); + (void) level; + _User_extensions_Fatal( the_source, the_error ); /* @@ -65,8 +73,6 @@ void _Terminate( * * The following code is only executed in badly configured applications. */ - _ISR_Local_disable( level ); - (void) level; _CPU_Thread_Idle_body( 0 ); } diff --git a/testsuites/validation/tc-score-fatal.c b/testsuites/validation/tc-score-fatal.c index caa869c31d..ac0e97a1f5 100644 --- a/testsuites/validation/tc-score-fatal.c +++ b/testsuites/validation/tc-score-fatal.c @@ -146,6 +146,7 @@ static void Fatal( ctx->source = source; ctx->code = code; _Atomic_Fetch_add_uint( &ctx->counter, 1, ATOMIC_ORDER_RELAXED ); + _ISR_Set_level( 0 ); } static void FatalTaskExit( diff --git a/testsuites/validation/tc-sem-smp.c b/testsuites/validation/tc-sem-smp.c index 5dc3f437a1..947d8373d6 100644 --- a/testsuites/validation/tc-sem-smp.c +++ b/testsuites/validation/tc-sem-smp.c @@ -163,6 +163,7 @@ static void BadEnqueueFatal( SetFatalHandler( NULL, NULL ); + _ISR_Set_level( 0 ); cpu_self = _Per_CPU_Get(); _Thread_Dispatch_unnest( cpu_self ); _Thread_Dispatch_unnest( cpu_self ); diff --git a/testsuites/validation/tc-task-delete.c b/testsuites/validation/tc-task-delete.c index d917062d0d..7efef67a05 100644 --- a/testsuites/validation/tc-task-delete.c +++ b/testsuites/validation/tc-task-delete.c @@ -654,6 +654,7 @@ static void Fatal( ctx = arg; ++ctx->calls.fatal; T_assert_eq_int( ctx->calls.fatal, 1 ); + _ISR_Set_level( 0 ); longjmp( ctx->thread_dispatch_context, 1 ); } @@ -670,6 +671,7 @@ static void ResumeThreadDispatch( ctx = arg; SetFatalHandler( Fatal, ctx ); + _ISR_Set_level( 0 ); longjmp( ctx->thread_dispatch_context, 1 ); } diff --git a/testsuites/validation/tc-task-exit.c b/testsuites/validation/tc-task-exit.c index 24373f6c47..46fff0aab9 100644 --- a/testsuites/validation/tc-task-exit.c +++ b/testsuites/validation/tc-task-exit.c @@ -390,6 +390,7 @@ static void Fatal( UnlockAllocator( ctx ); SuspendSelf(); + _ISR_Set_level( 0 ); cpu_self = _Per_CPU_Get(); _Thread_Dispatch_unnest( cpu_self ); _Thread_Dispatch_direct_no_return( cpu_self ); diff --git a/testsuites/validation/tc-task-restart.c b/testsuites/validation/tc-task-restart.c index c915f01a49..1987709048 100644 --- a/testsuites/validation/tc-task-restart.c +++ b/testsuites/validation/tc-task-restart.c @@ -720,6 +720,7 @@ static void Fatal( CaptureWorkerState( ctx ); + _ISR_Set_level( 0 ); cpu_self = _Per_CPU_Get(); _Thread_Dispatch_unnest( cpu_self ); _Thread_Dispatch_direct_no_return( cpu_self ); @@ -738,6 +739,7 @@ static void ResumeThreadDispatch( ctx = arg; SetFatalHandler( Fatal, ctx ); + _ISR_Set_level( 0 ); longjmp( ctx->thread_dispatch_context, 1 ); } diff --git a/testsuites/validation/tc-terminate.c b/testsuites/validation/tc-terminate.c index f26aae3e6d..2695bd2ec5 100644 --- a/testsuites/validation/tc-terminate.c +++ b/testsuites/validation/tc-terminate.c @@ -191,12 +191,16 @@ static void FatalExtension2( rtems_fatal_code code ) { - rtems_status_code sc; + rtems_status_code sc; + rtems_interrupt_level level; FatalExtension( source, always_set_to_false, code, 2 ); + _ISR_Set_level( 0 ); sc = rtems_extension_delete( extension_ids[ 3 ] ); T_quiet_rsc_success( sc ); + rtems_interrupt_local_disable( level ); + (void) level; } static void FatalExtension3( @@ -223,12 +227,16 @@ static void FatalExtension5( rtems_fatal_code code ) { - rtems_status_code sc; + rtems_status_code sc; + rtems_interrupt_level level; FatalExtension( source, always_set_to_false, code, 5 ); + _ISR_Set_level( 0 ); sc = rtems_extension_delete( extension_ids[ 5 ] ); T_quiet_rsc_success( sc ); + rtems_interrupt_local_disable( level ); + (void) level; } static void FatalExtension6( @@ -237,12 +245,16 @@ static void FatalExtension6( rtems_fatal_code code ) { - rtems_status_code sc; + rtems_status_code sc; + rtems_interrupt_level level; FatalExtension( source, always_set_to_false, code, 6 ); + _ISR_Set_level( 0 ); sc = rtems_extension_delete( extension_ids[ 4 ] ); T_quiet_rsc_success( sc ); + rtems_interrupt_local_disable( level ); + (void) level; } /** @@ -254,6 +266,7 @@ static void ScoreInterrValTerminate_Action_0( void ) { rtems_status_code sc; rtems_extensions_table table; + uint32_t test_case_isr_level; memset( &table, 0, sizeof( table ) ); @@ -297,6 +310,7 @@ static void ScoreInterrValTerminate_Action_0( void ) ); T_step_rsc_success( 4, sc ); + test_case_isr_level = _ISR_Get_level(); test_case_active = true; if ( setjmp( before_terminate ) == 0 ) { @@ -392,15 +406,16 @@ static void ScoreInterrValTerminate_Action_0( void ) * Check that maskable interrupts were enabled for the user extensions. Check * that the idle loop executes with maskable interrupts disabled. */ - T_step_eq_u32( 35, extension_isr_level, 0 ); - T_step_ne_u32( 36, idle_isr_level, 0 ); + T_step_eq_u32( 35, test_case_isr_level, 0 ); + T_step_ne_u32( 36, extension_isr_level, 0 ); + T_step_ne_u32( 37, idle_isr_level, 0 ); /* * Check that an idle loop executed after invocation of the user extensions. */ - T_step_eq_uint( 37, idle_counter, 7 ); + T_step_eq_uint( 38, idle_counter, 7 ); T_step_eq_uint( - 38, + 39, _Atomic_Load_uint( &counter, ATOMIC_ORDER_RELAXED ), 7 ); @@ -411,7 +426,7 @@ static void ScoreInterrValTerminate_Action_0( void ) */ T_TEST_CASE( ScoreInterrValTerminate ) { - T_plan( 39 ); + T_plan( 40 ); ScoreInterrValTerminate_Action_0(); } diff --git a/testsuites/validation/tx-thread-queue.c b/testsuites/validation/tx-thread-queue.c index ee9d2cf96d..dc823dee51 100644 --- a/testsuites/validation/tx-thread-queue.c +++ b/testsuites/validation/tx-thread-queue.c @@ -275,6 +275,7 @@ static void ThreadQueueDeadlock( T_eq_int( source, INTERNAL_ERROR_CORE ); T_eq_int( code, INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK ); SetFatalHandler( NULL, NULL ); + _ISR_Set_level( 0 ); longjmp( ctx->before_enqueue, 1 ); }