1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* AUTHOR : Saji Kumar.V.R <saji.kumar@wipro.com>
*/
/*\
* [Description]
*
* Verify that:
*
* - sched_rr_get_interval() fails with errno set to EINVAL for an
* invalid pid
*
* - sched_rr_get_interval() fails with errno set to ESRCH if the
* process with specified pid does not exists
*
* - sched_rr_get_interval() fails with errno set to EFAULT if the
* address specified as &tp is invalid
*/
#include "time64_variants.h"
#include "tst_timer.h"
#include "tst_sched.h"
static pid_t unused_pid;
static pid_t inval_pid = -1;
static pid_t zero_pid;
static struct tst_ts tp;
static void *bad_addr;
struct test_cases_t {
pid_t *pid;
struct tst_ts *tp;
int exp_errno;
} test_cases[] = {
{ &inval_pid, &tp, EINVAL},
{ &unused_pid, &tp, ESRCH},
{ &zero_pid, NULL, EFAULT}
};
static struct time64_variants variants[] = {
{ .sched_rr_get_interval = libc_sched_rr_get_interval, .ts_type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
#if (__NR_sched_rr_get_interval != __LTP__NR_INVALID_SYSCALL)
{ .sched_rr_get_interval = sys_sched_rr_get_interval, .ts_type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
#endif
#if (__NR_sched_rr_get_interval_time64 != __LTP__NR_INVALID_SYSCALL)
{ .sched_rr_get_interval = sys_sched_rr_get_interval64, .ts_type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
#endif
};
static void setup(void)
{
struct time64_variants *tv = &variants[tst_variant];
struct sched_param p = { 1 };
tst_res(TINFO, "Testing variant: %s", tv->desc);
bad_addr = tst_get_bad_addr(NULL);
tp.type = tv->ts_type;
if ((sys_sched_setscheduler(0, SCHED_RR, &p)) == -1)
tst_res(TFAIL | TERRNO, "sched_setscheduler() failed");
unused_pid = tst_get_unused_pid();
}
static void run(unsigned int i)
{
struct time64_variants *tv = &variants[tst_variant];
struct test_cases_t *tc = &test_cases[i];
struct timerspec *ts;
if (tc->exp_errno == EFAULT
&& tv->sched_rr_get_interval == libc_sched_rr_get_interval) {
tst_res(TCONF, "EFAULT skipped for libc_variant");
return;
}
if (tc->exp_errno == EFAULT)
ts = bad_addr;
else
ts = tst_ts_get(tc->tp);
TST_EXP_FAIL(tv->sched_rr_get_interval(*tc->pid, ts), tc->exp_errno,
"sched_rr_get_interval(%i, %p)", *tc->pid, ts);
}
static struct tst_test test = {
.test = run,
.tcnt = ARRAY_SIZE(test_cases),
.test_variants = ARRAY_SIZE(variants),
.setup = setup,
.needs_root = 1,
};
|