Skip to content

Commit a143f48

Browse files
vireshkmetan-ucw
authored andcommitted
syscalls/clock_gettime: Add support for time64 tests
This adds support for time64 tests to the existing clock_gettime() syscall tests. Signed-off-by: Viresh Kumar <[email protected]> Signed-off-by: Cyril Hrubis <[email protected]>
1 parent 87e11a8 commit a143f48

File tree

4 files changed

+202
-105
lines changed

4 files changed

+202
-105
lines changed

include/tst_timer.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <sys/time.h>
1616
#include <time.h>
1717
#include "tst_test.h"
18+
#include "lapi/syscalls.h"
1819

1920
/*
2021
* Converts timeval to microseconds.
@@ -128,6 +129,36 @@ struct tst_ts {
128129
} ts;
129130
};
130131

132+
static inline void *tst_ts_get(struct tst_ts *t)
133+
{
134+
switch (t->type) {
135+
case TST_LIBC_TIMESPEC:
136+
return &t->ts.libc_ts;
137+
case TST_KERN_OLD_TIMESPEC:
138+
return &t->ts.kern_old_ts;
139+
case TST_KERN_TIMESPEC:
140+
return &t->ts.kern_ts;
141+
default:
142+
tst_brk(TBROK, "Invalid type: %d", t->type);
143+
return NULL;
144+
}
145+
}
146+
147+
static inline int libc_clock_gettime(clockid_t clk_id, void *ts)
148+
{
149+
return clock_gettime(clk_id, ts);
150+
}
151+
152+
static inline int sys_clock_gettime(clockid_t clk_id, void *ts)
153+
{
154+
return tst_syscall(__NR_clock_gettime, clk_id, ts);
155+
}
156+
157+
static inline int sys_clock_gettime64(clockid_t clk_id, void *ts)
158+
{
159+
return tst_syscall(__NR_clock_gettime64, clk_id, ts);
160+
}
161+
131162
/*
132163
* Returns tst_ts seconds.
133164
*/
@@ -164,6 +195,27 @@ static inline long long tst_ts_get_nsec(struct tst_ts ts)
164195
}
165196
}
166197

198+
/*
199+
* Checks that timespec is valid, i.e. that the timestamp is not zero and that
200+
* the nanoseconds are normalized i.e. in <0, 1s) interval.
201+
*
202+
* 0: On success, i.e. timespec updated correctly.
203+
* -1: Error, timespec not updated.
204+
* -2: Error, tv_nsec is corrupted.
205+
*/
206+
static inline int tst_ts_valid(struct tst_ts *t)
207+
{
208+
long long nsec = tst_ts_get_nsec(*t);
209+
210+
if (nsec < 0 || nsec >= 1000000000)
211+
return -2;
212+
213+
if (tst_ts_get_sec(*t) == 0 && tst_ts_get_nsec(*t) == 0)
214+
return -1;
215+
216+
return 0;
217+
}
218+
167219
/*
168220
* Sets tst_ts seconds.
169221
*/

testcases/kernel/syscalls/clock_gettime/clock_gettime01.c

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,14 @@
1919
#include "config.h"
2020
#include "tst_timer.h"
2121
#include "tst_safe_clocks.h"
22-
#include "tst_test.h"
23-
#include "lapi/syscalls.h"
22+
#include "lapi/abisize.h"
2423

2524
struct test_case {
2625
clockid_t clktype;
2726
int allow_inval;
2827
};
2928

30-
struct tmpfunc {
31-
int (*func)(clockid_t clk_id, struct timespec *tp);
32-
char *desc;
33-
};
34-
35-
struct test_case tc[] = {
29+
static struct test_case tc[] = {
3630
{
3731
.clktype = CLOCK_REALTIME,
3832
},
@@ -63,79 +57,73 @@ struct test_case tc[] = {
6357
},
6458
};
6559

66-
static int sys_clock_gettime(clockid_t clk_id, struct timespec *tp)
67-
{
68-
return tst_syscall(__NR_clock_gettime, clk_id, tp);
69-
}
60+
static struct tst_ts spec;
7061

71-
static int check_spec(struct timespec *spec)
62+
static struct test_variants {
63+
int (*func)(clockid_t clk_id, void *ts);
64+
enum tst_ts_type type;
65+
char *desc;
66+
} variants[] = {
67+
#if defined(TST_ABI32)
68+
{ .func = libc_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
69+
{ .func = sys_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
70+
{ .func = sys_clock_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
71+
#endif
72+
73+
#if defined(TST_ABI64)
74+
{ .func = sys_clock_gettime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
75+
#endif
76+
77+
#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL)
78+
{ .func = sys_clock_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
79+
#endif
80+
};
81+
82+
static void setup(void)
7283
{
73-
return (spec->tv_nsec != 0 || spec->tv_sec != 0) ? 1 : 0;
84+
tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
7485
}
7586

7687
static void verify_clock_gettime(unsigned int i)
7788
{
78-
size_t sz;
79-
struct timespec spec;
80-
81-
/*
82-
* check clock_gettime() syscall AND libc (or vDSO) functions
83-
*/
84-
struct tmpfunc tf[] = {
85-
{ .func = sys_clock_gettime, .desc = "syscall" },
86-
{ .func = clock_gettime, .desc = "vDSO or syscall" },
87-
};
88-
89-
for (sz = 0; sz < ARRAY_SIZE(tf); sz++) {
89+
struct test_variants *tv = &variants[tst_variant];
90+
int ret;
9091

91-
memset(&spec, 0, sizeof(struct timespec));
92+
memset(&spec, 0, sizeof(spec));
93+
spec.type = tv->type;
9294

93-
TEST(tf[sz].func(tc[i].clktype, &spec));
94-
95-
if (TST_RET == -1) {
96-
97-
/* errors: allow unsupported clock types */
98-
99-
if (tc[i].allow_inval && TST_ERR == EINVAL) {
100-
101-
tst_res(TPASS, "clock_gettime(2): unsupported "
102-
"clock %s (%s) failed as "
103-
"expected",
104-
tst_clock_name(tc[i].clktype),
105-
tf[sz].desc);
106-
107-
} else {
108-
109-
tst_res(TFAIL | TTERRNO, "clock_gettime(2): "
110-
"clock %s (%s) failed "
111-
"unexpectedly",
112-
tst_clock_name(tc[i].clktype),
113-
tf[sz].desc);
114-
}
95+
TEST(tv->func(tc[i].clktype, tst_ts_get(&spec)));
11596

97+
if (TST_RET == -1) {
98+
/* errors: allow unsupported clock types */
99+
if (tc[i].allow_inval && TST_ERR == EINVAL) {
100+
tst_res(TPASS, "clock_gettime(2): unsupported clock %s failed as expected",
101+
tst_clock_name(tc[i].clktype));
116102
} else {
103+
tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s failed unexpectedly",
104+
tst_clock_name(tc[i].clktype));
105+
}
117106

118-
/* success: also check if timespec was changed */
119-
120-
if (check_spec(&spec)) {
121-
tst_res(TPASS, "clock_gettime(2): clock %s "
122-
"(%s) passed",
123-
tst_clock_name(tc[i].clktype),
124-
tf[sz].desc);
125-
} else {
126-
127-
tst_res(TFAIL, "clock_gettime(2): clock %s "
128-
"(%s) passed, unchanged "
129-
"timespec",
130-
tst_clock_name(tc[i].clktype),
131-
tf[sz].desc);
132-
}
107+
} else {
108+
/* success: also check if timespec was changed */
109+
ret = tst_ts_valid(&spec);
110+
if (!ret) {
111+
tst_res(TPASS, "clock_gettime(2): clock %s passed",
112+
tst_clock_name(tc[i].clktype));
113+
} else if (ret == -1) {
114+
tst_res(TFAIL, "clock_gettime(2): clock %s passed, unchanged timespec",
115+
tst_clock_name(tc[i].clktype));
116+
} else if (ret == -2) {
117+
tst_res(TFAIL, "clock_gettime(2): clock %s passed, Corrupted timespec",
118+
tst_clock_name(tc[i].clktype));
133119
}
134120
}
135121
}
136122

137123
static struct tst_test test = {
138124
.test = verify_clock_gettime,
139125
.tcnt = ARRAY_SIZE(tc),
126+
.test_variants = ARRAY_SIZE(variants),
127+
.setup = setup,
140128
.needs_root = 1,
141129
};

testcases/kernel/syscalls/clock_gettime/clock_gettime02.c

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@
1919
*/
2020

2121
#include "config.h"
22-
#include "tst_test.h"
23-
#include "lapi/syscalls.h"
2422
#include "tst_timer.h"
2523
#include "tst_safe_clocks.h"
24+
#include "lapi/abisize.h"
25+
26+
static void *bad_addr;
2627

2728
struct test_case {
2829
clockid_t clktype;
2930
int exp_err;
3031
int allow_inval;
3132
};
3233

33-
struct test_case tc[] = {
34+
static struct test_case tc[] = {
3435
{
3536
.clktype = MAX_CLOCKS,
3637
.exp_err = EINVAL,
@@ -81,52 +82,72 @@ struct test_case tc[] = {
8182
},
8283
};
8384

85+
static struct tst_ts spec;
86+
8487
/*
8588
* bad pointer w/ libc causes SIGSEGV signal, call syscall directly
8689
*/
87-
static int sys_clock_gettime(clockid_t clk_id, struct timespec *tp)
90+
static struct test_variants {
91+
int (*func)(clockid_t clk_id, void *ts);
92+
enum tst_ts_type type;
93+
char *desc;
94+
} variants[] = {
95+
#if defined(TST_ABI32)
96+
{ .func = sys_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
97+
{ .func = sys_clock_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
98+
#endif
99+
100+
#if defined(TST_ABI64)
101+
{ .func = sys_clock_gettime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
102+
#endif
103+
104+
#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL)
105+
{ .func = sys_clock_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
106+
#endif
107+
};
108+
109+
static void setup(void)
88110
{
89-
return tst_syscall(__NR_clock_gettime, clk_id, tp);
111+
tst_res(TINFO, "Testing variant: %d: %s", tst_variant, variants[tst_variant].desc);
112+
113+
bad_addr = tst_get_bad_addr(NULL);
90114
}
91115

92116
static void verify_clock_gettime(unsigned int i)
93117
{
94-
struct timespec spec, *specptr;
95-
96-
specptr = &spec;
118+
struct test_variants *tv = &variants[tst_variant];
119+
void *ts;
97120

98121
/* bad pointer cases */
99-
if (tc[i].exp_err == EFAULT)
100-
specptr = tst_get_bad_addr(NULL);
101-
102-
TEST(sys_clock_gettime(tc[i].clktype, specptr));
103-
104-
if (TST_RET == -1) {
105-
106-
if ((tc[i].exp_err == TST_ERR) ||
107-
(tc[i].allow_inval && TST_ERR == EINVAL)) {
108-
109-
tst_res(TPASS | TTERRNO, "clock_gettime(2): "
110-
"clock %s failed as expected",
111-
tst_clock_name(tc[i].clktype));
122+
if (tc[i].exp_err == EFAULT) {
123+
ts = bad_addr;
124+
} else {
125+
spec.type = tv->type;
126+
ts = tst_ts_get(&spec);
127+
}
112128

113-
} else {
129+
TEST(tv->func(tc[i].clktype, ts));
114130

115-
tst_res(TFAIL | TTERRNO, "clock_gettime(2): "
116-
"clock %s failed unexpectedly",
117-
tst_clock_name(tc[i].clktype));
118-
}
131+
if (TST_RET != -1) {
132+
tst_res(TFAIL, "clock_gettime(2): clock %s passed unexcpectedly",
133+
tst_clock_name(tc[i].clktype));
134+
return;
135+
}
119136

137+
if ((tc[i].exp_err == TST_ERR) ||
138+
(tc[i].allow_inval && TST_ERR == EINVAL)) {
139+
tst_res(TPASS | TTERRNO, "clock_gettime(2): clock %s failed as expected",
140+
tst_clock_name(tc[i].clktype));
120141
} else {
121-
122-
tst_res(TFAIL, "clock_gettime(2): clock %s passed"
123-
" unexcpectedly",
124-
tst_clock_name(tc[i].clktype));
142+
tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s failed unexpectedly",
143+
tst_clock_name(tc[i].clktype));
125144
}
126145
}
127146

128147
static struct tst_test test = {
129148
.test = verify_clock_gettime,
130149
.tcnt = ARRAY_SIZE(tc),
150+
.test_variants = ARRAY_SIZE(variants),
151+
.setup = setup,
131152
.needs_root = 1,
132153
};

0 commit comments

Comments
 (0)