Updates for the VDSO subsystem:

- Further consolidation of the VDSO infrastructure and the common data
     store.
 
   - Simplification of the related Kconfig logic
 
   - Improve the VDSO selftest suite
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmjaUJgTHHRnbHhAbGlu
 dXRyb25peC5kZQAKCRCmGPVMDXSYoT5VD/9l+TP42vJzwygPArefVM9QijAc4k+g
 iptaz5M+Lhk0BlwMUu502Tp1zcwGq5529LlE2P72DuYoZRtZKSFCGES2mye0JiAs
 A5Vk8d1zicg3IIGjYgw39shA9ghzuzV3gZdgHVqQ6024uSeKxUY3SqF156GGfPFG
 azXWDV7i4RGQvKLm2ye8m7JNYCE3P9f8Wh+GvPaq7qBlW1MsMCWC4FP5qu4iStf3
 mol9uA/EM2zSDwkpIpq6P5L2TpIH1dGDNGxVf/HG3J16UhNXzzXv/rxuKHKPNGWm
 MQZ8WdPjF+uwdUsNXaImC6aCE0hoQ1Ga7GE2YA3pMQYfySeiJ/fA5I1KfhlUCiHD
 oUgnb6PQfZjaBDrIODKcrFHAYc5pTOyJXnJ6q1Lc1yrOfoVcIpMaRXHO/phCeuwI
 61gfb9ggbFEH/7cL26Z9XGSqh4BDCKVP5Z+y98OnNEzV74ScpX13/szB3VgdN6LW
 tmTOeMPYCo4FQoPw8OV1xkeYOKD2JyqH+garnxDZNFjaVaeUkzlAMKz+1JUjxRZj
 UpUhZ8y5KFVjgKkqZHxhucr9cnwV/xd4n+IzZeG4l6XZp4VyirG+5QpAikGYe+Jq
 WFU4Ao1xvevyizrJEhoGJKznwtrNrsy6AQ+wLQxYiRR4aTnng8n9T/ry2DVvhJf8
 diYWxuRTR7KMxg==
 =i3UB
 -----END PGP SIGNATURE-----

Merge tag 'timers-vdso-2025-09-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull VDSO updates from Thomas Gleixner:

 - Further consolidation of the VDSO infrastructure and the common data
   store

 - Simplification of the related Kconfig logic

 - Improve the VDSO selftest suite

* tag 'timers-vdso-2025-09-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  selftests: vDSO: Drop vdso_test_clock_getres
  selftests: vDSO: vdso_test_abi: Add tests for clock_gettime64()
  selftests: vDSO: vdso_test_abi: Test CPUTIME clocks
  selftests: vDSO: vdso_test_abi: Use explicit indices for name array
  selftests: vDSO: vdso_test_abi: Drop clock availability tests
  selftests: vDSO: vdso_test_abi: Use ksft_finished()
  selftests: vDSO: vdso_test_abi: Correctly skip whole test with missing vDSO
  selftests: vDSO: Fix -Wunitialized in powerpc VDSO_CALL() wrapper
  vdso: Add struct __kernel_old_timeval forward declaration to gettime.h
  vdso: Gate VDSO_GETRANDOM behind HAVE_GENERIC_VDSO
  vdso: Drop Kconfig GENERIC_VDSO_TIME_NS
  vdso: Drop Kconfig GENERIC_VDSO_DATA_STORE
  vdso: Drop kconfig GENERIC_COMPAT_VDSO
  vdso: Drop kconfig GENERIC_VDSO_32
  riscv: vdso: Untangle Kconfig logic
  time: Build generic update_vsyscall() only with generic time vDSO
  vdso/gettimeofday: Remove !CONFIG_TIME_NS stubs
  vdso: Move ENABLE_COMPAT_VDSO from core to arm64
  ARM: VDSO: Remove cntvct_ok global variable
  vdso/datastore: Gate time data behind CONFIG_GENERIC_GETTIMEOFDAY
This commit is contained in:
Linus Torvalds 2025-09-30 16:58:21 -07:00
commit 4b81e2eb9e
30 changed files with 91 additions and 285 deletions

View File

@ -1657,7 +1657,7 @@ config HAVE_SPARSE_SYSCALL_NR
related optimizations for a given architecture.
config ARCH_HAS_VDSO_ARCH_DATA
depends on GENERIC_VDSO_DATA_STORE
depends on HAVE_GENERIC_VDSO
bool
config ARCH_HAS_VDSO_TIME_DATA

View File

@ -7,8 +7,6 @@
#include <vdso/datapage.h>
#include <asm/cacheflush.h>
extern bool cntvct_ok;
static __always_inline
void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
{

View File

@ -54,11 +54,9 @@ struct elfinfo {
char *dynstr; /* ptr to .dynstr section */
};
/* Cached result of boot-time check for whether the arch timer exists,
* and if so, whether the virtual counter is useable.
/* Boot-time check for whether the arch timer exists, and if so,
* whether the virtual counter is usable.
*/
bool cntvct_ok __ro_after_init;
static bool __init cntvct_functional(void)
{
struct device_node *np;
@ -159,7 +157,7 @@ static void __init patch_vdso(void *ehdr)
* want programs to incur the slight additional overhead of
* dispatching through the VDSO only to fall back to syscalls.
*/
if (!cntvct_ok) {
if (!cntvct_functional()) {
vdso_nullpatch_one(&einfo, "__vdso_gettimeofday");
vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
vdso_nullpatch_one(&einfo, "__vdso_clock_gettime64");
@ -197,8 +195,6 @@ static int __init vdso_init(void)
vdso_total_pages = VDSO_NR_PAGES; /* for the data/vvar pages */
vdso_total_pages += text_pages;
cntvct_ok = cntvct_functional();
patch_vdso(vdso_start);
return 0;

View File

@ -926,9 +926,7 @@ config VDSO
default y if ARM_ARCH_TIMER
select HAVE_GENERIC_VDSO
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_32
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_DATA_STORE
help
Place in the process address space an ELF shared object
providing fast implementations of gettimeofday and

View File

@ -166,8 +166,6 @@ config ARM64
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_DATA_STORE
select GENERIC_VDSO_TIME_NS
select HARDIRQS_SW_RESEND
select HAS_IOPORT
select HAVE_MOVE_PMD
@ -1750,7 +1748,6 @@ config COMPAT_VDSO
bool "Enable vDSO for 32-bit applications"
depends on !CPU_BIG_ENDIAN
depends on (CC_IS_CLANG && LD_IS_LLD) || "$(CROSS_COMPILE_COMPAT)" != ""
select GENERIC_COMPAT_VDSO
default y
help
Place in the process address space of 32-bit applications an

View File

@ -7,11 +7,10 @@
#ifndef __ASSEMBLY__
/*
* Warning: This code is meant to be used with
* ENABLE_COMPAT_VDSO only.
* Warning: This code is meant to be used from the compat vDSO only.
*/
#ifndef ENABLE_COMPAT_VDSO
#error This header is meant to be used with ENABLE_COMPAT_VDSO only
#ifdef __arch64__
#error This header is meant to be used with from the compat vDSO only
#endif
#ifdef dmb

View File

@ -2,8 +2,8 @@
/*
* Copyright (C) 2018 ARM Limited
*/
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
#define __ASM_VDSO_GETTIMEOFDAY_H
#ifndef __ASM_VDSO_COMPAT_GETTIMEOFDAY_H
#define __ASM_VDSO_COMPAT_GETTIMEOFDAY_H
#ifndef __ASSEMBLY__
@ -163,4 +163,4 @@ static inline bool vdso_clocksource_ok(const struct vdso_clock *vc)
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
#endif /* __ASM_VDSO_COMPAT_GETTIMEOFDAY_H */

View File

@ -5,6 +5,8 @@
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
#define __ASM_VDSO_GETTIMEOFDAY_H
#ifdef __aarch64__
#ifndef __ASSEMBLY__
#include <asm/alternative.h>
@ -96,4 +98,10 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(
#endif /* !__ASSEMBLY__ */
#else /* !__aarch64__ */
#include "compat_gettimeofday.h"
#endif /* __aarch64__ */
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */

View File

@ -57,7 +57,6 @@ VDSO_CAFLAGS += -DDISABLE_BRANCH_PROFILING
VDSO_CAFLAGS += -march=armv8-a
VDSO_CFLAGS := $(VDSO_CAFLAGS)
VDSO_CFLAGS += -DENABLE_COMPAT_VDSO=1
# KBUILD_CFLAGS from top-level Makefile
VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \

View File

@ -110,8 +110,6 @@ config LOONGARCH
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_DATA_STORE
select GENERIC_VDSO_TIME_NS
select GPIOLIB
select HAS_IOPORT
select HAVE_ARCH_AUDITSYSCALL

View File

@ -51,7 +51,6 @@ config MIPS
select GENERIC_SMP_IDLE_THREAD
select GENERIC_IDLE_POLL_SETUP
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_DATA_STORE
select GUP_GET_PXX_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
select HAS_IOPORT if !NO_IOPORT_MAP || ISA
select HAVE_ARCH_COMPILER_H

View File

@ -210,8 +210,6 @@ config PPC
select GENERIC_PCI_IOMAP if PCI
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_DATA_STORE
select GENERIC_VDSO_TIME_NS
select HAS_IOPORT if PCI
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP

View File

@ -53,7 +53,7 @@ config RISCV
select ARCH_HAS_SYSCALL_WRAPPER
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UBSAN
select ARCH_HAS_VDSO_ARCH_DATA if GENERIC_VDSO_DATA_STORE
select ARCH_HAS_VDSO_ARCH_DATA if HAVE_GENERIC_VDSO
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_KEEP_MEMBLOCK if ACPI
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if 64BIT && MMU
@ -110,7 +110,7 @@ config RISCV
select GENERIC_CPU_VULNERABILITIES
select GENERIC_EARLY_IOREMAP
select GENERIC_ENTRY
select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO && 64BIT
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IOREMAP if MMU
select GENERIC_IRQ_IPI if SMP
@ -123,9 +123,7 @@ config RISCV
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
select GENERIC_VDSO_DATA_STORE if MMU
select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
select GENERIC_TIME_VSYSCALL if GENERIC_GETTIMEOFDAY
select HARDIRQS_SW_RESEND
select HAS_IOPORT if MMU
select HAVE_ALIGNED_STRUCT_PAGE
@ -169,7 +167,7 @@ config RISCV
select HAVE_FUNCTION_ARG_ACCESS_API
select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_GCC_PLUGINS
select HAVE_GENERIC_VDSO if MMU && 64BIT
select HAVE_GENERIC_VDSO if MMU
select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
select HAVE_KERNEL_GZIP if !XIP_KERNEL && !EFI_ZBOOT
@ -225,7 +223,7 @@ config RISCV
select THREAD_INFO_IN_TASK
select TRACE_IRQFLAGS_SUPPORT
select UACCESS_MEMCPY if !MMU
select VDSO_GETRANDOM if HAVE_GENERIC_VDSO
select VDSO_GETRANDOM if HAVE_GENERIC_VDSO && 64BIT
select USER_STACKTRACE_SUPPORT
select ZONE_DMA32 if 64BIT

View File

@ -174,8 +174,6 @@ config S390
select GENERIC_GETTIMEOFDAY
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_DATA_STORE
select GENERIC_VDSO_TIME_NS
select GENERIC_IOREMAP if PCI
select HAVE_ALIGNED_STRUCT_PAGE
select HAVE_ARCH_AUDITSYSCALL

View File

@ -14,7 +14,6 @@ config X86_32
select ARCH_WANT_IPC_PARSE_VERSION
select CLKSRC_I8253
select CLONE_BACKWARDS
select GENERIC_VDSO_32
select HAVE_DEBUG_STACKOVERFLOW
select KMAP_LOCAL
select MODULES_USE_ELF_REL
@ -182,8 +181,6 @@ config X86
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_DATA_STORE
select GENERIC_VDSO_TIME_NS
select GENERIC_VDSO_OVERFLOW_PROTECT
select GUP_GET_PXX_LOW_HIGH if X86_PAE
select HARDIRQS_SW_RESEND

View File

@ -4,8 +4,6 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
#ifndef __arch_get_vdso_u_time_data
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
{
@ -20,8 +18,6 @@ static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(vo
}
#endif
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
#ifndef __arch_update_vdso_clock
static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
{

View File

@ -31,7 +31,7 @@ struct arch_vdso_time_data {};
#if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)
#include <asm/vdso/arch_data.h>
#elif defined(CONFIG_GENERIC_VDSO_DATA_STORE)
#else
struct vdso_arch_data {
/* Needed for the generic code, never actually used at runtime */
char __unused;
@ -164,7 +164,6 @@ struct vdso_rng_data {
* With the hidden visibility, the compiler simply generates a PC-relative
* relocation, and this is what we need.
*/
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
extern struct vdso_time_data vdso_u_time_data __attribute__((visibility("hidden")));
extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));
@ -185,8 +184,6 @@ enum vdso_pages {
VDSO_NR_PAGES
};
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
/*
* The generic vDSO implementation requires that gettimeofday.h
* provides:
@ -196,11 +193,7 @@ enum vdso_pages {
* - clock_gettime_fallback(): fallback for clock_gettime.
* - clock_getres_fallback(): fallback for clock_getres.
*/
#ifdef ENABLE_COMPAT_VDSO
#include <asm/vdso/compat_gettimeofday.h>
#else
#include <asm/vdso/gettimeofday.h>
#endif /* ENABLE_COMPAT_VDSO */
#else /* !__ASSEMBLY__ */

View File

@ -5,6 +5,7 @@
#include <linux/types.h>
struct __kernel_timespec;
struct __kernel_old_timeval;
struct timezone;
#if !defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64)

View File

@ -1363,7 +1363,7 @@ config UTS_NS
config TIME_NS
bool "TIME namespace"
depends on GENERIC_VDSO_TIME_NS
depends on GENERIC_GETTIMEOFDAY
default y
help
In this namespace boottime and monotonic clocks can be set.

View File

@ -26,7 +26,7 @@ obj-$(CONFIG_LEGACY_TIMER_TICK) += tick-legacy.o
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_NO_HZ_COMMON) += timer_migration.o
endif
obj-$(CONFIG_HAVE_GENERIC_VDSO) += vsyscall.o
obj-$(CONFIG_GENERIC_GETTIMEOFDAY) += vsyscall.o
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
obj-$(CONFIG_TIME_NS) += namespace.o

View File

@ -12,24 +12,6 @@ config GENERIC_GETTIMEOFDAY
Each architecture that enables this feature has to
provide the fallback implementation.
config GENERIC_VDSO_32
bool
depends on GENERIC_GETTIMEOFDAY && !64BIT
help
This config option helps to avoid possible performance issues
in 32 bit only architectures.
config GENERIC_COMPAT_VDSO
bool
help
This config option enables the compat VDSO layer.
config GENERIC_VDSO_TIME_NS
bool
help
Selected by architectures which support time namespaces in the
VDSO
config GENERIC_VDSO_OVERFLOW_PROTECT
bool
help
@ -37,14 +19,9 @@ config GENERIC_VDSO_OVERFLOW_PROTECT
time getter functions for the price of an extra conditional
in the hotpath.
endif
config VDSO_GETRANDOM
bool
help
Selected by architectures that support vDSO getrandom().
config GENERIC_VDSO_DATA_STORE
bool
help
Selected by architectures that use the generic vDSO data store.
endif

View File

@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_GENERIC_VDSO_DATA_STORE) += datastore.o
obj-$(CONFIG_HAVE_GENERIC_VDSO) += datastore.o

View File

@ -11,14 +11,14 @@
/*
* The vDSO data page.
*/
#ifdef CONFIG_HAVE_GENERIC_VDSO
#ifdef CONFIG_GENERIC_GETTIMEOFDAY
static union {
struct vdso_time_data data;
u8 page[PAGE_SIZE];
} vdso_time_data_store __page_aligned_data;
struct vdso_time_data *vdso_k_time_data = &vdso_time_data_store.data;
static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
#endif /* CONFIG_HAVE_GENERIC_VDSO */
#endif /* CONFIG_GENERIC_GETTIMEOFDAY */
#ifdef CONFIG_VDSO_GETRANDOM
static union {
@ -46,7 +46,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
switch (vmf->pgoff) {
case VDSO_TIME_PAGE_OFFSET:
if (!IS_ENABLED(CONFIG_HAVE_GENERIC_VDSO))
if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY))
return VM_FAULT_SIGBUS;
pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
if (timens_page) {

View File

@ -108,15 +108,11 @@ bool vdso_get_timestamp(const struct vdso_time_data *vd, const struct vdso_clock
return true;
}
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
static __always_inline
const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_time_data *vd)
{
return (void *)vd + PAGE_SIZE;
}
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
static __always_inline
bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
@ -149,20 +145,6 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
return true;
}
#else
static __always_inline
const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_time_data *vd)
{
return NULL;
}
static __always_inline
bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
clockid_t clk, struct __kernel_timespec *ts)
{
return false;
}
#endif
static __always_inline
bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
@ -204,7 +186,6 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
return true;
}
#ifdef CONFIG_TIME_NS
static __always_inline
bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
clockid_t clk, struct __kernel_timespec *ts)
@ -233,14 +214,6 @@ bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
return true;
}
#else
static __always_inline
bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
clockid_t clk, struct __kernel_timespec *ts)
{
return false;
}
#endif
static __always_inline
bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,

View File

@ -4,6 +4,5 @@ CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_TIME_NS=y
CONFIG_GENERIC_VDSO_TIME_NS=y
CONFIG_CGROUPS=y
CONFIG_CHECKPOINT_RESTORE=y

View File

@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
vdso_test
vdso_test_abi
vdso_test_clock_getres
vdso_test_correctness
vdso_test_gettimeofday
vdso_test_getcpu

View File

@ -4,7 +4,6 @@ include ../../../scripts/Makefile.arch
TEST_GEN_PROGS := vdso_test_gettimeofday
TEST_GEN_PROGS += vdso_test_getcpu
TEST_GEN_PROGS += vdso_test_abi
TEST_GEN_PROGS += vdso_test_clock_getres
ifeq ($(ARCH),$(filter $(ARCH),x86 x86_64))
TEST_GEN_PROGS += vdso_standalone_test_x86
endif
@ -29,7 +28,6 @@ CFLAGS_NOLIBC := -nostdlib -nostdinc -ffreestanding -fno-asynchronous-unwind-tab
$(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c
$(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.c
$(OUTPUT)/vdso_test_abi: parse_vdso.c vdso_test_abi.c
$(OUTPUT)/vdso_test_clock_getres: vdso_test_clock_getres.c
$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c | headers
$(OUTPUT)/vdso_standalone_test_x86: CFLAGS:=$(CFLAGS_NOLIBC) $(CFLAGS)

View File

@ -44,7 +44,6 @@
register long _r6 asm ("r6"); \
register long _r7 asm ("r7"); \
register long _r8 asm ("r8"); \
register long _rval asm ("r3"); \
\
LOADARGS_##nr(fn, args); \
\
@ -54,13 +53,13 @@
" bns+ 1f\n" \
" neg 3, 3\n" \
"1:" \
: "+r" (_r0), "=r" (_r3), "+r" (_r4), "+r" (_r5), \
: "+r" (_r0), "+r" (_r3), "+r" (_r4), "+r" (_r5), \
"+r" (_r6), "+r" (_r7), "+r" (_r8) \
: "r" (_rval) \
: \
: "r9", "r10", "r11", "r12", "cr0", "cr1", "cr5", \
"cr6", "cr7", "xer", "lr", "ctr", "memory" \
); \
_rval; \
_r3; \
})
#else

View File

@ -26,24 +26,31 @@
static const char *version;
static const char **name;
/* The same as struct __kernel_timespec */
struct vdso_timespec64 {
uint64_t tv_sec;
uint64_t tv_nsec;
};
typedef long (*vdso_gettimeofday_t)(struct timeval *tv, struct timezone *tz);
typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
typedef long (*vdso_clock_gettime64_t)(clockid_t clk_id, struct vdso_timespec64 *ts);
typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
typedef time_t (*vdso_time_t)(time_t *t);
const char *vdso_clock_name[12] = {
"CLOCK_REALTIME",
"CLOCK_MONOTONIC",
"CLOCK_PROCESS_CPUTIME_ID",
"CLOCK_THREAD_CPUTIME_ID",
"CLOCK_MONOTONIC_RAW",
"CLOCK_REALTIME_COARSE",
"CLOCK_MONOTONIC_COARSE",
"CLOCK_BOOTTIME",
"CLOCK_REALTIME_ALARM",
"CLOCK_BOOTTIME_ALARM",
"CLOCK_SGI_CYCLE",
"CLOCK_TAI",
static const char * const vdso_clock_name[] = {
[CLOCK_REALTIME] = "CLOCK_REALTIME",
[CLOCK_MONOTONIC] = "CLOCK_MONOTONIC",
[CLOCK_PROCESS_CPUTIME_ID] = "CLOCK_PROCESS_CPUTIME_ID",
[CLOCK_THREAD_CPUTIME_ID] = "CLOCK_THREAD_CPUTIME_ID",
[CLOCK_MONOTONIC_RAW] = "CLOCK_MONOTONIC_RAW",
[CLOCK_REALTIME_COARSE] = "CLOCK_REALTIME_COARSE",
[CLOCK_MONOTONIC_COARSE] = "CLOCK_MONOTONIC_COARSE",
[CLOCK_BOOTTIME] = "CLOCK_BOOTTIME",
[CLOCK_REALTIME_ALARM] = "CLOCK_REALTIME_ALARM",
[CLOCK_BOOTTIME_ALARM] = "CLOCK_BOOTTIME_ALARM",
[10 /* CLOCK_SGI_CYCLE */] = "CLOCK_SGI_CYCLE",
[CLOCK_TAI] = "CLOCK_TAI",
};
static void vdso_test_gettimeofday(void)
@ -70,6 +77,33 @@ static void vdso_test_gettimeofday(void)
}
}
static void vdso_test_clock_gettime64(clockid_t clk_id)
{
/* Find clock_gettime64. */
vdso_clock_gettime64_t vdso_clock_gettime64 =
(vdso_clock_gettime64_t)vdso_sym(version, name[5]);
if (!vdso_clock_gettime64) {
ksft_print_msg("Couldn't find %s\n", name[5]);
ksft_test_result_skip("%s %s\n", name[5],
vdso_clock_name[clk_id]);
return;
}
struct vdso_timespec64 ts;
long ret = VDSO_CALL(vdso_clock_gettime64, 2, clk_id, &ts);
if (ret == 0) {
ksft_print_msg("The time is %lld.%06lld\n",
(long long)ts.tv_sec, (long long)ts.tv_nsec);
ksft_test_result_pass("%s %s\n", name[5],
vdso_clock_name[clk_id]);
} else {
ksft_test_result_fail("%s %s\n", name[5],
vdso_clock_name[clk_id]);
}
}
static void vdso_test_clock_gettime(clockid_t clk_id)
{
/* Find clock_gettime. */
@ -171,23 +205,23 @@ static inline void vdso_test_clock(clockid_t clock_id)
ksft_print_msg("clock_id: %s\n", vdso_clock_name[clock_id]);
vdso_test_clock_gettime(clock_id);
vdso_test_clock_gettime64(clock_id);
vdso_test_clock_getres(clock_id);
}
#define VDSO_TEST_PLAN 16
#define VDSO_TEST_PLAN 29
int main(int argc, char **argv)
{
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
ksft_print_header();
ksft_set_plan(VDSO_TEST_PLAN);
if (!sysinfo_ehdr) {
ksft_print_msg("AT_SYSINFO_EHDR is not present!\n");
return KSFT_SKIP;
}
if (!sysinfo_ehdr)
ksft_exit_skip("AT_SYSINFO_EHDR is not present!\n");
ksft_set_plan(VDSO_TEST_PLAN);
version = versions[VDSO_VERSION];
name = (const char **)&names[VDSO_NAMES];
@ -198,40 +232,17 @@ int main(int argc, char **argv)
vdso_test_gettimeofday();
#if _POSIX_TIMERS > 0
#ifdef CLOCK_REALTIME
vdso_test_clock(CLOCK_REALTIME);
#endif
#ifdef CLOCK_BOOTTIME
vdso_test_clock(CLOCK_BOOTTIME);
#endif
#ifdef CLOCK_TAI
vdso_test_clock(CLOCK_TAI);
#endif
#ifdef CLOCK_REALTIME_COARSE
vdso_test_clock(CLOCK_REALTIME_COARSE);
#endif
#ifdef CLOCK_MONOTONIC
vdso_test_clock(CLOCK_MONOTONIC);
#endif
#ifdef CLOCK_MONOTONIC_RAW
vdso_test_clock(CLOCK_MONOTONIC_RAW);
#endif
#ifdef CLOCK_MONOTONIC_COARSE
vdso_test_clock(CLOCK_MONOTONIC_COARSE);
#endif
#endif
vdso_test_clock(CLOCK_PROCESS_CPUTIME_ID);
vdso_test_clock(CLOCK_THREAD_CPUTIME_ID);
vdso_test_time();
ksft_print_cnts();
return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
ksft_finished();
}

View File

@ -1,123 +0,0 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
* vdso_clock_getres.c: Sample code to test clock_getres.
* Copyright (c) 2019 Arm Ltd.
*
* Compile with:
* gcc -std=gnu99 vdso_clock_getres.c
*
* Tested on ARM, ARM64, MIPS32, x86 (32-bit and 64-bit),
* Power (32-bit and 64-bit), S390x (32-bit and 64-bit).
* Might work on other architectures.
*/
#define _GNU_SOURCE
#include <elf.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "../kselftest.h"
static long syscall_clock_getres(clockid_t _clkid, struct timespec *_ts)
{
long ret;
ret = syscall(SYS_clock_getres, _clkid, _ts);
return ret;
}
const char *vdso_clock_name[12] = {
"CLOCK_REALTIME",
"CLOCK_MONOTONIC",
"CLOCK_PROCESS_CPUTIME_ID",
"CLOCK_THREAD_CPUTIME_ID",
"CLOCK_MONOTONIC_RAW",
"CLOCK_REALTIME_COARSE",
"CLOCK_MONOTONIC_COARSE",
"CLOCK_BOOTTIME",
"CLOCK_REALTIME_ALARM",
"CLOCK_BOOTTIME_ALARM",
"CLOCK_SGI_CYCLE",
"CLOCK_TAI",
};
/*
* This function calls clock_getres in vdso and by system call
* with different values for clock_id.
*
* Example of output:
*
* clock_id: CLOCK_REALTIME [PASS]
* clock_id: CLOCK_BOOTTIME [PASS]
* clock_id: CLOCK_TAI [PASS]
* clock_id: CLOCK_REALTIME_COARSE [PASS]
* clock_id: CLOCK_MONOTONIC [PASS]
* clock_id: CLOCK_MONOTONIC_RAW [PASS]
* clock_id: CLOCK_MONOTONIC_COARSE [PASS]
*/
static inline int vdso_test_clock(unsigned int clock_id)
{
struct timespec x, y;
printf("clock_id: %s", vdso_clock_name[clock_id]);
clock_getres(clock_id, &x);
syscall_clock_getres(clock_id, &y);
if ((x.tv_sec != y.tv_sec) || (x.tv_nsec != y.tv_nsec)) {
printf(" [FAIL]\n");
return KSFT_FAIL;
}
printf(" [PASS]\n");
return KSFT_PASS;
}
int main(int argc, char **argv)
{
int ret = 0;
#if _POSIX_TIMERS > 0
#ifdef CLOCK_REALTIME
ret += vdso_test_clock(CLOCK_REALTIME);
#endif
#ifdef CLOCK_BOOTTIME
ret += vdso_test_clock(CLOCK_BOOTTIME);
#endif
#ifdef CLOCK_TAI
ret += vdso_test_clock(CLOCK_TAI);
#endif
#ifdef CLOCK_REALTIME_COARSE
ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
#endif
#ifdef CLOCK_MONOTONIC
ret += vdso_test_clock(CLOCK_MONOTONIC);
#endif
#ifdef CLOCK_MONOTONIC_RAW
ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
#endif
#ifdef CLOCK_MONOTONIC_COARSE
ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
#endif
#endif
if (ret > 0)
return KSFT_FAIL;
return KSFT_PASS;
}