Commit 79c74ecb authored by Martin Schwidefsky's avatar Martin Schwidefsky

s390/time,vdso: convert to the new update_vsyscall interface

Switch to the improved update_vsyscall interface that provides
sub-nanosecond precision for gettimeofday and clock_gettime.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 71a86ef0
...@@ -101,7 +101,7 @@ config S390 ...@@ -101,7 +101,7 @@ config S390
select GENERIC_CPU_DEVICES if !SMP select GENERIC_CPU_DEVICES if !SMP
select GENERIC_FIND_FIRST_BIT select GENERIC_FIND_FIRST_BIT
select GENERIC_SMP_IDLE_THREAD select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL_OLD select GENERIC_TIME_VSYSCALL
select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SECCOMP_FILTER
......
...@@ -26,8 +26,9 @@ struct vdso_data { ...@@ -26,8 +26,9 @@ struct vdso_data {
__u64 wtom_clock_nsec; /* 0x28 */ __u64 wtom_clock_nsec; /* 0x28 */
__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; /* ECTG instruction present 0x38 */
__u32 ntp_mult; /* NTP adjusted multiplier 0x3C */ __u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */
__u32 tk_shift; /* Shift used for xtime_nsec 0x40 */
}; };
struct vdso_per_cpu_data { struct vdso_per_cpu_data {
......
...@@ -65,7 +65,8 @@ int main(void) ...@@ -65,7 +65,8 @@ 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_TK_MULT, offsetof(struct vdso_data, tk_mult));
DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift));
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,21 +221,30 @@ struct clocksource * __init clocksource_default_clock(void) ...@@ -221,21 +221,30 @@ struct clocksource * __init clocksource_default_clock(void)
return &clocksource_tod; return &clocksource_tod;
} }
void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm, void update_vsyscall(struct timekeeper *tk)
struct clocksource *clock, u32 mult)
{ {
if (clock != &clocksource_tod) u64 nsecps;
if (tk->clock != &clocksource_tod)
return; return;
/* Make userspace gettimeofday spin until we're done. */ /* Make userspace gettimeofday spin until we're done. */
++vdso_data->tb_update_count; ++vdso_data->tb_update_count;
smp_wmb(); smp_wmb();
vdso_data->xtime_tod_stamp = clock->cycle_last; vdso_data->xtime_tod_stamp = tk->clock->cycle_last;
vdso_data->xtime_clock_sec = wall_time->tv_sec; vdso_data->xtime_clock_sec = tk->xtime_sec;
vdso_data->xtime_clock_nsec = wall_time->tv_nsec; vdso_data->xtime_clock_nsec = tk->xtime_nsec;
vdso_data->wtom_clock_sec = wtm->tv_sec; vdso_data->wtom_clock_sec =
vdso_data->wtom_clock_nsec = wtm->tv_nsec; tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
vdso_data->ntp_mult = mult; vdso_data->wtom_clock_nsec = tk->xtime_nsec +
+ (tk->wall_to_monotonic.tv_nsec << tk->shift);
nsecps = (u64) NSEC_PER_SEC << tk->shift;
while (vdso_data->wtom_clock_nsec >= nsecps) {
vdso_data->wtom_clock_nsec -= nsecps;
vdso_data->wtom_clock_sec++;
}
vdso_data->tk_mult = tk->mult;
vdso_data->tk_shift = tk->shift;
smp_wmb(); smp_wmb();
++vdso_data->tb_update_count; ++vdso_data->tb_update_count;
} }
......
...@@ -38,25 +38,26 @@ __kernel_clock_gettime: ...@@ -38,25 +38,26 @@ __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: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */ 2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
lr %r2,%r0 lr %r2,%r0
l %r0,__VDSO_NTP_MULT(%r5) l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1 ltr %r1,%r1
mr %r0,%r0 mr %r0,%r0
jnm 3f jnm 3f
a %r0,__VDSO_NTP_MULT(%r5) a %r0,__VDSO_TK_MULT(%r5)
3: alr %r0,%r2 3: alr %r0,%r2
srdl %r0,12 al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
al %r1,__VDSO_XTIME_NSEC+4(%r5) al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,4f brc 12,4f
ahi %r0,1 ahi %r0,1
4: l %r2,__VDSO_XTIME_SEC+4(%r5) 4: al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
al %r1,__VDSO_WTOM_NSEC+4(%r5) al %r1,__VDSO_WTOM_NSEC+4(%r5)
brc 12,5f brc 12,5f
ahi %r0,1 ahi %r0,1
5: al %r2,__VDSO_WTOM_SEC+4(%r5) 5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
srdl %r0,0(%r2) /* >> tk->shift */
l %r2,__VDSO_XTIME_SEC+4(%r5)
al %r2,__VDSO_WTOM_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 1b jne 1b
basr %r5,0 basr %r5,0
...@@ -86,20 +87,21 @@ __kernel_clock_gettime: ...@@ -86,20 +87,21 @@ __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: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */ 12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
lr %r2,%r0 lr %r2,%r0
l %r0,__VDSO_NTP_MULT(%r5) l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1 ltr %r1,%r1
mr %r0,%r0 mr %r0,%r0
jnm 13f jnm 13f
a %r0,__VDSO_NTP_MULT(%r5) a %r0,__VDSO_TK_MULT(%r5)
13: alr %r0,%r2 13: alr %r0,%r2
srdl %r0,12 al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
al %r1,__VDSO_XTIME_NSEC+4(%r5) al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,14f brc 12,14f
ahi %r0,1 ahi %r0,1
14: l %r2,__VDSO_XTIME_SEC+4(%r5) 14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
srdl %r0,0(%r2) /* >> tk->shift */
l %r2,__VDSO_XTIME_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 11b jne 11b
basr %r5,0 basr %r5,0
......
...@@ -35,15 +35,14 @@ __kernel_gettimeofday: ...@@ -35,15 +35,14 @@ __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: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */ 3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
st %r0,24(%r15) st %r0,24(%r15)
l %r0,__VDSO_NTP_MULT(%r5) l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1 ltr %r1,%r1
mr %r0,%r0 mr %r0,%r0
jnm 4f jnm 4f
a %r0,__VDSO_NTP_MULT(%r5) a %r0,__VDSO_TK_MULT(%r5)
4: al %r0,24(%r15) 4: al %r0,24(%r15)
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
al %r1,__VDSO_XTIME_NSEC+4(%r5) al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,5f brc 12,5f
...@@ -51,6 +50,8 @@ __kernel_gettimeofday: ...@@ -51,6 +50,8 @@ __kernel_gettimeofday:
5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5) 5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 1b jne 1b
l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
srdl %r0,0(%r4) /* >> tk->shift */
l %r4,24(%r15) /* get tv_sec from stack */ l %r4,24(%r15) /* get tv_sec from stack */
basr %r5,0 basr %r5,0
6: ltr %r0,%r0 6: ltr %r0,%r0
......
...@@ -34,14 +34,15 @@ __kernel_clock_gettime: ...@@ -34,14 +34,15 @@ __kernel_clock_gettime:
tmll %r4,0x0001 /* pending update ? loop */ tmll %r4,0x0001 /* pending update ? loop */
jnz 0b jnz 0b
stck 48(%r15) /* Store TOD clock */ stck 48(%r15) /* Store TOD clock */
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
alg %r0,__VDSO_WTOM_SEC(%r5) /* + wall_to_monotonic.sec */
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 */
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
lg %r0,__VDSO_XTIME_SEC(%r5) srlg %r1,%r1,0(%r2) /* >> tk->shift */
alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
alg %r0,__VDSO_WTOM_SEC(%r5)
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
jne 0b jne 0b
larl %r5,13f larl %r5,13f
...@@ -62,12 +63,13 @@ __kernel_clock_gettime: ...@@ -62,12 +63,13 @@ __kernel_clock_gettime:
tmll %r4,0x0001 /* pending update ? loop */ tmll %r4,0x0001 /* pending update ? loop */
jnz 5b jnz 5b
stck 48(%r15) /* Store TOD clock */ stck 48(%r15) /* Store TOD clock */
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
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 */
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ srlg %r1,%r1,0(%r2) /* >> tk->shift */
lg %r0,__VDSO_XTIME_SEC(%r5) lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
jne 5b jne 5b
larl %r5,13f larl %r5,13f
......
...@@ -31,12 +31,13 @@ __kernel_gettimeofday: ...@@ -31,12 +31,13 @@ __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 */
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */ lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
jne 0b jne 0b
lgf %r5,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
srlg %r1,%r1,0(%r5) /* >> tk->shift */
larl %r5,5f larl %r5,5f
2: clg %r1,0(%r5) 2: clg %r1,0(%r5)
jl 3f jl 3f
......
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