mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-24 22:41:25 +00:00
powerpc: Fix time setting bug on 32-bit
This fixes a bug where settimeofday would set the wrong parameters in do_gtod, resulting in gettimeofday returning a value about 4 hours after the correct time. The bug was that we divided a negative 64-bit value with do_div, which treated it as unsigned and gave us a result that was approximately 1.8e10 too large (since the divisor was 1e9). Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
eb66ce6333
commit
5f6b5b973a
@ -518,7 +518,7 @@ int do_settimeofday(struct timespec *tv)
|
|||||||
long wtm_nsec, new_nsec = tv->tv_nsec;
|
long wtm_nsec, new_nsec = tv->tv_nsec;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
long int tb_delta;
|
long int tb_delta;
|
||||||
u64 new_xsec;
|
u64 new_xsec, tb_delta_xs;
|
||||||
|
|
||||||
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
|
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -541,8 +541,7 @@ int do_settimeofday(struct timespec *tv)
|
|||||||
#endif
|
#endif
|
||||||
tb_delta = tb_ticks_since(tb_last_stamp);
|
tb_delta = tb_ticks_since(tb_last_stamp);
|
||||||
tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
|
tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
|
||||||
|
tb_delta_xs = mulhdu(tb_delta, do_gtod.varp->tb_to_xs);
|
||||||
new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta);
|
|
||||||
|
|
||||||
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
|
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
|
||||||
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
|
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
|
||||||
@ -557,9 +556,12 @@ int do_settimeofday(struct timespec *tv)
|
|||||||
|
|
||||||
ntp_clear();
|
ntp_clear();
|
||||||
|
|
||||||
new_xsec = (u64)new_nsec * XSEC_PER_SEC;
|
new_xsec = 0;
|
||||||
do_div(new_xsec, NSEC_PER_SEC);
|
if (new_nsec != 0) {
|
||||||
new_xsec += (u64)new_sec * XSEC_PER_SEC;
|
new_xsec = (u64)new_nsec * XSEC_PER_SEC;
|
||||||
|
do_div(new_xsec, NSEC_PER_SEC);
|
||||||
|
}
|
||||||
|
new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs;
|
||||||
update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
|
update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
|
Loading…
x
Reference in New Issue
Block a user