Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kselftest: Extend vDSO selftest to clock_getres

The current version of the multiarch vDSO selftest verifies only
gettimeofday.

Extend the vDSO selftest to clock_getres, to verify that the
syscall and the vDSO library function return the same information.

The extension has been used to verify the hrtimer_resoltion fix.

Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Vincenzo Frascino and committed by
Shuah Khan
03f55c79 693f5ca0

+126
+2
tools/testing/selftests/vDSO/Makefile
··· 6 6 7 7 TEST_GEN_PROGS := $(OUTPUT)/vdso_test_gettimeofday $(OUTPUT)/vdso_test_getcpu 8 8 TEST_GEN_PROGS += $(OUTPUT)/vdso_test_abi 9 + TEST_GEN_PROGS += $(OUTPUT)/vdso_test_clock_getres 9 10 ifeq ($(ARCH),x86) 10 11 TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86 11 12 endif ··· 21 20 $(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c 22 21 $(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.c 23 22 $(OUTPUT)/vdso_test_abi: parse_vdso.c vdso_test_abi.c 23 + $(OUTPUT)/vdso_test_clock_getres: vdso_test_clock_getres.c 24 24 $(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c 25 25 $(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \ 26 26 vdso_standalone_test_x86.c parse_vdso.c \
+124
tools/testing/selftests/vDSO/vdso_test_clock_getres.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note 2 + /* 3 + * vdso_clock_getres.c: Sample code to test clock_getres. 4 + * Copyright (c) 2019 Arm Ltd. 5 + * 6 + * Compile with: 7 + * gcc -std=gnu99 vdso_clock_getres.c 8 + * 9 + * Tested on ARM, ARM64, MIPS32, x86 (32-bit and 64-bit), 10 + * Power (32-bit and 64-bit), S390x (32-bit and 64-bit). 11 + * Might work on other architectures. 12 + */ 13 + 14 + #define _GNU_SOURCE 15 + #include <elf.h> 16 + #include <err.h> 17 + #include <fcntl.h> 18 + #include <stdint.h> 19 + #include <stdio.h> 20 + #include <stdlib.h> 21 + #include <time.h> 22 + #include <sys/auxv.h> 23 + #include <sys/mman.h> 24 + #include <sys/time.h> 25 + #include <unistd.h> 26 + #include <sys/syscall.h> 27 + 28 + #include "../kselftest.h" 29 + 30 + static long syscall_clock_getres(clockid_t _clkid, struct timespec *_ts) 31 + { 32 + long ret; 33 + 34 + ret = syscall(SYS_clock_getres, _clkid, _ts); 35 + 36 + return ret; 37 + } 38 + 39 + const char *vdso_clock_name[12] = { 40 + "CLOCK_REALTIME", 41 + "CLOCK_MONOTONIC", 42 + "CLOCK_PROCESS_CPUTIME_ID", 43 + "CLOCK_THREAD_CPUTIME_ID", 44 + "CLOCK_MONOTONIC_RAW", 45 + "CLOCK_REALTIME_COARSE", 46 + "CLOCK_MONOTONIC_COARSE", 47 + "CLOCK_BOOTTIME", 48 + "CLOCK_REALTIME_ALARM", 49 + "CLOCK_BOOTTIME_ALARM", 50 + "CLOCK_SGI_CYCLE", 51 + "CLOCK_TAI", 52 + }; 53 + 54 + /* 55 + * This function calls clock_getres in vdso and by system call 56 + * with different values for clock_id. 57 + * 58 + * Example of output: 59 + * 60 + * clock_id: CLOCK_REALTIME [PASS] 61 + * clock_id: CLOCK_BOOTTIME [PASS] 62 + * clock_id: CLOCK_TAI [PASS] 63 + * clock_id: CLOCK_REALTIME_COARSE [PASS] 64 + * clock_id: CLOCK_MONOTONIC [PASS] 65 + * clock_id: CLOCK_MONOTONIC_RAW [PASS] 66 + * clock_id: CLOCK_MONOTONIC_COARSE [PASS] 67 + */ 68 + static inline int vdso_test_clock(unsigned int clock_id) 69 + { 70 + struct timespec x, y; 71 + 72 + printf("clock_id: %s", vdso_clock_name[clock_id]); 73 + clock_getres(clock_id, &x); 74 + syscall_clock_getres(clock_id, &y); 75 + 76 + if ((x.tv_sec != y.tv_sec) || (x.tv_nsec != y.tv_nsec)) { 77 + printf(" [FAIL]\n"); 78 + return KSFT_FAIL; 79 + } 80 + 81 + printf(" [PASS]\n"); 82 + return KSFT_PASS; 83 + } 84 + 85 + int main(int argc, char **argv) 86 + { 87 + int ret; 88 + 89 + #if _POSIX_TIMERS > 0 90 + 91 + #ifdef CLOCK_REALTIME 92 + ret = vdso_test_clock(CLOCK_REALTIME); 93 + #endif 94 + 95 + #ifdef CLOCK_BOOTTIME 96 + ret += vdso_test_clock(CLOCK_BOOTTIME); 97 + #endif 98 + 99 + #ifdef CLOCK_TAI 100 + ret += vdso_test_clock(CLOCK_TAI); 101 + #endif 102 + 103 + #ifdef CLOCK_REALTIME_COARSE 104 + ret += vdso_test_clock(CLOCK_REALTIME_COARSE); 105 + #endif 106 + 107 + #ifdef CLOCK_MONOTONIC 108 + ret += vdso_test_clock(CLOCK_MONOTONIC); 109 + #endif 110 + 111 + #ifdef CLOCK_MONOTONIC_RAW 112 + ret += vdso_test_clock(CLOCK_MONOTONIC_RAW); 113 + #endif 114 + 115 + #ifdef CLOCK_MONOTONIC_COARSE 116 + ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE); 117 + #endif 118 + 119 + #endif 120 + if (ret > 0) 121 + return KSFT_FAIL; 122 + 123 + return KSFT_PASS; 124 + }