From: Mao Minkai maominkai@wxiat.com
Sunway inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I56P0Z
--------------------------------
Fallback to syscall automatically if vDSO cannot handle the request to make sure user can get correct result when there's no libc.
Signed-off-by: Mao Minkai maominkai@wxiat.com
Signed-off-by: Gu Zitao guzitao@wxiat.com --- arch/sw_64/kernel/vdso/vgettimeofday.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/arch/sw_64/kernel/vdso/vgettimeofday.c b/arch/sw_64/kernel/vdso/vgettimeofday.c index 6ba9ff6e33d5..e45618f9f2de 100644 --- a/arch/sw_64/kernel/vdso/vgettimeofday.c +++ b/arch/sw_64/kernel/vdso/vgettimeofday.c @@ -18,6 +18,23 @@ #include <asm/vdso.h> #include <asm/io.h>
+static __always_inline int syscall_fallback(clockid_t clkid, struct timespec64 *ts) +{ + register int r0 asm("$0"); + register unsigned long r19 asm("$19"); + asm volatile( + " mov %0, $16\n" + " mov %1, $17\n" + " ldi $0, %2\n" + " sys_call 0x83\n" + :: "r"(clkid), "r"(ts), "i"(__NR_clock_gettime) + : "$0", "$16", "$17", "$19"); + if (unlikely(r19)) + return -r0; + else + return r0; +} + static __always_inline int do_realtime_coarse(struct timespec64 *ts, const struct vdso_data *data) { @@ -170,10 +187,9 @@ int __vdso_clock_gettime(clockid_t clkid, struct timespec64 *ts) ret = do_monotonic(ts, data); break; default: - ret = -ENOSYS; - break; + /* fall back to a syscall */ + ret = syscall_fallback(clkid, ts); }
- /* If we return -ENOSYS libc should fall back to a syscall. */ return ret; }