Commit 191ce9d1 authored by Martin Schwidefsky's avatar Martin Schwidefsky

s390/time: fix clocksource steering for negative clock offsets

The TOD clock offset injected by an STP sync check can be negative.
If the resulting total tod_steering_delta gets negative the kernel
will panic.

Change the type of tod_steering_delta to a signed type.
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Fixes: 75c7b6f3 ("s390/time: steer clocksource on STP sync events")
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 68962269
...@@ -63,7 +63,7 @@ unsigned char ptff_function_mask[16]; ...@@ -63,7 +63,7 @@ unsigned char ptff_function_mask[16];
static unsigned long long lpar_offset; static unsigned long long lpar_offset;
static unsigned long long initial_leap_seconds; static unsigned long long initial_leap_seconds;
static unsigned long long tod_steering_end; static unsigned long long tod_steering_end;
static unsigned long long tod_steering_delta; static long long tod_steering_delta;
/* /*
* Get time offsets with PTFF * Get time offsets with PTFF
...@@ -223,8 +223,7 @@ static cycle_t read_tod_clock(struct clocksource *cs) ...@@ -223,8 +223,7 @@ static cycle_t read_tod_clock(struct clocksource *cs)
* therefore steered in ~9h. The adjust will decrease * therefore steered in ~9h. The adjust will decrease
* over time, until it finally reaches 0. * over time, until it finally reaches 0.
*/ */
now += ((s64) tod_steering_delta < 0) ? now += (tod_steering_delta < 0) ? (adj >> 15) : -(adj >> 15);
(adj >> 15) : -(adj >> 15);
preempt_enable(); preempt_enable();
return now; return now;
} }
...@@ -412,7 +411,7 @@ static void clock_sync_global(unsigned long long delta) ...@@ -412,7 +411,7 @@ static void clock_sync_global(unsigned long long delta)
adj = tod_steering_end - now; adj = tod_steering_end - now;
if (unlikely((s64) adj >= 0)) if (unlikely((s64) adj >= 0))
/* Calculate how much of the old adjustment is left. */ /* Calculate how much of the old adjustment is left. */
tod_steering_delta = ((s64) tod_steering_delta < 0) ? tod_steering_delta = (tod_steering_delta < 0) ?
-(adj >> 15) : (adj >> 15); -(adj >> 15) : (adj >> 15);
tod_steering_delta += delta; tod_steering_delta += delta;
if ((abs(tod_steering_delta) >> 48) != 0) if ((abs(tod_steering_delta) >> 48) != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment