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: Dan Carpenter <dan.carpenter@oracle.com>
Fixes: 75c7b6f3f6
("s390/time: steer clocksource on STP sync events")
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
68962269a4
commit
191ce9d1fd
|
@ -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)
|
||||||
* 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)
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue