s390/vdso: fix vDSO clock_getres()

clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().

In particular, posix_get_hrtimer_res() does:
    sec = 0;
    ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.

Fix the s390 vdso implementation of clock_getres keeping a copy of
hrtimer_resolution in vdso data and using that directly.

Link: https://lkml.kernel.org/r/20200324121027.21665-1-vincenzo.frascino@arm.com
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
[heiko.carstens@de.ibm.com: use llgf for proper zero extension]
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Vincenzo Frascino 2020-03-24 12:10:27 +00:00 committed by Vasily Gorbik
parent 2b2a25845d
commit 478237a595
4 changed files with 8 additions and 6 deletions

View File

@ -36,6 +36,7 @@ struct vdso_data {
__u32 tk_shift; /* Shift used for xtime_nsec 0x60 */ __u32 tk_shift; /* Shift used for xtime_nsec 0x60 */
__u32 ts_dir; /* TOD steering direction 0x64 */ __u32 ts_dir; /* TOD steering direction 0x64 */
__u64 ts_end; /* TOD steering end 0x68 */ __u64 ts_end; /* TOD steering end 0x68 */
__u32 hrtimer_res; /* hrtimer resolution 0x70 */
}; };
struct vdso_per_cpu_data { struct vdso_per_cpu_data {

View File

@ -76,6 +76,7 @@ int main(void)
OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir); OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir);
OFFSET(__VDSO_TS_END, vdso_data, ts_end); OFFSET(__VDSO_TS_END, vdso_data, ts_end);
OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res);
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val);
@ -86,7 +87,6 @@ int main(void)
DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID); DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC); DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
BLANK(); BLANK();
/* idle data offsets */ /* idle data offsets */

View File

@ -301,6 +301,7 @@ void update_vsyscall(struct timekeeper *tk)
vdso_data->tk_mult = tk->tkr_mono.mult; vdso_data->tk_mult = tk->tkr_mono.mult;
vdso_data->tk_shift = tk->tkr_mono.shift; vdso_data->tk_shift = tk->tkr_mono.shift;
vdso_data->hrtimer_res = hrtimer_resolution;
smp_wmb(); smp_wmb();
++vdso_data->tb_update_count; ++vdso_data->tb_update_count;
} }

View File

@ -17,12 +17,14 @@
.type __kernel_clock_getres,@function .type __kernel_clock_getres,@function
__kernel_clock_getres: __kernel_clock_getres:
CFI_STARTPROC CFI_STARTPROC
larl %r1,4f larl %r1,3f
lg %r0,0(%r1)
cghi %r2,__CLOCK_REALTIME_COARSE cghi %r2,__CLOCK_REALTIME_COARSE
je 0f je 0f
cghi %r2,__CLOCK_MONOTONIC_COARSE cghi %r2,__CLOCK_MONOTONIC_COARSE
je 0f je 0f
larl %r1,3f larl %r1,_vdso_data
llgf %r0,__VDSO_CLOCK_REALTIME_RES(%r1)
cghi %r2,__CLOCK_REALTIME cghi %r2,__CLOCK_REALTIME
je 0f je 0f
cghi %r2,__CLOCK_MONOTONIC cghi %r2,__CLOCK_MONOTONIC
@ -36,7 +38,6 @@ __kernel_clock_getres:
jz 2f jz 2f
0: ltgr %r3,%r3 0: ltgr %r3,%r3
jz 1f /* res == NULL */ jz 1f /* res == NULL */
lg %r0,0(%r1)
xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */ xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */
stg %r0,8(%r3) /* store tp->tv_usec */ stg %r0,8(%r3) /* store tp->tv_usec */
1: lghi %r2,0 1: lghi %r2,0
@ -45,6 +46,5 @@ __kernel_clock_getres:
svc 0 svc 0
br %r14 br %r14
CFI_ENDPROC CFI_ENDPROC
3: .quad __CLOCK_REALTIME_RES 3: .quad __CLOCK_COARSE_RES
4: .quad __CLOCK_COARSE_RES
.size __kernel_clock_getres,.-__kernel_clock_getres .size __kernel_clock_getres,.-__kernel_clock_getres