Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9a3b33b authored by Vincenzo Frascino's avatar Vincenzo Frascino Committed by Sasha Levin
Browse files

s390/vdso: fix vDSO clock_getres()

[ Upstream commit 478237a595120a18e9b52fd2c57a6e8b7a01e411 ]

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: default avatarVincenzo Frascino <vincenzo.frascino@arm.com>
Acked-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
[heiko.carstens@de.ibm.com: use llgf for proper zero extension]
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 68a3cbc4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct vdso_data {
	__u32 tk_shift;			/* Shift used for xtime_nsec	0x60 */
	__u32 ts_dir;			/* TOD steering direction	0x64 */
	__u64 ts_end;			/* TOD steering end		0x68 */
	__u32 hrtimer_res;		/* hrtimer resolution		0x70 */
};

struct vdso_per_cpu_data {
+1 −1
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ int main(void)
	OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
	OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir);
	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_USER, vdso_per_cpu_data, ectg_user_time);
	OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
@@ -87,7 +88,6 @@ int main(void)
	DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
	DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
	DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
	DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
	DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
	BLANK();
	/* idle data offsets */
+1 −0
Original line number Diff line number Diff line
@@ -310,6 +310,7 @@ void update_vsyscall(struct timekeeper *tk)

	vdso_data->tk_mult = tk->tkr_mono.mult;
	vdso_data->tk_shift = tk->tkr_mono.shift;
	vdso_data->hrtimer_res = hrtimer_resolution;
	smp_wmb();
	++vdso_data->tb_update_count;
}
+5 −5
Original line number Diff line number Diff line
@@ -17,12 +17,14 @@
	.type  __kernel_clock_getres,@function
__kernel_clock_getres:
	CFI_STARTPROC
	larl	%r1,4f
	larl	%r1,3f
	lg	%r0,0(%r1)
	cghi	%r2,__CLOCK_REALTIME_COARSE
	je	0f
	cghi	%r2,__CLOCK_MONOTONIC_COARSE
	je	0f
	larl	%r1,3f
	larl	%r1,_vdso_data
	llgf	%r0,__VDSO_CLOCK_REALTIME_RES(%r1)
	cghi	%r2,__CLOCK_REALTIME
	je	0f
	cghi	%r2,__CLOCK_MONOTONIC
@@ -36,7 +38,6 @@ __kernel_clock_getres:
	jz	2f
0:	ltgr	%r3,%r3
	jz	1f				/* res == NULL */
	lg	%r0,0(%r1)
	xc	0(8,%r3),0(%r3)			/* set tp->tv_sec to zero */
	stg	%r0,8(%r3)			/* store tp->tv_usec */
1:	lghi	%r2,0
@@ -45,6 +46,5 @@ __kernel_clock_getres:
	svc	0
	br	%r14
	CFI_ENDPROC
3:	.quad	__CLOCK_REALTIME_RES
4:	.quad	__CLOCK_COARSE_RES
3:	.quad	__CLOCK_COARSE_RES
	.size	__kernel_clock_getres,.-__kernel_clock_getres