~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/vDSO/vdso_test_abi.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * vdso_full_test.c: Sample code to test all the timers.
  4  * Copyright (c) 2019 Arm Ltd.
  5  *
  6  * Compile with:
  7  * gcc -std=gnu99 vdso_full_test.c parse_vdso.c
  8  *
  9  */
 10 
 11 #include <stdint.h>
 12 #include <elf.h>
 13 #include <stdio.h>
 14 #include <time.h>
 15 #include <sys/auxv.h>
 16 #include <sys/time.h>
 17 #define _GNU_SOURCE
 18 #include <unistd.h>
 19 #include <sys/syscall.h>
 20 
 21 #include "../kselftest.h"
 22 #include "vdso_config.h"
 23 
 24 extern void *vdso_sym(const char *version, const char *name);
 25 extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
 26 extern void vdso_init_from_auxv(void *auxv);
 27 
 28 static const char *version;
 29 static const char **name;
 30 
 31 typedef long (*vdso_gettimeofday_t)(struct timeval *tv, struct timezone *tz);
 32 typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
 33 typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
 34 typedef time_t (*vdso_time_t)(time_t *t);
 35 
 36 const char *vdso_clock_name[12] = {
 37         "CLOCK_REALTIME",
 38         "CLOCK_MONOTONIC",
 39         "CLOCK_PROCESS_CPUTIME_ID",
 40         "CLOCK_THREAD_CPUTIME_ID",
 41         "CLOCK_MONOTONIC_RAW",
 42         "CLOCK_REALTIME_COARSE",
 43         "CLOCK_MONOTONIC_COARSE",
 44         "CLOCK_BOOTTIME",
 45         "CLOCK_REALTIME_ALARM",
 46         "CLOCK_BOOTTIME_ALARM",
 47         "CLOCK_SGI_CYCLE",
 48         "CLOCK_TAI",
 49 };
 50 
 51 static void vdso_test_gettimeofday(void)
 52 {
 53         /* Find gettimeofday. */
 54         vdso_gettimeofday_t vdso_gettimeofday =
 55                 (vdso_gettimeofday_t)vdso_sym(version, name[0]);
 56 
 57         if (!vdso_gettimeofday) {
 58                 ksft_print_msg("Couldn't find %s\n", name[0]);
 59                 ksft_test_result_skip("%s\n", name[0]);
 60                 return;
 61         }
 62 
 63         struct timeval tv;
 64         long ret = vdso_gettimeofday(&tv, 0);
 65 
 66         if (ret == 0) {
 67                 ksft_print_msg("The time is %lld.%06lld\n",
 68                                (long long)tv.tv_sec, (long long)tv.tv_usec);
 69                 ksft_test_result_pass("%s\n", name[0]);
 70         } else {
 71                 ksft_test_result_fail("%s\n", name[0]);
 72         }
 73 }
 74 
 75 static void vdso_test_clock_gettime(clockid_t clk_id)
 76 {
 77         /* Find clock_gettime. */
 78         vdso_clock_gettime_t vdso_clock_gettime =
 79                 (vdso_clock_gettime_t)vdso_sym(version, name[1]);
 80 
 81         if (!vdso_clock_gettime) {
 82                 ksft_print_msg("Couldn't find %s\n", name[1]);
 83                 ksft_test_result_skip("%s %s\n", name[1],
 84                                       vdso_clock_name[clk_id]);
 85                 return;
 86         }
 87 
 88         struct timespec ts;
 89         long ret = vdso_clock_gettime(clk_id, &ts);
 90 
 91         if (ret == 0) {
 92                 ksft_print_msg("The time is %lld.%06lld\n",
 93                                (long long)ts.tv_sec, (long long)ts.tv_nsec);
 94                 ksft_test_result_pass("%s %s\n", name[1],
 95                                       vdso_clock_name[clk_id]);
 96         } else {
 97                 ksft_test_result_fail("%s %s\n", name[1],
 98                                       vdso_clock_name[clk_id]);
 99         }
100 }
101 
102 static void vdso_test_time(void)
103 {
104         /* Find time. */
105         vdso_time_t vdso_time =
106                 (vdso_time_t)vdso_sym(version, name[2]);
107 
108         if (!vdso_time) {
109                 ksft_print_msg("Couldn't find %s\n", name[2]);
110                 ksft_test_result_skip("%s\n", name[2]);
111                 return;
112         }
113 
114         long ret = vdso_time(NULL);
115 
116         if (ret > 0) {
117                 ksft_print_msg("The time in hours since January 1, 1970 is %lld\n",
118                                 (long long)(ret / 3600));
119                 ksft_test_result_pass("%s\n", name[2]);
120         } else {
121                 ksft_test_result_fail("%s\n", name[2]);
122         }
123 }
124 
125 static void vdso_test_clock_getres(clockid_t clk_id)
126 {
127         int clock_getres_fail = 0;
128 
129         /* Find clock_getres. */
130         vdso_clock_getres_t vdso_clock_getres =
131                 (vdso_clock_getres_t)vdso_sym(version, name[3]);
132 
133         if (!vdso_clock_getres) {
134                 ksft_print_msg("Couldn't find %s\n", name[3]);
135                 ksft_test_result_skip("%s %s\n", name[3],
136                                       vdso_clock_name[clk_id]);
137                 return;
138         }
139 
140         struct timespec ts, sys_ts;
141         long ret = vdso_clock_getres(clk_id, &ts);
142 
143         if (ret == 0) {
144                 ksft_print_msg("The vdso resolution is %lld %lld\n",
145                                (long long)ts.tv_sec, (long long)ts.tv_nsec);
146         } else {
147                 clock_getres_fail++;
148         }
149 
150         ret = syscall(SYS_clock_getres, clk_id, &sys_ts);
151 
152         ksft_print_msg("The syscall resolution is %lld %lld\n",
153                         (long long)sys_ts.tv_sec, (long long)sys_ts.tv_nsec);
154 
155         if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec))
156                 clock_getres_fail++;
157 
158         if (clock_getres_fail > 0) {
159                 ksft_test_result_fail("%s %s\n", name[3],
160                                       vdso_clock_name[clk_id]);
161         } else {
162                 ksft_test_result_pass("%s %s\n", name[3],
163                                       vdso_clock_name[clk_id]);
164         }
165 }
166 
167 /*
168  * This function calls vdso_test_clock_gettime and vdso_test_clock_getres
169  * with different values for clock_id.
170  */
171 static inline void vdso_test_clock(clockid_t clock_id)
172 {
173         ksft_print_msg("clock_id: %s\n", vdso_clock_name[clock_id]);
174 
175         vdso_test_clock_gettime(clock_id);
176 
177         vdso_test_clock_getres(clock_id);
178 }
179 
180 #define VDSO_TEST_PLAN  16
181 
182 int main(int argc, char **argv)
183 {
184         unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
185 
186         ksft_print_header();
187         ksft_set_plan(VDSO_TEST_PLAN);
188 
189         if (!sysinfo_ehdr) {
190                 ksft_print_msg("AT_SYSINFO_EHDR is not present!\n");
191                 return KSFT_SKIP;
192         }
193 
194         version = versions[VDSO_VERSION];
195         name = (const char **)&names[VDSO_NAMES];
196 
197         ksft_print_msg("[vDSO kselftest] VDSO_VERSION: %s\n", version);
198 
199         vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
200 
201         vdso_test_gettimeofday();
202 
203 #if _POSIX_TIMERS > 0
204 
205 #ifdef CLOCK_REALTIME
206         vdso_test_clock(CLOCK_REALTIME);
207 #endif
208 
209 #ifdef CLOCK_BOOTTIME
210         vdso_test_clock(CLOCK_BOOTTIME);
211 #endif
212 
213 #ifdef CLOCK_TAI
214         vdso_test_clock(CLOCK_TAI);
215 #endif
216 
217 #ifdef CLOCK_REALTIME_COARSE
218         vdso_test_clock(CLOCK_REALTIME_COARSE);
219 #endif
220 
221 #ifdef CLOCK_MONOTONIC
222         vdso_test_clock(CLOCK_MONOTONIC);
223 #endif
224 
225 #ifdef CLOCK_MONOTONIC_RAW
226         vdso_test_clock(CLOCK_MONOTONIC_RAW);
227 #endif
228 
229 #ifdef CLOCK_MONOTONIC_COARSE
230         vdso_test_clock(CLOCK_MONOTONIC_COARSE);
231 #endif
232 
233 #endif
234 
235         vdso_test_time();
236 
237         ksft_print_cnts();
238         return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
239 }
240 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php