On 4/10/19 8:08 am, Joel Sherrill wrote: > 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
How is it overridden? > 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( I initially read this as setting the "hook" and not the "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( Why bool? Would returning an `int` let the BSP determine the error code returned? > 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 ); ie is this the only error that can ever be returned for type of call? What about EIO, EACCES, EINVAL, etc. > } > #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 Is this only useful for virtual BSPs and is it always a requirement to implement this call in those environments? Would this call be useful to a non-virtual BSP, for example one with a battery backed RTC device? Would a hook API along the lines of .... typedef int (*_TOD_Set_Handler)(const struct timespec *tod); _TOD_Set_Handler _TOD_Set_hook(_TOD_Set_Handler handler); ... be more flexible? Chris _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel