[PATCH 2/3] Add hook for BSP to act when time is set

Joel Sherrill joel at rtems.org
Thu Oct 3 22:08:12 UTC 2019


This hook is only enabled when paravirtualized. It allows
the application running on RTEMS in a paravirtualized
environment to have its set time operations impact
the hosting environment. This requires support specific
to the paravirtualized environment. The hosting environment
may refuse to let the paravirtualized application set the
time and this is reflected to the application as a
permissions or not owner of resource issue.
---
 cpukit/headers.am                    |  1 +
 cpukit/include/rtems/score/tod.h     | 51 ++++++++++++++++++++++++++++++++++++
 cpukit/include/rtems/score/todimpl.h |  8 +++++-
 cpukit/posix/src/clocksettime.c      |  6 ++++-
 cpukit/rtems/src/clockset.c          |  6 ++++-
 cpukit/score/src/coretodadjust.c     |  2 +-
 cpukit/score/src/coretodset.c        | 15 ++++++++++-
 7 files changed, 84 insertions(+), 5 deletions(-)
 create mode 100644 cpukit/include/rtems/score/tod.h

diff --git a/cpukit/headers.am b/cpukit/headers.am
index 008b7cc..3386f77 100644
--- a/cpukit/headers.am
+++ b/cpukit/headers.am
@@ -399,6 +399,7 @@ include_rtems_score_HEADERS += include/rtems/score/timespec.h
 include_rtems_score_HEADERS += include/rtems/score/timestamp.h
 include_rtems_score_HEADERS += include/rtems/score/timestampimpl.h
 include_rtems_score_HEADERS += include/rtems/score/tls.h
+include_rtems_score_HEADERS += include/rtems/score/tod.h
 include_rtems_score_HEADERS += include/rtems/score/todimpl.h
 include_rtems_score_HEADERS += include/rtems/score/userext.h
 include_rtems_score_HEADERS += include/rtems/score/userextdata.h
diff --git a/cpukit/include/rtems/score/tod.h b/cpukit/include/rtems/score/tod.h
new file mode 100644
index 0000000..3b06642
--- /dev/null
+++ b/cpukit/include/rtems/score/tod.h
@@ -0,0 +1,51 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTOD
+ *
+ * @brief Time of Day Handler API
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2009.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  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.
+ */
+
+#ifndef _RTEMS_SCORE_TOD_H
+#define _RTEMS_SCORE_TOD_H
+
+#include <sys/timespec.h>
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(RTEMS_PARAVIRT)
+/**
+ * @brief Method Invoked When TOD is Set
+ *
+ * This method is invoked when the TOD is set. It can be overridden
+ * by the BSP to allow it to set the TOD in the host in a paravirtualized
+ * environment.
+ *
+ * @param tod points to the new TOD
+ *
+ * @note This is invoked with the TOD locked.
+ */
+bool _TOD_Set_hook(
+  const struct timespec *tod
+);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/todimpl.h b/cpukit/include/rtems/score/todimpl.h
index 0d4faac..25bb979 100644
--- a/cpukit/include/rtems/score/todimpl.h
+++ b/cpukit/include/rtems/score/todimpl.h
@@ -183,8 +183,14 @@ static inline void _TOD_Acquire( ISR_lock_Context *lock_context )
  * @param lock_context The ISR lock context used for the corresponding
  *   _TOD_Acquire().  The caller must be the owner of the TOD lock.  This
  *   function will release the TOD lock.
+ *
+ * @note This method currently always returns true in non-paravirtualized
+ *       configuration. In a paravirtualized envivonment, it may fail if
+ *       the container does not have permission to set the time.
+ *
+ * @return This method returns true if successful and false otherwise.
  */
-void _TOD_Set(
+bool _TOD_Set(
   const struct timespec *tod,
   ISR_lock_Context      *lock_context
 );
diff --git a/cpukit/posix/src/clocksettime.c b/cpukit/posix/src/clocksettime.c
index a0fdd91..387de4e 100644
--- a/cpukit/posix/src/clocksettime.c
+++ b/cpukit/posix/src/clocksettime.c
@@ -32,6 +32,8 @@ int clock_settime(
   const struct timespec *tp
 )
 {
+  bool rc;
+
   if ( !tp )
     rtems_set_errno_and_return_minus_one( EINVAL );
 
@@ -43,8 +45,10 @@ int clock_settime(
 
     _TOD_Lock();
     _TOD_Acquire( &lock_context );
-    _TOD_Set( tp, &lock_context );
+    rc = _TOD_Set( tp, &lock_context );
     _TOD_Unlock();
+    if (rc == false)
+      rtems_set_errno_and_return_minus_one( EPERM );
   }
 #ifdef _POSIX_CPUTIME
   else if ( clock_id == CLOCK_PROCESS_CPUTIME_ID )
diff --git a/cpukit/rtems/src/clockset.c b/cpukit/rtems/src/clockset.c
index d772682..9acb8d7 100644
--- a/cpukit/rtems/src/clockset.c
+++ b/cpukit/rtems/src/clockset.c
@@ -26,6 +26,8 @@ rtems_status_code rtems_clock_set(
   const rtems_time_of_day *tod
 )
 {
+  bool rc;
+
   if ( !tod )
     return RTEMS_INVALID_ADDRESS;
 
@@ -39,8 +41,10 @@ rtems_status_code rtems_clock_set(
 
     _TOD_Lock();
     _TOD_Acquire( &lock_context );
-    _TOD_Set( &tod_as_timespec, &lock_context );
+    rc = _TOD_Set( &tod_as_timespec, &lock_context );
     _TOD_Unlock();
+    if (rc == false)
+      return RTEMS_NOT_OWNER_OF_RESOURCE;
 
     return RTEMS_SUCCESSFUL;
   }
diff --git a/cpukit/score/src/coretodadjust.c b/cpukit/score/src/coretodadjust.c
index accb99b..b420c85 100644
--- a/cpukit/score/src/coretodadjust.c
+++ b/cpukit/score/src/coretodadjust.c
@@ -39,6 +39,6 @@ void _TOD_Adjust(
   _TOD_Acquire( &lock_context );
   _TOD_Get( &tod );
   _Timespec_Add_to( &tod, delta );
-  _TOD_Set( &tod, &lock_context );
+  (void) _TOD_Set( &tod, &lock_context );
   _TOD_Unlock();
 }
diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c
index b021a58..95bf162 100644
--- a/cpukit/score/src/coretodset.c
+++ b/cpukit/score/src/coretodset.c
@@ -22,7 +22,7 @@
 #include <rtems/score/assert.h>
 #include <rtems/score/watchdogimpl.h>
 
-void _TOD_Set(
+bool _TOD_Set(
   const struct timespec *tod,
   ISR_lock_Context      *lock_context
 )
@@ -35,6 +35,18 @@ void _TOD_Set(
   _Assert( _TOD_Is_owner() );
 
   timespec2bintime( tod, &tod_as_bintime );
+
+#if defined(RTEMS_PARAVIRT)
+  /*
+   * If in a paravirtualized environment, attempt to set the TOD in
+   * the hosting environment. This may fail due to a permission error
+   * if this guest is not allowed to set the TOD.
+   */
+  if (_TOD_Set_hook( tod ) == false) {
+    return false;
+  }
+#endif
+
   _Timecounter_Set_clock( &tod_as_bintime, lock_context );
 
   tod_as_ticks = _Watchdog_Ticks_from_timespec( tod );
@@ -67,4 +79,5 @@ void _TOD_Set(
   }
 
   _TOD.is_set = true;
+  return true;
 }
-- 
1.8.3.1



More information about the devel mailing list