Skip to content

Commit ec04989

Browse files
fvincenzoshuahkh
authored andcommitted
kselftest: Fix vdso_test_abi return status
vdso_test_abi contains a batch of tests that verify the validity of the vDSO ABI. When a vDSO symbol is not found the relevant test is skipped reporting KSFT_SKIP. All the tests return values are then added in a single variable which is checked to verify failures. This approach can have side effects which result in reporting the wrong kselftest exit status. Fix vdso_test_abi verifying the return code of each test separately. Cc: Shuah Khan <shuah@kernel.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Reported-by: Cristian Marussi <cristian.marussi@arm.com> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent dae1d8a commit ec04989

File tree

1 file changed

+62
-73
lines changed

1 file changed

+62
-73
lines changed

tools/testing/selftests/vDSO/vdso_test_abi.c

Lines changed: 62 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -33,110 +33,114 @@ typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
3333
typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
3434
typedef time_t (*vdso_time_t)(time_t *t);
3535

36-
static int vdso_test_gettimeofday(void)
36+
#define VDSO_TEST_PASS_MSG() "\n%s(): PASS\n", __func__
37+
#define VDSO_TEST_FAIL_MSG(x) "\n%s(): %s FAIL\n", __func__, x
38+
#define VDSO_TEST_SKIP_MSG(x) "\n%s(): SKIP: Could not find %s\n", __func__, x
39+
40+
static void vdso_test_gettimeofday(void)
3741
{
3842
/* Find gettimeofday. */
3943
vdso_gettimeofday_t vdso_gettimeofday =
4044
(vdso_gettimeofday_t)vdso_sym(version, name[0]);
4145

4246
if (!vdso_gettimeofday) {
43-
printf("Could not find %s\n", name[0]);
44-
return KSFT_SKIP;
47+
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[0]));
48+
return;
4549
}
4650

4751
struct timeval tv;
4852
long ret = vdso_gettimeofday(&tv, 0);
4953

5054
if (ret == 0) {
51-
printf("The time is %lld.%06lld\n",
52-
(long long)tv.tv_sec, (long long)tv.tv_usec);
55+
ksft_print_msg("The time is %lld.%06lld\n",
56+
(long long)tv.tv_sec, (long long)tv.tv_usec);
57+
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
5358
} else {
54-
printf("%s failed\n", name[0]);
55-
return KSFT_FAIL;
59+
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[0]));
5660
}
57-
58-
return KSFT_PASS;
5961
}
6062

61-
static int vdso_test_clock_gettime(clockid_t clk_id)
63+
static void vdso_test_clock_gettime(clockid_t clk_id)
6264
{
6365
/* Find clock_gettime. */
6466
vdso_clock_gettime_t vdso_clock_gettime =
6567
(vdso_clock_gettime_t)vdso_sym(version, name[1]);
6668

6769
if (!vdso_clock_gettime) {
68-
printf("Could not find %s\n", name[1]);
69-
return KSFT_SKIP;
70+
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[1]));
71+
return;
7072
}
7173

7274
struct timespec ts;
7375
long ret = vdso_clock_gettime(clk_id, &ts);
7476

7577
if (ret == 0) {
76-
printf("The time is %lld.%06lld\n",
77-
(long long)ts.tv_sec, (long long)ts.tv_nsec);
78+
ksft_print_msg("The time is %lld.%06lld\n",
79+
(long long)ts.tv_sec, (long long)ts.tv_nsec);
80+
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
7881
} else {
79-
printf("%s failed\n", name[1]);
80-
return KSFT_FAIL;
82+
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[1]));
8183
}
82-
83-
return KSFT_PASS;
8484
}
8585

86-
static int vdso_test_time(void)
86+
static void vdso_test_time(void)
8787
{
8888
/* Find time. */
8989
vdso_time_t vdso_time =
9090
(vdso_time_t)vdso_sym(version, name[2]);
9191

9292
if (!vdso_time) {
93-
printf("Could not find %s\n", name[2]);
94-
return KSFT_SKIP;
93+
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[2]));
94+
return;
9595
}
9696

9797
long ret = vdso_time(NULL);
9898

9999
if (ret > 0) {
100-
printf("The time in hours since January 1, 1970 is %lld\n",
100+
ksft_print_msg("The time in hours since January 1, 1970 is %lld\n",
101101
(long long)(ret / 3600));
102+
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
102103
} else {
103-
printf("%s failed\n", name[2]);
104-
return KSFT_FAIL;
104+
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[2]));
105105
}
106-
107-
return KSFT_PASS;
108106
}
109107

110-
static int vdso_test_clock_getres(clockid_t clk_id)
108+
static void vdso_test_clock_getres(clockid_t clk_id)
111109
{
110+
int clock_getres_fail = 0;
111+
112112
/* Find clock_getres. */
113113
vdso_clock_getres_t vdso_clock_getres =
114114
(vdso_clock_getres_t)vdso_sym(version, name[3]);
115115

116116
if (!vdso_clock_getres) {
117-
printf("Could not find %s\n", name[3]);
118-
return KSFT_SKIP;
117+
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[3]));
118+
return;
119119
}
120120

121121
struct timespec ts, sys_ts;
122122
long ret = vdso_clock_getres(clk_id, &ts);
123123

124124
if (ret == 0) {
125-
printf("The resolution is %lld %lld\n",
126-
(long long)ts.tv_sec, (long long)ts.tv_nsec);
125+
ksft_print_msg("The vdso resolution is %lld %lld\n",
126+
(long long)ts.tv_sec, (long long)ts.tv_nsec);
127127
} else {
128-
printf("%s failed\n", name[3]);
129-
return KSFT_FAIL;
128+
clock_getres_fail++;
130129
}
131130

132131
ret = syscall(SYS_clock_getres, clk_id, &sys_ts);
133132

134-
if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) {
135-
printf("%s failed\n", name[3]);
136-
return KSFT_FAIL;
137-
}
133+
ksft_print_msg("The syscall resolution is %lld %lld\n",
134+
(long long)sys_ts.tv_sec, (long long)sys_ts.tv_nsec);
138135

139-
return KSFT_PASS;
136+
if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec))
137+
clock_getres_fail++;
138+
139+
if (clock_getres_fail > 0) {
140+
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[3]));
141+
} else {
142+
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
143+
}
140144
}
141145

142146
const char *vdso_clock_name[12] = {
@@ -158,36 +162,23 @@ const char *vdso_clock_name[12] = {
158162
* This function calls vdso_test_clock_gettime and vdso_test_clock_getres
159163
* with different values for clock_id.
160164
*/
161-
static inline int vdso_test_clock(clockid_t clock_id)
165+
static inline void vdso_test_clock(clockid_t clock_id)
162166
{
163-
int ret0, ret1;
164-
165-
ret0 = vdso_test_clock_gettime(clock_id);
166-
/* A skipped test is considered passed */
167-
if (ret0 == KSFT_SKIP)
168-
ret0 = KSFT_PASS;
169-
170-
ret1 = vdso_test_clock_getres(clock_id);
171-
/* A skipped test is considered passed */
172-
if (ret1 == KSFT_SKIP)
173-
ret1 = KSFT_PASS;
167+
ksft_print_msg("\nclock_id: %s\n", vdso_clock_name[clock_id]);
174168

175-
ret0 += ret1;
169+
vdso_test_clock_gettime(clock_id);
176170

177-
printf("clock_id: %s", vdso_clock_name[clock_id]);
178-
179-
if (ret0 > 0)
180-
printf(" [FAIL]\n");
181-
else
182-
printf(" [PASS]\n");
183-
184-
return ret0;
171+
vdso_test_clock_getres(clock_id);
185172
}
186173

174+
#define VDSO_TEST_PLAN 16
175+
187176
int main(int argc, char **argv)
188177
{
189178
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
190-
int ret;
179+
180+
ksft_print_header();
181+
ksft_set_plan(VDSO_TEST_PLAN);
191182

192183
if (!sysinfo_ehdr) {
193184
printf("AT_SYSINFO_EHDR is not present!\n");
@@ -201,44 +192,42 @@ int main(int argc, char **argv)
201192

202193
vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
203194

204-
ret = vdso_test_gettimeofday();
195+
vdso_test_gettimeofday();
205196

206197
#if _POSIX_TIMERS > 0
207198

208199
#ifdef CLOCK_REALTIME
209-
ret += vdso_test_clock(CLOCK_REALTIME);
200+
vdso_test_clock(CLOCK_REALTIME);
210201
#endif
211202

212203
#ifdef CLOCK_BOOTTIME
213-
ret += vdso_test_clock(CLOCK_BOOTTIME);
204+
vdso_test_clock(CLOCK_BOOTTIME);
214205
#endif
215206

216207
#ifdef CLOCK_TAI
217-
ret += vdso_test_clock(CLOCK_TAI);
208+
vdso_test_clock(CLOCK_TAI);
218209
#endif
219210

220211
#ifdef CLOCK_REALTIME_COARSE
221-
ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
212+
vdso_test_clock(CLOCK_REALTIME_COARSE);
222213
#endif
223214

224215
#ifdef CLOCK_MONOTONIC
225-
ret += vdso_test_clock(CLOCK_MONOTONIC);
216+
vdso_test_clock(CLOCK_MONOTONIC);
226217
#endif
227218

228219
#ifdef CLOCK_MONOTONIC_RAW
229-
ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
220+
vdso_test_clock(CLOCK_MONOTONIC_RAW);
230221
#endif
231222

232223
#ifdef CLOCK_MONOTONIC_COARSE
233-
ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
224+
vdso_test_clock(CLOCK_MONOTONIC_COARSE);
234225
#endif
235226

236227
#endif
237228

238-
ret += vdso_test_time();
239-
240-
if (ret > 0)
241-
return KSFT_FAIL;
229+
vdso_test_time();
242230

243-
return KSFT_PASS;
231+
ksft_print_cnts();
232+
return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
244233
}

0 commit comments

Comments
 (0)