diff mbox

[RFC/PATCH] ARM: VDSO support

Message ID 1428081934-22419-1-git-send-email-nathan_lynch@codesourcery.com
State Dropped
Headers show

Commit Message

Nathan Lynch April 3, 2015, 5:25 p.m. UTC
Future versions of Linux on 32-bit ARM are expected to provide fast
user-space implementations of the following system calls:

- gettimeofday
- clock_gettime

The kernel implementation depends on the ARMv7 Generic Timers
Extension to accelerate these system calls.  So CPUs such as
Cortex-A15 and -A7 benefit, while Cortex-A9, -A8, and pre-v7 CPUs do
not.

The kernel support is currently in linux-next and is slated for
inclusion in Linux 4.1.  I plan to ping or resubmit this patch once
Linux 4.1 is released, but would appreciate any preliminary review in
the meantime.  For reference, the current kernel patch submission may
be found here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/332573.html

This patch adds support for the ARM VDSO to glibc.  I have run make
check on OMAP5 using kernels with and without the VDSO, with no new
failures.

ChangeLog:

2015-04-03  Nathan Lynch  <nathan_lynch@codesourcery.com>

	* sysdeps/unix/sysv/linux/arm/Makefile (sysdep_routines):
	Include dl-vdso.
	* sysdeps/unix/sysv/linux/arm/Versions: Add __vdso_clock_gettime
	and __vdso_gettimeofday.
	* sysdeps/unix/sysv/linux/arm/libc-vdso.h: New file: declare
	__vdso_clock_gettime, __vdso_gettimeofday.
	* sysdeps/unix/sysv/linux/arm/init-first.c: New file: Set
	__vdso_gettimeofday, __vdso_clock_gettime to vdso entry points
	if available.
	* sysdeps/unix/sysv/linux/arm/clock_gettime.c: New file:
	define SYSCALL_GETTIME, use __vdso_clock_gettime if set.
	* sysdeps/unix/sysv/linux/arm/gettimeofday.c: New file: define
	__gettimeofday, use __vdso_gettimeofday if set.
---
 sysdeps/unix/sysv/linux/arm/Makefile        |  1 +
 sysdeps/unix/sysv/linux/arm/Versions        |  2 +
 sysdeps/unix/sysv/linux/arm/clock_gettime.c | 48 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/gettimeofday.c  | 62 +++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/init-first.c    | 52 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/libc-vdso.h     | 32 +++++++++++++++
 6 files changed, 197 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/arm/clock_gettime.c
 create mode 100644 sysdeps/unix/sysv/linux/arm/gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/arm/init-first.c
 create mode 100644 sysdeps/unix/sysv/linux/arm/libc-vdso.h

Comments

Adhemerval Zanella April 6, 2015, 7:04 p.m. UTC | #1
Hi,

On 03-04-2015 14:25, Nathan Lynch wrote:
> Future versions of Linux on 32-bit ARM are expected to provide fast
> user-space implementations of the following system calls:
>
> - gettimeofday
> - clock_gettime
>
> The kernel implementation depends on the ARMv7 Generic Timers
> Extension to accelerate these system calls.  So CPUs such as
> Cortex-A15 and -A7 benefit, while Cortex-A9, -A8, and pre-v7 CPUs do
> not.
>
> The kernel support is currently in linux-next and is slated for
> inclusion in Linux 4.1.  I plan to ping or resubmit this patch once
> Linux 4.1 is released, but would appreciate any preliminary review in
> the meantime.  For reference, the current kernel patch submission may
> be found here:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/332573.html
>
> This patch adds support for the ARM VDSO to glibc.  I have run make
> check on OMAP5 using kernels with and without the VDSO, with no new
> failures.

LGTM. Also, you can tune latency a bit more by using IFUNC on gettimeofday.
Nathan Lynch April 6, 2015, 10:53 p.m. UTC | #2
On 04/06/2015 02:04 PM, Adhemerval Zanella wrote:
> Hi,
> 
> On 03-04-2015 14:25, Nathan Lynch wrote:
>> Future versions of Linux on 32-bit ARM are expected to provide fast
>> user-space implementations of the following system calls:
>>
>> - gettimeofday
>> - clock_gettime
>>
>> The kernel implementation depends on the ARMv7 Generic Timers
>> Extension to accelerate these system calls.  So CPUs such as
>> Cortex-A15 and -A7 benefit, while Cortex-A9, -A8, and pre-v7 CPUs do
>> not.
>>
>> The kernel support is currently in linux-next and is slated for
>> inclusion in Linux 4.1.  I plan to ping or resubmit this patch once
>> Linux 4.1 is released, but would appreciate any preliminary review in
>> the meantime.  For reference, the current kernel patch submission may
>> be found here:
>>
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/332573.html
>>
>> This patch adds support for the ARM VDSO to glibc.  I have run make
>> check on OMAP5 using kernels with and without the VDSO, with no new
>> failures.
> 
> LGTM. Also, you can tune latency a bit more by using IFUNC on gettimeofday.

Thanks, I'll check into that.
Joseph Myers April 7, 2015, 4:46 p.m. UTC | #3
On Fri, 3 Apr 2015, Nathan Lynch wrote:

> This patch adds support for the ARM VDSO to glibc.  I have run make
> check on OMAP5 using kernels with and without the VDSO, with no new
> failures.

How does this compare to the implementations for other architectures?  
What are the points on which the VDSO interfaces vary between 
architectures?  It would seem desirable for the code to be factored so 
that the ARM code only contains the minimal set of things that are 
necessarily ARM-specific (for example, just declaring the ARM-specific 
choices before including architecture-independent files shared by all 
architectures that can get these functions from a VDSO).
Adhemerval Zanella April 7, 2015, 5:06 p.m. UTC | #4
On 07-04-2015 13:46, Joseph Myers wrote:
> On Fri, 3 Apr 2015, Nathan Lynch wrote:
>
>> This patch adds support for the ARM VDSO to glibc.  I have run make
>> check on OMAP5 using kernels with and without the VDSO, with no new
>> failures.
> How does this compare to the implementations for other architectures?  
> What are the points on which the VDSO interfaces vary between 
> architectures?  It would seem desirable for the code to be factored so 
> that the ARM code only contains the minimal set of things that are 
> necessarily ARM-specific (for example, just declaring the ARM-specific 
> choices before including architecture-independent files shared by all 
> architectures that can get these functions from a VDSO).
>
I see the factoring work being another subsequent patch that should not
impede the inclusion of proposed modification.
Joseph Myers April 7, 2015, 5:15 p.m. UTC | #5
On Tue, 7 Apr 2015, Adhemerval Zanella wrote:

> On 07-04-2015 13:46, Joseph Myers wrote:
> > On Fri, 3 Apr 2015, Nathan Lynch wrote:
> >
> >> This patch adds support for the ARM VDSO to glibc.  I have run make
> >> check on OMAP5 using kernels with and without the VDSO, with no new
> >> failures.
> > How does this compare to the implementations for other architectures?  
> > What are the points on which the VDSO interfaces vary between 
> > architectures?  It would seem desirable for the code to be factored so 
> > that the ARM code only contains the minimal set of things that are 
> > necessarily ARM-specific (for example, just declaring the ARM-specific 
> > choices before including architecture-independent files shared by all 
> > architectures that can get these functions from a VDSO).
> >
> I see the factoring work being another subsequent patch that should not
> impede the inclusion of proposed modification. 

I see it as a preparatory cleanup that is (unlike the main change) not 
blocked on the kernel changes getting into kernel.org sources.
Joseph Myers April 7, 2015, 5:20 p.m. UTC | #6
On Tue, 7 Apr 2015, Joseph Myers wrote:

> On Tue, 7 Apr 2015, Adhemerval Zanella wrote:
> 
> > On 07-04-2015 13:46, Joseph Myers wrote:
> > > On Fri, 3 Apr 2015, Nathan Lynch wrote:
> > >
> > >> This patch adds support for the ARM VDSO to glibc.  I have run make
> > >> check on OMAP5 using kernels with and without the VDSO, with no new
> > >> failures.
> > > How does this compare to the implementations for other architectures?  
> > > What are the points on which the VDSO interfaces vary between 
> > > architectures?  It would seem desirable for the code to be factored so 
> > > that the ARM code only contains the minimal set of things that are 
> > > necessarily ARM-specific (for example, just declaring the ARM-specific 
> > > choices before including architecture-independent files shared by all 
> > > architectures that can get these functions from a VDSO).
> > >
> > I see the factoring work being another subsequent patch that should not
> > impede the inclusion of proposed modification. 
> 
> I see it as a preparatory cleanup that is (unlike the main change) not 
> blocked on the kernel changes getting into kernel.org sources.

And, in any case, if a non-refactored patch is to go in, the analysis of 
how the implementations and interfaces for different architectures relate 
should be part of the justification for the implementation approach 
chosen.  That is, the questions I posed should be answered as questions, 
regardless of what patch the answers end up supporting.
Adhemerval Zanella April 7, 2015, 6:55 p.m. UTC | #7
On 07-04-2015 14:20, Joseph Myers wrote:
> On Tue, 7 Apr 2015, Joseph Myers wrote:
>
>> On Tue, 7 Apr 2015, Adhemerval Zanella wrote:
>>
>>> On 07-04-2015 13:46, Joseph Myers wrote:
>>>> On Fri, 3 Apr 2015, Nathan Lynch wrote:
>>>>
>>>>> This patch adds support for the ARM VDSO to glibc.  I have run make
>>>>> check on OMAP5 using kernels with and without the VDSO, with no new
>>>>> failures.
>>>> How does this compare to the implementations for other architectures?  
>>>> What are the points on which the VDSO interfaces vary between 
>>>> architectures?  It would seem desirable for the code to be factored so 
>>>> that the ARM code only contains the minimal set of things that are 
>>>> necessarily ARM-specific (for example, just declaring the ARM-specific 
>>>> choices before including architecture-independent files shared by all 
>>>> architectures that can get these functions from a VDSO).
>>>>
>>> I see the factoring work being another subsequent patch that should not
>>> impede the inclusion of proposed modification. 
>> I see it as a preparatory cleanup that is (unlike the main change) not 
>> blocked on the kernel changes getting into kernel.org sources.
> And, in any case, if a non-refactored patch is to go in, the analysis of 
> how the implementations and interfaces for different architectures relate 
> should be part of the justification for the implementation approach 
> chosen.  That is, the questions I posed should be answered as questions, 
> regardless of what patch the answers end up supporting.
>
My only point is the cleanup should not be a block issue for patch inclusion.
Anyway, about your questioning:

* aarch64/tile/s390 uses INLINE_VSYSCALL 

* powerpc32/powerpc64/i386/x86_64 uses a iFUNC mechanism to call the vDSO 
  symbol directly and falling and avoid glibc symbol wrapper

* powerpc32 and i386 internal gettimeofday are done by the glibc system wrapper

So I think a possible cleanup can start as:

1. Add INLINE_VSYSCALL for arch that does not define it

2. Add a sysdeps/unix/sysv/linux/gettimeofday.c that uses the INLINE_VSYSCALL

3. aarch64/tile/s390 can be removed by 2.

4. The IFUNC cleanup will require some work.  It can be use
   ./sysdeps/unix/sysv/linux/x86/gettimeofday.c as base and if a arch want to
   use it my define USE_IFUNC (or something else) and define the FALLBACK
   mechanism for case where vDSO is not available.

What do you think?
Joseph Myers April 7, 2015, 8:06 p.m. UTC | #8
On Tue, 7 Apr 2015, Adhemerval Zanella wrote:

> So I think a possible cleanup can start as:
> 
> 1. Add INLINE_VSYSCALL for arch that does not define it
> 
> 2. Add a sysdeps/unix/sysv/linux/gettimeofday.c that uses the INLINE_VSYSCALL
> 
> 3. aarch64/tile/s390 can be removed by 2.
> 
> 4. The IFUNC cleanup will require some work.  It can be use
>    ./sysdeps/unix/sysv/linux/x86/gettimeofday.c as base and if a arch want to
>    use it my define USE_IFUNC (or something else) and define the FALLBACK
>    mechanism for case where vDSO is not available.
> 
> What do you think?

Seems plausible to me.  The case of IFUNCs not necessarily being supported 
on some architectures is one that does need architecture differences 
(beyond the choice of whether there is a VDSO at all), but I don't see an 
obvious need for other differences.
Nathan Lynch April 7, 2015, 9:19 p.m. UTC | #9
On 04/07/2015 11:46 AM, Joseph Myers wrote:
> On Fri, 3 Apr 2015, Nathan Lynch wrote:
> 
>> This patch adds support for the ARM VDSO to glibc.  I have run make
>> check on OMAP5 using kernels with and without the VDSO, with no new
>> failures.
> 
> How does this compare to the implementations for other architectures?

One consideration that informed this implementation for ARM is that the
timestamp-related APIs (gettimeofday, clock_gettime) rely on an
architecture extension that is implemented on a subset of CPUs.  CPUs
such as Cortex-A9 which do not have this extension can be expected to
remain in wide use for some time.  So I have paid particular attention
to the cost imposed by this code on systems where the VDSO is _not_
useful for those APIs.  (On such systems the kernel presents a VDSO
which returns NULL for lookups of the symbols for gettimeofday and
clock_gettime).

I referred specifically to the recent x86 VDSO work when writing this.
Although unlike the support which was added for the 32-bit x86 VDSO,
this code introduces a test and branch into the system call path rather
than an unconditional dispatch through a function pointer.  This seems
to impose the least overhead.  For example on i.MX6 (Cortex-A9), where I
measured gettimeofday() to take 560-570ns, the overhead introduced by
unconditional dispatch was ~30ns, while the proposed patch adds only ~15ns.

If I can employ ifunc as Adhemerval suggested, I expect the overhead
could be reduced further or eliminated.

I avoided implementing INLINE_VSYSCALL for ARM partly out of the perhaps
mistaken belief that it would require assembly (both arm and thumb
versions of INLINE_VSYSCALL_NCS), and partly in order to avoid using
preprocessor-pasting which defeats grep (__vdso_##name).  But if
INLINE_VSYSCALL is the preferred method, I can use that; I have an older
version of the patch which has it.


> What are the points on which the VDSO interfaces vary between 
> architectures?

The vdso(7) page from the Linux man-pages project lists the VDSO
interfaces by architecture and seems to be accurate/complete except for
the omission of tile (see the "ARCHITECTURE-SPECIFIC NOTES" section):

http://man7.org/linux/man-pages/man7/vdso.7.html

There is a lot of variation (even in the soname), but it is common to
provide at least gettimeofday and clock_gettime.


> It would seem desirable for the code to be factored so 
> that the ARM code only contains the minimal set of things that are 
> necessarily ARM-specific (for example, just declaring the ARM-specific 
> choices before including architecture-independent files shared by all 
> architectures that can get these functions from a VDSO).

OK.  While I agree that seems desirable, I think it's worth emphasizing
that unlike the other architectures, VDSO acceleration of the
time-related syscalls on ARM cannot be considered the usual case, as
discussed above.  I don't want to pessimize the "fallback" syscall case
on ARM unnecessarily.
Joseph Myers April 7, 2015, 10:22 p.m. UTC | #10
On Tue, 7 Apr 2015, Nathan Lynch wrote:

> I referred specifically to the recent x86 VDSO work when writing this.
> Although unlike the support which was added for the 32-bit x86 VDSO,
> this code introduces a test and branch into the system call path rather
> than an unconditional dispatch through a function pointer.  This seems
> to impose the least overhead.  For example on i.MX6 (Cortex-A9), where I

That suggests making that specific point configurable by architectures 
(VSYSCALL_TEST_IN_SYSCALL_PATH or similar), with comments on the ARM 
definition explaining the reason for the choice there.

> I avoided implementing INLINE_VSYSCALL for ARM partly out of the perhaps
> mistaken belief that it would require assembly (both arm and thumb
> versions of INLINE_VSYSCALL_NCS), and partly in order to avoid using
> preprocessor-pasting which defeats grep (__vdso_##name).  But if
> INLINE_VSYSCALL is the preferred method, I can use that; I have an older
> version of the patch which has it.

I don't think you should need assembly; the x86_64 version does a normal 
function call.  Indeed, maybe something like the x86_64 definition should 
go in a new sysdeps/unix/sysv/linux/sysdep.h, with all Linux architectures 
being made to use that file (architectures with existing definitions could 
still override them if they have good reasons to do so).

In general, the preferred method is to keep architecture-specific code to 
a minimum (cf the recent removal of lots of architecture-specific assembly 
in NPTL, for example); if something can be done generically, there should 
be a good reason (such as your benchmark results showing one approach is 
more efficient than another) for adding anything architecture-specific 
beyond what's needed to cause the generic code to be used.
Mike Frysinger April 8, 2015, 3:39 a.m. UTC | #11
On 07 Apr 2015 16:19, Nathan Lynch wrote:
> The vdso(7) page from the Linux man-pages project lists the VDSO
> interfaces by architecture and seems to be accurate/complete except for
> the omission of tile (see the "ARCHITECTURE-SPECIFIC NOTES" section):
> 
> http://man7.org/linux/man-pages/man7/vdso.7.html
> 
> There is a lot of variation (even in the soname), but it is common to
> provide at least gettimeofday and clock_gettime.

you should send an update to the man group to update arm in vdso(7) :)
-mike
Nathan Lynch April 8, 2015, 3:44 a.m. UTC | #12
On 04/07/2015 10:39 PM, Mike Frysinger wrote:
> On 07 Apr 2015 16:19, Nathan Lynch wrote:
>> The vdso(7) page from the Linux man-pages project lists the VDSO
>> interfaces by architecture and seems to be accurate/complete except for
>> the omission of tile (see the "ARCHITECTURE-SPECIFIC NOTES" section):
>>
>> http://man7.org/linux/man-pages/man7/vdso.7.html
>>
>> There is a lot of variation (even in the soname), but it is common to
>> provide at least gettimeofday and clock_gettime.
> 
> you should send an update to the man group to update arm in vdso(7) :)

Yes, I have a patch written already :)

I'll send it when the ARM VDSO support in Linux is a bit closer to being
in a released version (it is currently queued for 4.1).
diff mbox

Patch

diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index 50410b67b5fc..0ed6f088d574 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -1,4 +1,5 @@ 
 ifeq ($(subdir),elf)
+sysdep_routines	     += dl-vdso
 sysdep-rtld-routines += aeabi_read_tp libc-do-syscall
 endif
 
diff --git a/sysdeps/unix/sysv/linux/arm/Versions b/sysdeps/unix/sysv/linux/arm/Versions
index a251b0fd7d87..7bc5936372bb 100644
--- a/sysdeps/unix/sysv/linux/arm/Versions
+++ b/sysdeps/unix/sysv/linux/arm/Versions
@@ -10,5 +10,7 @@  libc {
   GLIBC_PRIVATE {
     # A copy of sigaction lives in libpthread, and needs these.
     __default_sa_restorer; __default_rt_sa_restorer;
+    __vdso_clock_gettime;
+    __vdso_gettimeofday;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/arm/clock_gettime.c b/sysdeps/unix/sysv/linux/arm/clock_gettime.c
new file mode 100644
index 000000000000..958db42c6b7c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/clock_gettime.c
@@ -0,0 +1,48 @@ 
+/* Get the current value of a clock.  Linux/arm version.
+   Copyright (C) 2015 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
+
+#include <sysdep.h>
+#include <sys/time.h>
+#include <libc-vdso.h>
+
+static long int
+clock_gettime_syscall (clockid_t id, struct timespec *tp)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  return INTERNAL_SYSCALL (clock_gettime, err, 2, id, tp);
+}
+
+
+# define SYSCALL_GETTIME(id, tp) \
+  ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+  long int v_ret;							  \
+  PTR_DEMANGLE (f);							  \
+  if (f)								  \
+    v_ret = (*f) (id, tp);						  \
+  else									  \
+    v_ret = clock_gettime_syscall(id, tp);			          \
+  if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) {				  \
+    __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, ));			  \
+    v_ret = -1;								  \
+  }									  \
+  v_ret; })
+#endif
+
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
diff --git a/sysdeps/unix/sysv/linux/arm/gettimeofday.c b/sysdeps/unix/sysv/linux/arm/gettimeofday.c
new file mode 100644
index 000000000000..3665ade8f226
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/gettimeofday.c
@@ -0,0 +1,62 @@ 
+/* gettimeofday - get the time.  Linux/arm version.
+   Copyright (C) 2015 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 <sysdep.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+# include <libc-vdso.h>
+
+static long int
+gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  return INTERNAL_SYSCALL (gettimeofday, err, 2, tv, tz);
+}
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+  long int (*f) (struct timeval *, struct timezone *) = __vdso_gettimeofday;
+  long int v_ret;
+
+  PTR_DEMANGLE (f);
+  if (f)
+    v_ret = (*f) (tv, tz);
+  else
+    v_ret = gettimeofday_syscall(tv, tz);
+  if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) {
+    __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, ));
+    v_ret = -1;
+  }
+  return v_ret;
+}
+
+#else
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+
+#endif
+libc_hidden_def (__gettimeofday)
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/arm/init-first.c b/sysdeps/unix/sysv/linux/arm/init-first.c
new file mode 100644
index 000000000000..c512d3a3e795
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/init-first.c
@@ -0,0 +1,52 @@ 
+/* Initialization code run first thing by the ELF startup code.  Linux/arm.
+   Copyright (C) 2015 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
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+  __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
+
+long int (*__vdso_gettimeofday) (struct timeval *tv, struct timezone *tz)
+  __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_gettimeofday)
+libc_hidden_data_def (__vdso_gettimeofday)
+
+static inline void
+__vdso_platform_setup (void)
+{
+  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+
+  void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+  PTR_MANGLE (p);
+  __vdso_clock_gettime = p;
+
+  p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
+  PTR_MANGLE (p);
+  __vdso_gettimeofday = p;
+}
+
+# define VDSO_SETUP __vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/arm/libc-vdso.h b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
new file mode 100644
index 000000000000..622ef4dd62c3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
@@ -0,0 +1,32 @@ 
+/* Resolve function pointers to VDSO functions.
+   Copyright (C) 2015 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/>.  */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+extern long int (*__vdso_gettimeofday) (struct timeval *, struct timezone *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */