Commit 157a1a27 authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Martin Schwidefsky

[S390] vdso: use ntp adjusted clock multiplier

Commit "timekeeping: Fix clock_gettime vsyscall time warp" (0696b711)
introduced the new parameter "mult" to update_vsyscall(). This parameter
contains the internal NTP adjusted clock multiplier.

The s390x vdso did not use this adjusted multiplier.  Instead, it used
the constant clock multiplier for gettimeofday() and clock_gettime()
variants.  This may result in observable time warps as explained in
commit 0696b711.

Make the NTP adjusted clock multiplier available to the s390x vdso
implementation and use it for time calculations.

Cc: <stable@kernel.org>
Signed-off-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 8821d24c
...@@ -29,6 +29,7 @@ struct vdso_data { ...@@ -29,6 +29,7 @@ struct vdso_data {
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */ __u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
__u32 tz_dsttime; /* Type of dst correction 0x34 */ __u32 tz_dsttime; /* Type of dst correction 0x34 */
__u32 ectg_available; __u32 ectg_available;
__u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
}; };
struct vdso_per_cpu_data { struct vdso_per_cpu_data {
......
...@@ -61,6 +61,7 @@ int main(void) ...@@ -61,6 +61,7 @@ int main(void)
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available)); DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base)); DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time)); DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
/* constants used by the vdso */ /* constants used by the vdso */
......
...@@ -221,6 +221,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, ...@@ -221,6 +221,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
vdso_data->xtime_clock_nsec = wall_time->tv_nsec; vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
vdso_data->ntp_mult = mult;
smp_wmb(); smp_wmb();
++vdso_data->tb_update_count; ++vdso_data->tb_update_count;
} }
......
...@@ -38,13 +38,13 @@ __kernel_clock_gettime: ...@@ -38,13 +38,13 @@ __kernel_clock_gettime:
sl %r1,__VDSO_XTIME_STAMP+4(%r5) sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,2f brc 3,2f
ahi %r0,-1 ahi %r0,-1
2: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */ 2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
lr %r2,%r0 lr %r2,%r0
lhi %r0,1000 l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1 ltr %r1,%r1
mr %r0,%r0 mr %r0,%r0
jnm 3f jnm 3f
ahi %r0,1000 a %r0,__VDSO_NTP_MULT(%r5)
3: alr %r0,%r2 3: alr %r0,%r2
srdl %r0,12 srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
...@@ -86,13 +86,13 @@ __kernel_clock_gettime: ...@@ -86,13 +86,13 @@ __kernel_clock_gettime:
sl %r1,__VDSO_XTIME_STAMP+4(%r5) sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,12f brc 3,12f
ahi %r0,-1 ahi %r0,-1
12: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */ 12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
lr %r2,%r0 lr %r2,%r0
lhi %r0,1000 l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1 ltr %r1,%r1
mr %r0,%r0 mr %r0,%r0
jnm 13f jnm 13f
ahi %r0,1000 a %r0,__VDSO_NTP_MULT(%r5)
13: alr %r0,%r2 13: alr %r0,%r2
srdl %r0,12 srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
......
...@@ -35,13 +35,13 @@ __kernel_gettimeofday: ...@@ -35,13 +35,13 @@ __kernel_gettimeofday:
sl %r1,__VDSO_XTIME_STAMP+4(%r5) sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,3f brc 3,3f
ahi %r0,-1 ahi %r0,-1
3: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */ 3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
st %r0,24(%r15) st %r0,24(%r15)
lhi %r0,1000 l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1 ltr %r1,%r1
mr %r0,%r0 mr %r0,%r0
jnm 4f jnm 4f
ahi %r0,1000 a %r0,__VDSO_NTP_MULT(%r5)
4: al %r0,24(%r15) 4: al %r0,24(%r15)
srdl %r0,12 srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
......
...@@ -36,7 +36,7 @@ __kernel_clock_gettime: ...@@ -36,7 +36,7 @@ __kernel_clock_gettime:
stck 48(%r15) /* Store TOD clock */ stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15) lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
mghi %r1,1000 msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
lg %r0,__VDSO_XTIME_SEC(%r5) lg %r0,__VDSO_XTIME_SEC(%r5)
...@@ -64,7 +64,7 @@ __kernel_clock_gettime: ...@@ -64,7 +64,7 @@ __kernel_clock_gettime:
stck 48(%r15) /* Store TOD clock */ stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15) lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
mghi %r1,1000 msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
lg %r0,__VDSO_XTIME_SEC(%r5) lg %r0,__VDSO_XTIME_SEC(%r5)
......
...@@ -31,7 +31,7 @@ __kernel_gettimeofday: ...@@ -31,7 +31,7 @@ __kernel_gettimeofday:
stck 48(%r15) /* Store TOD clock */ stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15) lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
mghi %r1,1000 msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */ lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
......
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