[PATCH 2/3] Add hook for BSP to act when time is set
Chris Johns
chrisj at rtems.org
Fri Oct 4 02:44:52 UTC 2019
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
More information about the devel
mailing list