Re: [PATCH] mips: Fix gettimeofday() in the vdso library

From: H. Nikolaus Schaller
Date: Fri Nov 29 2019 - 09:53:03 EST



> Am 29.11.2019 um 15:36 schrieb Vincenzo Frascino <vincenzo.frascino@xxxxxxx>:
>
> The libc provides a discovery mechanism for vDSO library and its
> symbols. When a symbol is not exposed by the vDSOs the libc falls back
> on the system calls.
>
> With the introduction of the unified vDSO library on mips this behavior
> is not honored anymore by the kernel in the case of gettimeofday().
>
> The issue has been noticed and reported due to a dhclient failure on the
> CI20 board:
>
> root@letux:~# dhclient
> ../../../../lib/isc/unix/time.c:200: Operation not permitted
> root@letux:~#
>
> Restore the original behavior fixing gettimeofday() in the vDSO library.
>
> Cc: Paul Burton <paulburton@xxxxxxxxxx>
> Reported-by: H. Nikolaus Schaller <hns@xxxxxxxxxxxxx>
> Testes-by: H. Nikolaus Schaller <hns@xxxxxxxxxxxxx> # CI20 with JZ4780
^^^ funny typo... -> Tested-by:
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@xxxxxxx>
> ---
> arch/mips/include/asm/vdso/gettimeofday.h | 13 -------------
> arch/mips/vdso/vgettimeofday.c | 20 ++++++++++++++++++++
> 2 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
> index b08825531e9f..0ae9b4cbc153 100644
> --- a/arch/mips/include/asm/vdso/gettimeofday.h
> +++ b/arch/mips/include/asm/vdso/gettimeofday.h
> @@ -26,8 +26,6 @@
>
> #define __VDSO_USE_SYSCALL ULLONG_MAX
>
> -#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
> -
> static __always_inline long gettimeofday_fallback(
> struct __kernel_old_timeval *_tv,
> struct timezone *_tz)
> @@ -48,17 +46,6 @@ static __always_inline long gettimeofday_fallback(
> return error ? -ret : ret;
> }
>
> -#else
> -
> -static __always_inline long gettimeofday_fallback(
> - struct __kernel_old_timeval *_tv,
> - struct timezone *_tz)
> -{
> - return -1;
> -}
> -
> -#endif
> -
> static __always_inline long clock_gettime_fallback(
> clockid_t _clkid,
> struct __kernel_timespec *_ts)
> diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c
> index 6ebdc37c89fc..6b83b6376a4b 100644
> --- a/arch/mips/vdso/vgettimeofday.c
> +++ b/arch/mips/vdso/vgettimeofday.c
> @@ -17,12 +17,22 @@ int __vdso_clock_gettime(clockid_t clock,
> return __cvdso_clock_gettime32(clock, ts);
> }
>
> +#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
> +
> +/*
> + * This is behind the ifdef so that we don't provide the symbol when there's no
> + * possibility of there being a usable clocksource, because there's nothing we
> + * can do without it. When libc fails the symbol lookup it should fall back on
> + * the standard syscall path.
> + */
> int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
> struct timezone *tz)
> {
> return __cvdso_gettimeofday(tv, tz);
> }
>
> +#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */
> +
> int __vdso_clock_getres(clockid_t clock_id,
> struct old_timespec32 *res)
> {
> @@ -43,12 +53,22 @@ int __vdso_clock_gettime(clockid_t clock,
> return __cvdso_clock_gettime(clock, ts);
> }
>
> +#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
> +
> +/*
> + * This is behind the ifdef so that we don't provide the symbol when there's no
> + * possibility of there being a usable clocksource, because there's nothing we
> + * can do without it. When libc fails the symbol lookup it should fall back on
> + * the standard syscall path.
> + */
> int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
> struct timezone *tz)
> {
> return __cvdso_gettimeofday(tv, tz);
> }
>
> +#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */
> +
> int __vdso_clock_getres(clockid_t clock_id,
> struct __kernel_timespec *res)
> {
> --
> 2.24.0
>