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:
commit
4b81e2eb9e
|
@ -1657,7 +1657,7 @@ config HAVE_SPARSE_SYSCALL_NR
|
||||||
related optimizations for a given architecture.
|
related optimizations for a given architecture.
|
||||||
|
|
||||||
config ARCH_HAS_VDSO_ARCH_DATA
|
config ARCH_HAS_VDSO_ARCH_DATA
|
||||||
depends on GENERIC_VDSO_DATA_STORE
|
depends on HAVE_GENERIC_VDSO
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config ARCH_HAS_VDSO_TIME_DATA
|
config ARCH_HAS_VDSO_TIME_DATA
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include <vdso/datapage.h>
|
#include <vdso/datapage.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
|
||||||
extern bool cntvct_ok;
|
|
||||||
|
|
||||||
static __always_inline
|
static __always_inline
|
||||||
void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
|
void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,11 +54,9 @@ struct elfinfo {
|
||||||
char *dynstr; /* ptr to .dynstr section */
|
char *dynstr; /* ptr to .dynstr section */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Cached result of boot-time check for whether the arch timer exists,
|
/* Boot-time check for whether the arch timer exists, and if so,
|
||||||
* and if so, whether the virtual counter is useable.
|
* whether the virtual counter is usable.
|
||||||
*/
|
*/
|
||||||
bool cntvct_ok __ro_after_init;
|
|
||||||
|
|
||||||
static bool __init cntvct_functional(void)
|
static bool __init cntvct_functional(void)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
@ -159,7 +157,7 @@ static void __init patch_vdso(void *ehdr)
|
||||||
* want programs to incur the slight additional overhead of
|
* want programs to incur the slight additional overhead of
|
||||||
* dispatching through the VDSO only to fall back to syscalls.
|
* 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_gettimeofday");
|
||||||
vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
|
vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
|
||||||
vdso_nullpatch_one(&einfo, "__vdso_clock_gettime64");
|
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 = VDSO_NR_PAGES; /* for the data/vvar pages */
|
||||||
vdso_total_pages += text_pages;
|
vdso_total_pages += text_pages;
|
||||||
|
|
||||||
cntvct_ok = cntvct_functional();
|
|
||||||
|
|
||||||
patch_vdso(vdso_start);
|
patch_vdso(vdso_start);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -926,9 +926,7 @@ config VDSO
|
||||||
default y if ARM_ARCH_TIMER
|
default y if ARM_ARCH_TIMER
|
||||||
select HAVE_GENERIC_VDSO
|
select HAVE_GENERIC_VDSO
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_VDSO_32
|
|
||||||
select GENERIC_GETTIMEOFDAY
|
select GENERIC_GETTIMEOFDAY
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
help
|
help
|
||||||
Place in the process address space an ELF shared object
|
Place in the process address space an ELF shared object
|
||||||
providing fast implementations of gettimeofday and
|
providing fast implementations of gettimeofday and
|
||||||
|
|
|
@ -166,8 +166,6 @@ config ARM64
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_GETTIMEOFDAY
|
select GENERIC_GETTIMEOFDAY
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
select GENERIC_VDSO_TIME_NS
|
|
||||||
select HARDIRQS_SW_RESEND
|
select HARDIRQS_SW_RESEND
|
||||||
select HAS_IOPORT
|
select HAS_IOPORT
|
||||||
select HAVE_MOVE_PMD
|
select HAVE_MOVE_PMD
|
||||||
|
@ -1750,7 +1748,6 @@ config COMPAT_VDSO
|
||||||
bool "Enable vDSO for 32-bit applications"
|
bool "Enable vDSO for 32-bit applications"
|
||||||
depends on !CPU_BIG_ENDIAN
|
depends on !CPU_BIG_ENDIAN
|
||||||
depends on (CC_IS_CLANG && LD_IS_LLD) || "$(CROSS_COMPILE_COMPAT)" != ""
|
depends on (CC_IS_CLANG && LD_IS_LLD) || "$(CROSS_COMPILE_COMPAT)" != ""
|
||||||
select GENERIC_COMPAT_VDSO
|
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Place in the process address space of 32-bit applications an
|
Place in the process address space of 32-bit applications an
|
||||||
|
|
|
@ -7,11 +7,10 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
/*
|
/*
|
||||||
* Warning: This code is meant to be used with
|
* Warning: This code is meant to be used from the compat vDSO only.
|
||||||
* ENABLE_COMPAT_VDSO only.
|
|
||||||
*/
|
*/
|
||||||
#ifndef ENABLE_COMPAT_VDSO
|
#ifdef __arch64__
|
||||||
#error This header is meant to be used with ENABLE_COMPAT_VDSO only
|
#error This header is meant to be used with from the compat vDSO only
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef dmb
|
#ifdef dmb
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 ARM Limited
|
* Copyright (C) 2018 ARM Limited
|
||||||
*/
|
*/
|
||||||
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
|
#ifndef __ASM_VDSO_COMPAT_GETTIMEOFDAY_H
|
||||||
#define __ASM_VDSO_GETTIMEOFDAY_H
|
#define __ASM_VDSO_COMPAT_GETTIMEOFDAY_H
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
@ -163,4 +163,4 @@ static inline bool vdso_clocksource_ok(const struct vdso_clock *vc)
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|
#endif /* __ASM_VDSO_COMPAT_GETTIMEOFDAY_H */
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
|
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
|
||||||
#define __ASM_VDSO_GETTIMEOFDAY_H
|
#define __ASM_VDSO_GETTIMEOFDAY_H
|
||||||
|
|
||||||
|
#ifdef __aarch64__
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <asm/alternative.h>
|
#include <asm/alternative.h>
|
||||||
|
@ -96,4 +98,10 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#else /* !__aarch64__ */
|
||||||
|
|
||||||
|
#include "compat_gettimeofday.h"
|
||||||
|
|
||||||
|
#endif /* __aarch64__ */
|
||||||
|
|
||||||
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|
||||||
|
|
|
@ -57,7 +57,6 @@ VDSO_CAFLAGS += -DDISABLE_BRANCH_PROFILING
|
||||||
VDSO_CAFLAGS += -march=armv8-a
|
VDSO_CAFLAGS += -march=armv8-a
|
||||||
|
|
||||||
VDSO_CFLAGS := $(VDSO_CAFLAGS)
|
VDSO_CFLAGS := $(VDSO_CAFLAGS)
|
||||||
VDSO_CFLAGS += -DENABLE_COMPAT_VDSO=1
|
|
||||||
# KBUILD_CFLAGS from top-level Makefile
|
# KBUILD_CFLAGS from top-level Makefile
|
||||||
VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||||
-fno-strict-aliasing -fno-common \
|
-fno-strict-aliasing -fno-common \
|
||||||
|
|
|
@ -110,8 +110,6 @@ config LOONGARCH
|
||||||
select GENERIC_SCHED_CLOCK
|
select GENERIC_SCHED_CLOCK
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
select GENERIC_VDSO_TIME_NS
|
|
||||||
select GPIOLIB
|
select GPIOLIB
|
||||||
select HAS_IOPORT
|
select HAS_IOPORT
|
||||||
select HAVE_ARCH_AUDITSYSCALL
|
select HAVE_ARCH_AUDITSYSCALL
|
||||||
|
|
|
@ -51,7 +51,6 @@ config MIPS
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_IDLE_POLL_SETUP
|
select GENERIC_IDLE_POLL_SETUP
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
select GUP_GET_PXX_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
|
select GUP_GET_PXX_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
|
||||||
select HAS_IOPORT if !NO_IOPORT_MAP || ISA
|
select HAS_IOPORT if !NO_IOPORT_MAP || ISA
|
||||||
select HAVE_ARCH_COMPILER_H
|
select HAVE_ARCH_COMPILER_H
|
||||||
|
|
|
@ -210,8 +210,6 @@ config PPC
|
||||||
select GENERIC_PCI_IOMAP if PCI
|
select GENERIC_PCI_IOMAP if PCI
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
select GENERIC_VDSO_TIME_NS
|
|
||||||
select HAS_IOPORT if PCI
|
select HAS_IOPORT if PCI
|
||||||
select HAVE_ARCH_AUDITSYSCALL
|
select HAVE_ARCH_AUDITSYSCALL
|
||||||
select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
|
select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
|
||||||
|
|
|
@ -53,7 +53,7 @@ config RISCV
|
||||||
select ARCH_HAS_SYSCALL_WRAPPER
|
select ARCH_HAS_SYSCALL_WRAPPER
|
||||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||||
select ARCH_HAS_UBSAN
|
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_HAVE_NMI_SAFE_CMPXCHG
|
||||||
select ARCH_KEEP_MEMBLOCK if ACPI
|
select ARCH_KEEP_MEMBLOCK if ACPI
|
||||||
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if 64BIT && MMU
|
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if 64BIT && MMU
|
||||||
|
@ -110,7 +110,7 @@ config RISCV
|
||||||
select GENERIC_CPU_VULNERABILITIES
|
select GENERIC_CPU_VULNERABILITIES
|
||||||
select GENERIC_EARLY_IOREMAP
|
select GENERIC_EARLY_IOREMAP
|
||||||
select GENERIC_ENTRY
|
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_IDLE_POLL_SETUP
|
||||||
select GENERIC_IOREMAP if MMU
|
select GENERIC_IOREMAP if MMU
|
||||||
select GENERIC_IRQ_IPI if SMP
|
select GENERIC_IRQ_IPI if SMP
|
||||||
|
@ -123,9 +123,7 @@ config RISCV
|
||||||
select GENERIC_PCI_IOMAP
|
select GENERIC_PCI_IOMAP
|
||||||
select GENERIC_SCHED_CLOCK
|
select GENERIC_SCHED_CLOCK
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
|
select GENERIC_TIME_VSYSCALL if GENERIC_GETTIMEOFDAY
|
||||||
select GENERIC_VDSO_DATA_STORE if MMU
|
|
||||||
select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
|
|
||||||
select HARDIRQS_SW_RESEND
|
select HARDIRQS_SW_RESEND
|
||||||
select HAS_IOPORT if MMU
|
select HAS_IOPORT if MMU
|
||||||
select HAVE_ALIGNED_STRUCT_PAGE
|
select HAVE_ALIGNED_STRUCT_PAGE
|
||||||
|
@ -169,7 +167,7 @@ config RISCV
|
||||||
select HAVE_FUNCTION_ARG_ACCESS_API
|
select HAVE_FUNCTION_ARG_ACCESS_API
|
||||||
select HAVE_FUNCTION_ERROR_INJECTION
|
select HAVE_FUNCTION_ERROR_INJECTION
|
||||||
select HAVE_GCC_PLUGINS
|
select HAVE_GCC_PLUGINS
|
||||||
select HAVE_GENERIC_VDSO if MMU && 64BIT
|
select HAVE_GENERIC_VDSO if MMU
|
||||||
select HAVE_IRQ_TIME_ACCOUNTING
|
select HAVE_IRQ_TIME_ACCOUNTING
|
||||||
select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
|
select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
|
||||||
select HAVE_KERNEL_GZIP 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 THREAD_INFO_IN_TASK
|
||||||
select TRACE_IRQFLAGS_SUPPORT
|
select TRACE_IRQFLAGS_SUPPORT
|
||||||
select UACCESS_MEMCPY if !MMU
|
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 USER_STACKTRACE_SUPPORT
|
||||||
select ZONE_DMA32 if 64BIT
|
select ZONE_DMA32 if 64BIT
|
||||||
|
|
||||||
|
|
|
@ -174,8 +174,6 @@ config S390
|
||||||
select GENERIC_GETTIMEOFDAY
|
select GENERIC_GETTIMEOFDAY
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
select GENERIC_VDSO_TIME_NS
|
|
||||||
select GENERIC_IOREMAP if PCI
|
select GENERIC_IOREMAP if PCI
|
||||||
select HAVE_ALIGNED_STRUCT_PAGE
|
select HAVE_ALIGNED_STRUCT_PAGE
|
||||||
select HAVE_ARCH_AUDITSYSCALL
|
select HAVE_ARCH_AUDITSYSCALL
|
||||||
|
|
|
@ -14,7 +14,6 @@ config X86_32
|
||||||
select ARCH_WANT_IPC_PARSE_VERSION
|
select ARCH_WANT_IPC_PARSE_VERSION
|
||||||
select CLKSRC_I8253
|
select CLKSRC_I8253
|
||||||
select CLONE_BACKWARDS
|
select CLONE_BACKWARDS
|
||||||
select GENERIC_VDSO_32
|
|
||||||
select HAVE_DEBUG_STACKOVERFLOW
|
select HAVE_DEBUG_STACKOVERFLOW
|
||||||
select KMAP_LOCAL
|
select KMAP_LOCAL
|
||||||
select MODULES_USE_ELF_REL
|
select MODULES_USE_ELF_REL
|
||||||
|
@ -182,8 +181,6 @@ config X86
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GENERIC_GETTIMEOFDAY
|
select GENERIC_GETTIMEOFDAY
|
||||||
select GENERIC_VDSO_DATA_STORE
|
|
||||||
select GENERIC_VDSO_TIME_NS
|
|
||||||
select GENERIC_VDSO_OVERFLOW_PROTECT
|
select GENERIC_VDSO_OVERFLOW_PROTECT
|
||||||
select GUP_GET_PXX_LOW_HIGH if X86_PAE
|
select GUP_GET_PXX_LOW_HIGH if X86_PAE
|
||||||
select HARDIRQS_SW_RESEND
|
select HARDIRQS_SW_RESEND
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
|
|
||||||
|
|
||||||
#ifndef __arch_get_vdso_u_time_data
|
#ifndef __arch_get_vdso_u_time_data
|
||||||
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
|
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
|
||||||
|
|
||||||
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
|
|
||||||
|
|
||||||
#ifndef __arch_update_vdso_clock
|
#ifndef __arch_update_vdso_clock
|
||||||
static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
|
static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct arch_vdso_time_data {};
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)
|
#if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)
|
||||||
#include <asm/vdso/arch_data.h>
|
#include <asm/vdso/arch_data.h>
|
||||||
#elif defined(CONFIG_GENERIC_VDSO_DATA_STORE)
|
#else
|
||||||
struct vdso_arch_data {
|
struct vdso_arch_data {
|
||||||
/* Needed for the generic code, never actually used at runtime */
|
/* Needed for the generic code, never actually used at runtime */
|
||||||
char __unused;
|
char __unused;
|
||||||
|
@ -164,7 +164,6 @@ struct vdso_rng_data {
|
||||||
* With the hidden visibility, the compiler simply generates a PC-relative
|
* With the hidden visibility, the compiler simply generates a PC-relative
|
||||||
* relocation, and this is what we need.
|
* 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_time_data vdso_u_time_data __attribute__((visibility("hidden")));
|
||||||
extern struct vdso_rng_data vdso_u_rng_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")));
|
extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));
|
||||||
|
@ -185,8 +184,6 @@ enum vdso_pages {
|
||||||
VDSO_NR_PAGES
|
VDSO_NR_PAGES
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The generic vDSO implementation requires that gettimeofday.h
|
* The generic vDSO implementation requires that gettimeofday.h
|
||||||
* provides:
|
* provides:
|
||||||
|
@ -196,11 +193,7 @@ enum vdso_pages {
|
||||||
* - clock_gettime_fallback(): fallback for clock_gettime.
|
* - clock_gettime_fallback(): fallback for clock_gettime.
|
||||||
* - clock_getres_fallback(): fallback for clock_getres.
|
* - clock_getres_fallback(): fallback for clock_getres.
|
||||||
*/
|
*/
|
||||||
#ifdef ENABLE_COMPAT_VDSO
|
|
||||||
#include <asm/vdso/compat_gettimeofday.h>
|
|
||||||
#else
|
|
||||||
#include <asm/vdso/gettimeofday.h>
|
#include <asm/vdso/gettimeofday.h>
|
||||||
#endif /* ENABLE_COMPAT_VDSO */
|
|
||||||
|
|
||||||
#else /* !__ASSEMBLY__ */
|
#else /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
struct __kernel_timespec;
|
struct __kernel_timespec;
|
||||||
|
struct __kernel_old_timeval;
|
||||||
struct timezone;
|
struct timezone;
|
||||||
|
|
||||||
#if !defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64)
|
#if !defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64)
|
||||||
|
|
|
@ -1363,7 +1363,7 @@ config UTS_NS
|
||||||
|
|
||||||
config TIME_NS
|
config TIME_NS
|
||||||
bool "TIME namespace"
|
bool "TIME namespace"
|
||||||
depends on GENERIC_VDSO_TIME_NS
|
depends on GENERIC_GETTIMEOFDAY
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
In this namespace boottime and monotonic clocks can be set.
|
In this namespace boottime and monotonic clocks can be set.
|
||||||
|
|
|
@ -26,7 +26,7 @@ obj-$(CONFIG_LEGACY_TIMER_TICK) += tick-legacy.o
|
||||||
ifeq ($(CONFIG_SMP),y)
|
ifeq ($(CONFIG_SMP),y)
|
||||||
obj-$(CONFIG_NO_HZ_COMMON) += timer_migration.o
|
obj-$(CONFIG_NO_HZ_COMMON) += timer_migration.o
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_HAVE_GENERIC_VDSO) += vsyscall.o
|
obj-$(CONFIG_GENERIC_GETTIMEOFDAY) += vsyscall.o
|
||||||
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
|
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
|
||||||
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
|
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
|
||||||
obj-$(CONFIG_TIME_NS) += namespace.o
|
obj-$(CONFIG_TIME_NS) += namespace.o
|
||||||
|
|
|
@ -12,24 +12,6 @@ config GENERIC_GETTIMEOFDAY
|
||||||
Each architecture that enables this feature has to
|
Each architecture that enables this feature has to
|
||||||
provide the fallback implementation.
|
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
|
config GENERIC_VDSO_OVERFLOW_PROTECT
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
|
@ -37,14 +19,9 @@ config GENERIC_VDSO_OVERFLOW_PROTECT
|
||||||
time getter functions for the price of an extra conditional
|
time getter functions for the price of an extra conditional
|
||||||
in the hotpath.
|
in the hotpath.
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
config VDSO_GETRANDOM
|
config VDSO_GETRANDOM
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
Selected by architectures that support vDSO getrandom().
|
Selected by architectures that support vDSO getrandom().
|
||||||
|
|
||||||
config GENERIC_VDSO_DATA_STORE
|
endif
|
||||||
bool
|
|
||||||
help
|
|
||||||
Selected by architectures that use the generic vDSO data store.
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
obj-$(CONFIG_GENERIC_VDSO_DATA_STORE) += datastore.o
|
obj-$(CONFIG_HAVE_GENERIC_VDSO) += datastore.o
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
/*
|
/*
|
||||||
* The vDSO data page.
|
* The vDSO data page.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_HAVE_GENERIC_VDSO
|
#ifdef CONFIG_GENERIC_GETTIMEOFDAY
|
||||||
static union {
|
static union {
|
||||||
struct vdso_time_data data;
|
struct vdso_time_data data;
|
||||||
u8 page[PAGE_SIZE];
|
u8 page[PAGE_SIZE];
|
||||||
} vdso_time_data_store __page_aligned_data;
|
} vdso_time_data_store __page_aligned_data;
|
||||||
struct vdso_time_data *vdso_k_time_data = &vdso_time_data_store.data;
|
struct vdso_time_data *vdso_k_time_data = &vdso_time_data_store.data;
|
||||||
static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
|
static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
|
||||||
#endif /* CONFIG_HAVE_GENERIC_VDSO */
|
#endif /* CONFIG_GENERIC_GETTIMEOFDAY */
|
||||||
|
|
||||||
#ifdef CONFIG_VDSO_GETRANDOM
|
#ifdef CONFIG_VDSO_GETRANDOM
|
||||||
static union {
|
static union {
|
||||||
|
@ -46,7 +46,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
|
||||||
|
|
||||||
switch (vmf->pgoff) {
|
switch (vmf->pgoff) {
|
||||||
case VDSO_TIME_PAGE_OFFSET:
|
case VDSO_TIME_PAGE_OFFSET:
|
||||||
if (!IS_ENABLED(CONFIG_HAVE_GENERIC_VDSO))
|
if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY))
|
||||||
return VM_FAULT_SIGBUS;
|
return VM_FAULT_SIGBUS;
|
||||||
pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
|
pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
|
||||||
if (timens_page) {
|
if (timens_page) {
|
||||||
|
|
|
@ -108,15 +108,11 @@ bool vdso_get_timestamp(const struct vdso_time_data *vd, const struct vdso_clock
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TIME_NS
|
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
|
|
||||||
static __always_inline
|
static __always_inline
|
||||||
const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_time_data *vd)
|
const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_time_data *vd)
|
||||||
{
|
{
|
||||||
return (void *)vd + PAGE_SIZE;
|
return (void *)vd + PAGE_SIZE;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
|
|
||||||
|
|
||||||
static __always_inline
|
static __always_inline
|
||||||
bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
|
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;
|
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
|
static __always_inline
|
||||||
bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TIME_NS
|
|
||||||
static __always_inline
|
static __always_inline
|
||||||
bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
|
bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
|
||||||
clockid_t clk, struct __kernel_timespec *ts)
|
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;
|
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
|
static __always_inline
|
||||||
bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
|
bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
|
||||||
|
|
|
@ -4,6 +4,5 @@ CONFIG_USER_NS=y
|
||||||
CONFIG_PID_NS=y
|
CONFIG_PID_NS=y
|
||||||
CONFIG_NET_NS=y
|
CONFIG_NET_NS=y
|
||||||
CONFIG_TIME_NS=y
|
CONFIG_TIME_NS=y
|
||||||
CONFIG_GENERIC_VDSO_TIME_NS=y
|
|
||||||
CONFIG_CGROUPS=y
|
CONFIG_CGROUPS=y
|
||||||
CONFIG_CHECKPOINT_RESTORE=y
|
CONFIG_CHECKPOINT_RESTORE=y
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
vdso_test
|
vdso_test
|
||||||
vdso_test_abi
|
vdso_test_abi
|
||||||
vdso_test_clock_getres
|
|
||||||
vdso_test_correctness
|
vdso_test_correctness
|
||||||
vdso_test_gettimeofday
|
vdso_test_gettimeofday
|
||||||
vdso_test_getcpu
|
vdso_test_getcpu
|
||||||
|
|
|
@ -4,7 +4,6 @@ include ../../../scripts/Makefile.arch
|
||||||
TEST_GEN_PROGS := vdso_test_gettimeofday
|
TEST_GEN_PROGS := vdso_test_gettimeofday
|
||||||
TEST_GEN_PROGS += vdso_test_getcpu
|
TEST_GEN_PROGS += vdso_test_getcpu
|
||||||
TEST_GEN_PROGS += vdso_test_abi
|
TEST_GEN_PROGS += vdso_test_abi
|
||||||
TEST_GEN_PROGS += vdso_test_clock_getres
|
|
||||||
ifeq ($(ARCH),$(filter $(ARCH),x86 x86_64))
|
ifeq ($(ARCH),$(filter $(ARCH),x86 x86_64))
|
||||||
TEST_GEN_PROGS += vdso_standalone_test_x86
|
TEST_GEN_PROGS += vdso_standalone_test_x86
|
||||||
endif
|
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_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c
|
||||||
$(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.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_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: vdso_standalone_test_x86.c parse_vdso.c | headers
|
||||||
$(OUTPUT)/vdso_standalone_test_x86: CFLAGS:=$(CFLAGS_NOLIBC) $(CFLAGS)
|
$(OUTPUT)/vdso_standalone_test_x86: CFLAGS:=$(CFLAGS_NOLIBC) $(CFLAGS)
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
register long _r6 asm ("r6"); \
|
register long _r6 asm ("r6"); \
|
||||||
register long _r7 asm ("r7"); \
|
register long _r7 asm ("r7"); \
|
||||||
register long _r8 asm ("r8"); \
|
register long _r8 asm ("r8"); \
|
||||||
register long _rval asm ("r3"); \
|
|
||||||
\
|
\
|
||||||
LOADARGS_##nr(fn, args); \
|
LOADARGS_##nr(fn, args); \
|
||||||
\
|
\
|
||||||
|
@ -54,13 +53,13 @@
|
||||||
" bns+ 1f\n" \
|
" bns+ 1f\n" \
|
||||||
" neg 3, 3\n" \
|
" neg 3, 3\n" \
|
||||||
"1:" \
|
"1:" \
|
||||||
: "+r" (_r0), "=r" (_r3), "+r" (_r4), "+r" (_r5), \
|
: "+r" (_r0), "+r" (_r3), "+r" (_r4), "+r" (_r5), \
|
||||||
"+r" (_r6), "+r" (_r7), "+r" (_r8) \
|
"+r" (_r6), "+r" (_r7), "+r" (_r8) \
|
||||||
: "r" (_rval) \
|
: \
|
||||||
: "r9", "r10", "r11", "r12", "cr0", "cr1", "cr5", \
|
: "r9", "r10", "r11", "r12", "cr0", "cr1", "cr5", \
|
||||||
"cr6", "cr7", "xer", "lr", "ctr", "memory" \
|
"cr6", "cr7", "xer", "lr", "ctr", "memory" \
|
||||||
); \
|
); \
|
||||||
_rval; \
|
_r3; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -26,24 +26,31 @@
|
||||||
static const char *version;
|
static const char *version;
|
||||||
static const char **name;
|
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_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_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 long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
|
||||||
typedef time_t (*vdso_time_t)(time_t *t);
|
typedef time_t (*vdso_time_t)(time_t *t);
|
||||||
|
|
||||||
const char *vdso_clock_name[12] = {
|
static const char * const vdso_clock_name[] = {
|
||||||
"CLOCK_REALTIME",
|
[CLOCK_REALTIME] = "CLOCK_REALTIME",
|
||||||
"CLOCK_MONOTONIC",
|
[CLOCK_MONOTONIC] = "CLOCK_MONOTONIC",
|
||||||
"CLOCK_PROCESS_CPUTIME_ID",
|
[CLOCK_PROCESS_CPUTIME_ID] = "CLOCK_PROCESS_CPUTIME_ID",
|
||||||
"CLOCK_THREAD_CPUTIME_ID",
|
[CLOCK_THREAD_CPUTIME_ID] = "CLOCK_THREAD_CPUTIME_ID",
|
||||||
"CLOCK_MONOTONIC_RAW",
|
[CLOCK_MONOTONIC_RAW] = "CLOCK_MONOTONIC_RAW",
|
||||||
"CLOCK_REALTIME_COARSE",
|
[CLOCK_REALTIME_COARSE] = "CLOCK_REALTIME_COARSE",
|
||||||
"CLOCK_MONOTONIC_COARSE",
|
[CLOCK_MONOTONIC_COARSE] = "CLOCK_MONOTONIC_COARSE",
|
||||||
"CLOCK_BOOTTIME",
|
[CLOCK_BOOTTIME] = "CLOCK_BOOTTIME",
|
||||||
"CLOCK_REALTIME_ALARM",
|
[CLOCK_REALTIME_ALARM] = "CLOCK_REALTIME_ALARM",
|
||||||
"CLOCK_BOOTTIME_ALARM",
|
[CLOCK_BOOTTIME_ALARM] = "CLOCK_BOOTTIME_ALARM",
|
||||||
"CLOCK_SGI_CYCLE",
|
[10 /* CLOCK_SGI_CYCLE */] = "CLOCK_SGI_CYCLE",
|
||||||
"CLOCK_TAI",
|
[CLOCK_TAI] = "CLOCK_TAI",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vdso_test_gettimeofday(void)
|
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)
|
static void vdso_test_clock_gettime(clockid_t clk_id)
|
||||||
{
|
{
|
||||||
/* Find clock_gettime. */
|
/* 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]);
|
ksft_print_msg("clock_id: %s\n", vdso_clock_name[clock_id]);
|
||||||
|
|
||||||
vdso_test_clock_gettime(clock_id);
|
vdso_test_clock_gettime(clock_id);
|
||||||
|
vdso_test_clock_gettime64(clock_id);
|
||||||
|
|
||||||
vdso_test_clock_getres(clock_id);
|
vdso_test_clock_getres(clock_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VDSO_TEST_PLAN 16
|
#define VDSO_TEST_PLAN 29
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
|
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
|
||||||
|
|
||||||
ksft_print_header();
|
ksft_print_header();
|
||||||
ksft_set_plan(VDSO_TEST_PLAN);
|
|
||||||
|
|
||||||
if (!sysinfo_ehdr) {
|
if (!sysinfo_ehdr)
|
||||||
ksft_print_msg("AT_SYSINFO_EHDR is not present!\n");
|
ksft_exit_skip("AT_SYSINFO_EHDR is not present!\n");
|
||||||
return KSFT_SKIP;
|
|
||||||
}
|
ksft_set_plan(VDSO_TEST_PLAN);
|
||||||
|
|
||||||
version = versions[VDSO_VERSION];
|
version = versions[VDSO_VERSION];
|
||||||
name = (const char **)&names[VDSO_NAMES];
|
name = (const char **)&names[VDSO_NAMES];
|
||||||
|
@ -198,40 +232,17 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
vdso_test_gettimeofday();
|
vdso_test_gettimeofday();
|
||||||
|
|
||||||
#if _POSIX_TIMERS > 0
|
|
||||||
|
|
||||||
#ifdef CLOCK_REALTIME
|
|
||||||
vdso_test_clock(CLOCK_REALTIME);
|
vdso_test_clock(CLOCK_REALTIME);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOCK_BOOTTIME
|
|
||||||
vdso_test_clock(CLOCK_BOOTTIME);
|
vdso_test_clock(CLOCK_BOOTTIME);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOCK_TAI
|
|
||||||
vdso_test_clock(CLOCK_TAI);
|
vdso_test_clock(CLOCK_TAI);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOCK_REALTIME_COARSE
|
|
||||||
vdso_test_clock(CLOCK_REALTIME_COARSE);
|
vdso_test_clock(CLOCK_REALTIME_COARSE);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOCK_MONOTONIC
|
|
||||||
vdso_test_clock(CLOCK_MONOTONIC);
|
vdso_test_clock(CLOCK_MONOTONIC);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOCK_MONOTONIC_RAW
|
|
||||||
vdso_test_clock(CLOCK_MONOTONIC_RAW);
|
vdso_test_clock(CLOCK_MONOTONIC_RAW);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOCK_MONOTONIC_COARSE
|
|
||||||
vdso_test_clock(CLOCK_MONOTONIC_COARSE);
|
vdso_test_clock(CLOCK_MONOTONIC_COARSE);
|
||||||
#endif
|
vdso_test_clock(CLOCK_PROCESS_CPUTIME_ID);
|
||||||
|
vdso_test_clock(CLOCK_THREAD_CPUTIME_ID);
|
||||||
#endif
|
|
||||||
|
|
||||||
vdso_test_time();
|
vdso_test_time();
|
||||||
|
|
||||||
ksft_print_cnts();
|
ksft_finished();
|
||||||
return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue