1 // SPDX-License-Identifier: GPL-2.0
11 #include <sys/syscall.h>
17 typedef int (*vgettime_t
)(clockid_t
, struct timespec
*);
19 vgettime_t vdso_clock_gettime
;
21 static void fill_function_pointers(void)
23 void *vdso
= dlopen("linux-vdso.so.1",
24 RTLD_LAZY
| RTLD_LOCAL
| RTLD_NOLOAD
);
26 vdso
= dlopen("linux-gate.so.1",
27 RTLD_LAZY
| RTLD_LOCAL
| RTLD_NOLOAD
);
29 pr_err("[WARN]\tfailed to find vDSO\n");
33 vdso_clock_gettime
= (vgettime_t
)dlsym(vdso
, "__vdso_clock_gettime");
34 if (!vdso_clock_gettime
)
35 pr_err("Warning: failed to find clock_gettime in vDSO\n");
39 static void test(clock_t clockid
, char *clockstr
, bool in_ns
)
41 struct timespec tp
, start
;
43 const int timeout
= 3;
45 vdso_clock_gettime(clockid
, &start
);
47 for (tp
= start
; start
.tv_sec
+ timeout
> tp
.tv_sec
||
48 (start
.tv_sec
+ timeout
== tp
.tv_sec
&&
49 start
.tv_nsec
> tp
.tv_nsec
); i
++) {
50 vdso_clock_gettime(clockid
, &tp
);
53 ksft_test_result_pass("%s:\tclock: %10s\tcycles:\t%10ld\n",
54 in_ns
? "ns" : "host", clockstr
, i
);
57 int main(int argc
, char *argv
[])
64 fill_function_pointers();
66 test(CLOCK_MONOTONIC
, "monotonic", false);
67 test(CLOCK_MONOTONIC_COARSE
, "monotonic-coarse", false);
68 test(CLOCK_MONOTONIC_RAW
, "monotonic-raw", false);
69 test(CLOCK_BOOTTIME
, "boottime", false);
76 nsfd
= open("/proc/self/ns/time_for_children", O_RDONLY
);
78 return pr_perror("Can't open a time namespace");
80 if (_settime(CLOCK_MONOTONIC
, offset
))
82 if (_settime(CLOCK_BOOTTIME
, offset
))
85 if (setns(nsfd
, CLONE_NEWTIME
))
86 return pr_perror("setns");
88 test(CLOCK_MONOTONIC
, "monotonic", true);
89 test(CLOCK_MONOTONIC_COARSE
, "monotonic-coarse", true);
90 test(CLOCK_MONOTONIC_RAW
, "monotonic-raw", true);
91 test(CLOCK_BOOTTIME
, "boottime", true);