diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2021-02-08 18:06:10 +0300 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2021-02-13 19:17:54 +0300 |
commit | f8d8977a3d971011ab04e4569a664628bd03935e (patch) | |
tree | 397a45a6eb3bd3534e944e826d75d8b62dfe1575 /arch/s390/include/asm/timex.h | |
parent | cc2c7db28f7924e9133adc06293a74838ddee59a (diff) | |
download | linux-f8d8977a3d971011ab04e4569a664628bd03935e.tar.xz |
s390/time: convert tod_clock_base to union
Convert tod_clock_base to union tod_clock. This simplifies quite a bit
of code and also fixes a bug in read_persistent_clock64();
void read_persistent_clock64(struct timespec64 *ts)
{
__u64 delta;
delta = initial_leap_seconds + TOD_UNIX_EPOCH;
get_tod_clock_ext(clk);
*(__u64 *) &clk[1] -= delta;
if (*(__u64 *) &clk[1] > delta)
clk[0]--;
ext_to_timespec64(clk, ts);
}
Assume &clk[1] == 3 and delta == 2; then after the substraction the if
condition becomes true and the epoch part of the clock is decremented
by one because of an assumed overflow, even though there is none.
Fix this by using 128 bit arithmetics and let the compiler do the
right thing:
void read_persistent_clock64(struct timespec64 *ts)
{
union tod_clock clk;
u64 delta;
delta = initial_leap_seconds + TOD_UNIX_EPOCH;
store_tod_clock_ext(&clk);
clk.eitod -= delta;
ext_to_timespec64(&clk, ts);
}
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/include/asm/timex.h')
-rw-r--r-- | arch/s390/include/asm/timex.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index 7bfdcae34515..dbd7b44bc9da 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -208,7 +208,7 @@ static inline cycles_t get_cycles(void) int get_phys_clock(unsigned long *clock); void init_cpu_timer(void); -extern unsigned char tod_clock_base[16] __aligned(8); +extern union tod_clock tod_clock_base; /** * get_clock_monotonic - returns current time in clock rate units @@ -222,7 +222,7 @@ static inline unsigned long long get_tod_clock_monotonic(void) unsigned long long tod; preempt_disable_notrace(); - tod = get_tod_clock() - *(unsigned long long *) &tod_clock_base[1]; + tod = get_tod_clock() - tod_clock_base.tod; preempt_enable_notrace(); return tod; } |