time: create __getnstimeofday for WARNless calls

The pstore RAM backend can get called during resume, and must be defensive
against a suspended time source. Expose getnstimeofday logic that returns
an error instead of a WARN. This can be detected and the timestamp can
be zeroed out.

Reported-by: Doug Anderson <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Anton Vorontsov <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: John Stultz <[email protected]>
This commit is contained in:
Kees Cook 2012-11-19 10:26:16 -08:00 • committed by John Stultz
commit 1e817fb62c
3 changed files with 32 additions and 8 deletions

View file

@ -214,19 +214,18 @@ static void timekeeping_forward_now(struct timekeeper *tk)
}
/**
* getnstimeofday - Returns the time of day in a timespec
* __getnstimeofday - Returns the time of day in a timespec.
* @ts: pointer to the timespec to be set
*
* Returns the time of day in a timespec.
* Updates the time of day in the timespec.
* Returns 0 on success, or -ve when suspended (timespec will be undefined).
*/
void getnstimeofday(struct timespec *ts)
int __getnstimeofday(struct timespec *ts)
{
struct timekeeper *tk = &timekeeper;
unsigned long seq;
s64 nsecs = 0;
WARN_ON(timekeeping_suspended);
do {
seq = read_seqbegin(&tk->lock);
@ -237,6 +236,26 @@ void getnstimeofday(struct timespec *ts)
ts->tv_nsec = 0;
timespec_add_ns(ts, nsecs);
/*
* Do not bail out early, in case there were callers still using
* the value, even in the face of the WARN_ON.
*/
if (unlikely(timekeeping_suspended))
return -EAGAIN;
return 0;
}
EXPORT_SYMBOL(__getnstimeofday);
/**
* getnstimeofday - Returns the time of day in a timespec.
* @ts: pointer to the timespec to be set
*
* Returns the time of day in a timespec (WARN if suspended).
*/
void getnstimeofday(struct timespec *ts)
{
WARN_ON(__getnstimeofday(ts));
}
EXPORT_SYMBOL(getnstimeofday);