[PATCH v2 2/4] rtems: New errors for rtems_signal_catch()

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Feb 19 09:40:36 UTC 2021


Ensure that no invalid modes are set during ASR processing.

Update #4244.
---
 cpukit/include/rtems/rtems/modesimpl.h | 48 ++++++++++++++++++++++++++
 cpukit/rtems/src/signalcatch.c         | 15 ++++++++
 cpukit/rtems/src/taskmode.c            | 14 +++-----
 3 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/cpukit/include/rtems/rtems/modesimpl.h b/cpukit/include/rtems/rtems/modesimpl.h
index 2b5e00f600..fe7f5e5721 100644
--- a/cpukit/include/rtems/rtems/modesimpl.h
+++ b/cpukit/include/rtems/rtems/modesimpl.h
@@ -19,6 +19,9 @@
 #define _RTEMS_RTEMS_MODESIMPL_H
 
 #include <rtems/rtems/modes.h>
+#include <rtems/score/schedulerimpl.h>
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/threadimpl.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -85,6 +88,51 @@ RTEMS_INLINE_ROUTINE ISR_Level _Modes_Get_interrupt_level (
   return ( mode_set & RTEMS_INTERRUPT_MASK );
 }
 
+#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+/**
+ * @brief Checks if support for the interrupt level is implemented.
+ *
+ * @param mode_set is the most set which specifies the interrupt level to
+ *   check.
+ *
+ * @return Returns true, if support for the interrupt level is implemented,
+ *   otherwise returns false.
+ */
+RTEMS_INLINE_ROUTINE bool _Modes_Is_interrupt_level_implemented(
+  rtems_mode mode_set
+)
+{
+  return _Modes_Get_interrupt_level( mode_set ) == 0
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+    || !_SMP_Need_inter_processor_interrupts()
+#endif
+    ;
+}
+#endif
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Checks if support for the preempt mode is implemented.
+ *
+ * @param mode_set is the most set which specifies the preempt mode to check.
+ *
+ * @param the_thread is the thread to check.
+ *
+ * @return Returns true, if support for the preempt mode is implemented,
+ *   otherwise returns false.
+ */
+RTEMS_INLINE_ROUTINE bool _Modes_Is_preempt_mode_implemented(
+  rtems_mode            mode_set,
+  const Thread_Control *the_thread
+)
+{
+  return _Modes_Is_preempt( mode_set ) ||
+    _Scheduler_Is_non_preempt_mode_supported(
+      _Thread_Scheduler_get_home( the_thread )
+    );
+}
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c
index 8ee22e5ec1..55dc7de667 100644
--- a/cpukit/rtems/src/signalcatch.c
+++ b/cpukit/rtems/src/signalcatch.c
@@ -22,6 +22,7 @@
 #endif
 
 #include <rtems/rtems/signalimpl.h>
+#include <rtems/rtems/modesimpl.h>
 #include <rtems/rtems/tasksdata.h>
 #include <rtems/score/threadimpl.h>
 
@@ -37,7 +38,21 @@ rtems_status_code rtems_signal_catch(
   ASR_Information    *asr;
   ISR_lock_Context    lock_context;
 
+#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+  if ( !_Modes_Is_interrupt_level_implemented( mode_set ) ) {
+    return RTEMS_NOT_IMPLEMENTED;
+  }
+#endif
+
   executing = _Thread_State_acquire_for_executing( &lock_context );
+
+#if defined(RTEMS_SMP)
+  if ( !_Modes_Is_preempt_mode_implemented( mode_set, executing ) ) {
+    _Thread_State_release( executing, &lock_context );
+    return RTEMS_NOT_IMPLEMENTED;
+  }
+#endif
+
   api = executing->API_Extensions[ THREAD_API_RTEMS ];
   asr = &api->Signal;
   asr->handler = asr_handler;
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
index 77338723b8..1275576968 100644
--- a/cpukit/rtems/src/taskmode.c
+++ b/cpukit/rtems/src/taskmode.c
@@ -50,11 +50,8 @@ rtems_status_code rtems_task_mode(
 
 #if defined(RTEMS_SMP)
   if (
-    ( mask & RTEMS_PREEMPT_MASK ) != 0
-      && !_Modes_Is_preempt( mode_set )
-      && !_Scheduler_Is_non_preempt_mode_supported(
-        _Thread_Scheduler_get_home( executing )
-      )
+    ( mask & RTEMS_PREEMPT_MASK ) != 0 &&
+    !_Modes_Is_preempt_mode_implemented( mode_set, executing )
   ) {
     return RTEMS_NOT_IMPLEMENTED;
   }
@@ -62,11 +59,8 @@ rtems_status_code rtems_task_mode(
 
 #if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
   if (
-    ( mask & RTEMS_INTERRUPT_MASK ) != 0
-      && _Modes_Get_interrupt_level( mode_set ) != 0
-#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
-      && _SMP_Need_inter_processor_interrupts()
-#endif
+    ( mask & RTEMS_INTERRUPT_MASK ) != 0 &&
+    !_Modes_Is_interrupt_level_implemented( mode_set )
   ) {
     return RTEMS_NOT_IMPLEMENTED;
   }
-- 
2.26.2



More information about the devel mailing list