diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
deleted file mode 100644
index 2474a2c575..0000000000
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* Get the current time of day and timezone information,
-   putting it into *tv and *tz.  If tz is null, *tz is not filled.
-   Returns 0 on success, -1 on errors.  */
-
-#include <sys/time.h>
-
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <sysdep-vdso.h>
-
-/* Used as a fallback in the ifunc resolver if VDSO is not available
-   and for libc.so internal __gettimeofday calls.  */
-
-static int
-__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-# define INIT_ARCH()
-
-libc_ifunc_hidden (__gettimeofday, __gettimeofday,
-		   (get_vdso_symbol ("__vdso_gettimeofday")
-		    ?: __gettimeofday_vsyscall))
-libc_hidden_def (__gettimeofday)
-
-#else
-
-# include <sysdep.h>
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
-#endif
-
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index d57f7232e2..526741ed82 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -163,6 +163,7 @@
 # define HAVE_CLOCK_GETRES_VSYSCALL	"__kernel_clock_getres"
 # define HAVE_CLOCK_GETTIME_VSYSCALL	"__kernel_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL	"__kernel_gettimeofday"
+# define USE_GETTIMEOFDAY_VSYSCALL_IFUNC	1
 
 /* Previously AArch64 used the generic version without the libc_hidden_def
    which lead in a non existent __send symbol in libc.so.  */
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
index a74f03825a..ed46723803 100644
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -16,24 +16,57 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <sys/time.h>
+/* Currently we have 3 possible gettimeofday implementations, which is also
+   selected in the order:
+
+   1. Wire-up __NR_gettimeofday with a vDSO implementation (currently aarch64,
+      x86, and powerpc).
+
+   2. vDSO gettimeofday (arm, mips*, riscv*, s390, and sparc).
 
+   3. Wire-up __NR_gettimeofday (alpha, hppa, ia64, m68k, microblaze,
+      nios, sh4).  */
+
+#define __gettimeofday __redirect___gettimeofday
+#include <sys/time.h>
 #undef __gettimeofday
 
+#include <sysdep.h>
 #ifdef HAVE_GETTIMEOFDAY_VSYSCALL
 # define HAVE_VSYSCALL
 #endif
 #include <sysdep-vdso.h>
+#include <libc-vdso.h>
+
+/* Get the current time of day and timezone information, putting it into *tv
+   and *tz.  If tz is null, *tz is not filled. Returns 0 on success, -1 on
+   errors.  */
+static int
+gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+}
+
+#if HAVE_IFUNC && defined USE_GETTIMEOFDAY_VSYSCALL_IFUNC
+/* Route externals calls direct to vDSO and static and internal calls to
+   fallback implementation (which also might call the vDSO).  */
+# ifdef SHARED
+#  define INIT_ARCH()
+libc_ifunc_redirected (__redirect___gettimeofday, __gettimeofday,
+		       get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+		       ?: gettimeofday_syscall);
+libc_hidden_def_redir (gettimeofday_syscall, __gettimeofday)
+#  else
+strong_alias (gettimeofday_syscall, __gettimeofday)
+#  endif /* SHARED  */
+#else
 
-/* Get the current time of day and timezone information,
-   putting it into *tv and *tz.  If tz is null, *tz is not filled.
-   Returns 0 on success, -1 on errors.  */
 int
 __gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+  return gettimeofday_syscall (tv, tz);
 }
-libc_hidden_def (__gettimeofday)
+libc_hidden_def_redir (__gettimeofday, __gettimeofday)
+#endif
 weak_alias (__gettimeofday, gettimeofday)
 libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
deleted file mode 100644
index 185450ece6..0000000000
--- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* gettimeofday - get the time.  Linux/i386 version.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifdef SHARED
-# define __gettimeofday __redirect___gettimeofday
-#endif
-
-#include <sys/time.h>
-
-#ifdef SHARED
-# undef __gettimeofday
-# define __gettimeofday_type __redirect___gettimeofday
-
-# undef libc_hidden_def
-# define libc_hidden_def(name) \
-  __hidden_ver1 (__gettimeofday_syscall, __GI___gettimeofday, \
-	       __gettimeofday_syscall);
-#endif
-
-#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 4f79f25989..076e4393d3 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -315,6 +315,7 @@ struct libc_do_syscall_args
 /* List of system calls which are supported as vsyscalls.  */
 # define HAVE_CLOCK_GETTIME_VSYSCALL    "__vdso_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL     "__vdso_gettimeofday"
+# define USE_GETTIMEOFDAY_VSYSCALL_IFUNC	1
 # define HAVE_TIME_VSYSCALL             "__vdso_time"
 # define USE_TIME_VSYSCALL_IFUNC	1
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
deleted file mode 100644
index 7a4e3cca0c..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#if defined SHARED && !defined __powerpc64__
-# define __gettimeofday __redirect___gettimeofday
-#else
-# define __redirect___gettimeofday __gettimeofday
-#endif
-
-#include <sys/time.h>
-
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-# include <dl-machine.h>
-
-# ifndef __powerpc64__
-#  undef __gettimeofday
-
-int
-__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
-   compiler make a local call (symbol@local) for internal GLIBC usage. It
-   means the PLT won't be used and the ifunc resolver will be called directly.
-   For ppc64 a call to a function in another translation unit might use a
-   different toc pointer thus disallowing direct branchess and making internal
-   ifuncs calls safe.  */
-#  undef libc_hidden_def
-#  define libc_hidden_def(name)					\
-  __hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday,	\
-	       __gettimeofday_vsyscall);
-
-# endif /* !__powerpc64__  */
-
-static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-
-# define INIT_ARCH()						\
-  void *vdso_gettimeofday = get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
-  
-
-/* If the vDSO is not available we fall back syscall.  */
-libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
-		   vdso_gettimeofday
-		   ? vdso_gettimeofday
-		   : (void *) __gettimeofday_syscall);
-libc_hidden_def (__gettimeofday)
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
-#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index 44bfa3f1b6..754832d580 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -26,6 +26,7 @@
 #define HAVE_TIME_VSYSCALL		"__kernel_time"
 #define USE_TIME_VSYSCALL_IFUNC		1
 #define HAVE_GETTIMEOFDAY_VSYSCALL	"__kernel_gettimeofday"
+#define USE_GETTIMEOFDAY_VSYSCALL_IFUNC	1
 #define HAVE_GET_TBFREQ                 "__kernel_get_tbfreq"
 
 #if defined(__PPC64__) || defined(__powerpc64__)
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
deleted file mode 100644
index 3ceab633e5..0000000000
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* gettimeofday - get the time.  Linux/x86 version.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/time.h>
-
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <errno.h>
-# include <sysdep-vdso.h>
-# include <sysdep-vdso.h>
-
-static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-
-# ifndef __gettimeofday_type
-/* The i386 gettimeofday.c includes this file with a defined
-   __gettimeofday_type macro.  For x86_64 we have to define it to __gettimeofday
-   as the internal symbol is the ifunc'ed one.  */
-#  define __gettimeofday_type __gettimeofday
-# endif
-
-# define INIT_ARCH()
-
-/* If the vDSO is not available we fall back to syscall.  */
-libc_ifunc_hidden (__gettimeofday_type, __gettimeofday,
-		   (get_vdso_symbol ("__vdso_gettimeofday")
-		    ?: __gettimeofday_syscall));
-libc_hidden_def (__gettimeofday)
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
-#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index c64fbd1e26..4ea9c4fa31 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -376,6 +376,7 @@
 /* List of system calls which are supported as vsyscalls.  */
 # define HAVE_CLOCK_GETTIME_VSYSCALL    "__vdso_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL     "__vdso_gettimeofday"
+# define USE_GETTIMEOFDAY_VSYSCALL_IFUNC	1
 # define HAVE_TIME_VSYSCALL		"__vdso_time"
 # define USE_TIME_VSYSCALL_IFUNC	1
 # define HAVE_GETCPU_VSYSCALL		"__vdso_getcpu"
