Page MenuHomeFreeBSD

Usermode gettimeofday(2) for armv7 and armv8, and non-executable stack for armv7.
ClosedPublic

Authored by kib on Nov 19 2015, 10:04 AM.
Referenced Files
F82410440: D4209.id10356.diff
Sun, Apr 28, 8:23 AM
Unknown Object (File)
Thu, Apr 11, 11:31 AM
Unknown Object (File)
Mar 18 2024, 9:13 PM
Unknown Object (File)
Feb 2 2024, 7:59 AM
Unknown Object (File)
Jan 18 2024, 1:19 AM
Unknown Object (File)
Jan 18 2024, 1:19 AM
Unknown Object (File)
Jan 8 2024, 10:29 PM
Unknown Object (File)
Dec 25 2023, 4:19 AM
Subscribers

Details

Summary

This adds support for usermode (vdso-like) gettimeofday(2) and clock_gettime(2) on armv7 and armv8 systems which have architectural generic timer hardware. It is similar how the RDTSC timer is used in userspace on x86.

Patch fixes a permission problem where generic timer access from EL0 (or userspace on v7) was not properly initialized on APs.

For ARMv7, it also makes the stack non-executable. The shared page is added for all arms, and signal trampoline code is moved to the page, but I believe that current ARMv8 pmap code does not implement non-executable permissions (I hope that I am wrong). ARMv8 usermode needs the pass to set up PT_GNUSTACK segment anyway (for ARMv7 it was already committed).

Test Plan

I run the previous version of the patch for more than one month on my RPI2, and I did not noticed an issue with ntpd loosing sync.

I tested ARMv8 in QEMU.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib retitled this revision from to Usermode gettimeofday(2) for armv7 and armv8, and non-executable stack for armv7..
kib updated this object.
kib edited the test plan for this revision. (Show Details)
kib added reviewers: ian, mmel, skra, andrew.
kib set the repository for this revision to rS FreeBSD src repository - subversion.
kib added projects: ARM, arm64.
kib added a subscriber: emaste.

This is cool.

lib/libc/arm/sys/__vdso_gettc.c
41–42 ↗(On Diff #10333)

this comment looks like it should be with the '.word' assembler below.

69 ↗(On Diff #10333)

here

sys/arm/arm/generic_timer.c
515 ↗(On Diff #10333)

What does this do? I thought arm would always be defined.

lib/libc/aarch64/sys/__vdso_gettc.c
4–5 ↗(On Diff #10333)

All non-boilerplate here is new content so you can use the "This software was developed..." text instead.

lib/libc/arm/sys/__vdso_gettc.c
69 ↗(On Diff #10333)

Would also be useful to put the intended instruction as a comment

sys/arm/arm/generic_timer.c
515 ↗(On Diff #10333)

arm64 defines __aarch64__ and not __arm__

lib/libc/aarch64/sys/__vdso_gettc.c
4–5 ↗(On Diff #10333)

Changed there and for arm.

lib/libc/arm/sys/__vdso_gettc.c
41–42 ↗(On Diff #10333)

Moved.

69 ↗(On Diff #10333)

I did, see the /* isb */ comment.

sys/arm/arm/generic_timer.c
515 ↗(On Diff #10333)

Yes, this file is compiled for both arm and arm64.

Change note in the copyright, move comment about v7 asm mode.

sys/arm/arm/generic_timer.c
515 ↗(On Diff #10354)

This should be enabled on both arm and arm64, I may change the timers around a bit in the future.

sys/arm64/arm64/exception.S
119 ↗(On Diff #10354)

Seems unrelated & should just be committed.

Use th_physical on arm64 as well.

As i said before, signal trampoline in shared page is perfect for me.

But i have problem with __vdso_gettc.c part. This change infects userland library with HW related data. Moreover, i don't see possibility to add different timer to it (without breaking backward/forward compatibility of userland library).
Or I have missed something here?

ARM uses many different timer implementation, most/some of them are ready for user mode acces (using memory mapped page). Memory mapped variant of generic timer (used in newer qcom SoCs) is one of examples.

In D4209#88979, @meloun-miracle-cz wrote:

As i said before, signal trampoline in shared page is perfect for me.

But i have problem with __vdso_gettc.c part. This change infects userland library with HW related data. Moreover, i don't see possibility to add different timer to it (without breaking backward/forward compatibility of userland library).
Or I have missed something here?

ARM uses many different timer implementation, most/some of them are ready for user mode acces (using memory mapped page). Memory mapped variant of generic timer (used in newer qcom SoCs) is one of examples.

If AT_TIMEKEEP auxv is not passed by kernel, userspace timecounter code is not activated. timekeep->tk_ver specifies the version on the algorithm, which is supposed to be incremented when incompatible change into the ABI is made. timehands->th_algo allows to have different timecounters under the same timekeep structure version. Existing code in libc falls to the syscall if either tk_ver or th_algo are not recognized.

In other words, I do not see an issue with supporting different timer hardware and extend the list with the time. Older libc on newer kernel should fall back to the syscall gracefully, I tested this when I did the initial work for x86.

On x86, I considered to add a support for HPET in addition to RDTSC, but finally my laziness took over. HPET would benefit only old Core2 which cannot use RDTSC if C3 sleep is enabled, so I decided that it is too much work for little benefit on the dying machine population.

If i have new SoC with timer that is accessible from user space (but its different from generic timer), how i can add it into this?.
And how this addition affects kernel <-> libc compatibility? (old libc / new kernel)?

AT_TIMEKEEP auxv only drives user / syscall switch, but it cannot control switch between different HW timers .

In D4209#88981, @meloun-miracle-cz wrote:

If i have new SoC with timer that is accessible from user space (but its different from generic timer), how i can add it into this?.
And how this addition affects kernel <-> libc compatibility? (old libc / new kernel)?

I answered both questions in my previous reply. timehands->th_algo is supposed to specify the algorithm, communicated from kernel to libc. If algorithm is unknown to libc, __vdso_gettimeofday() falls back to the syscall.

AT_TIMEKEEP auxv only drives user / syscall switch, but it cannot control switch between different HW timers .

oups, and I successfully ignored it (existence and meaning of th_algo field). I'm sorry for noise.

kib edited edge metadata.

Update after r291171.

andrew edited edge metadata.
This revision is now accepted and ready to land.Dec 5 2015, 6:11 PM
This revision was automatically updated to reflect the committed changes.