1 /*
2 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
3 * Copyright (c) 2015-2018 The strace developers.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "tests.h"
30 #include <asm/unistd.h>
31
32 #if defined __NR_sched_getattr && defined __NR_sched_setattr
33
34 # include <inttypes.h>
35 # include <stdio.h>
36 # include <sched.h>
37 # include <unistd.h>
38 # include "sched_attr.h"
39 # include "xlat.h"
40 # include "xlat/schedulers.h"
41
42 static const char *errstr;
43
44 static long
sys_sched_getattr(kernel_ulong_t pid,kernel_ulong_t attr,kernel_ulong_t size,kernel_ulong_t flags)45 sys_sched_getattr(kernel_ulong_t pid, kernel_ulong_t attr,
46 kernel_ulong_t size, kernel_ulong_t flags)
47 {
48 long rc = syscall(__NR_sched_getattr, pid, attr, size, flags);
49 errstr = sprintrc(rc);
50 return rc;
51 }
52
53 static long
sys_sched_setattr(kernel_ulong_t pid,kernel_ulong_t attr,kernel_ulong_t flags)54 sys_sched_setattr(kernel_ulong_t pid, kernel_ulong_t attr, kernel_ulong_t flags)
55 {
56 long rc = syscall(__NR_sched_setattr, pid, attr, flags);
57 errstr = sprintrc(rc);
58 return rc;
59 }
60
61 int
main(void)62 main(void)
63 {
64 static const kernel_ulong_t bogus_pid =
65 (kernel_ulong_t) 0xdefacedfacefeedULL;
66 static const kernel_ulong_t bogus_size =
67 (kernel_ulong_t) 0xdefacedcafef00dULL;
68 static const kernel_ulong_t bogus_flags =
69 (kernel_ulong_t) 0xdefaceddeadc0deULL;
70
71 TAIL_ALLOC_OBJECT_CONST_PTR(struct sched_attr, attr);
72 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, psize);
73 void *const efault = attr + 1;
74
75 sys_sched_getattr(0, 0, 0, 0);
76 printf("sched_getattr(0, NULL, 0, 0) = %s\n", errstr);
77
78 sys_sched_getattr(0, (unsigned long) attr, 0, 0);
79 printf("sched_getattr(0, %p, 0, 0) = %s\n", attr, errstr);
80
81 sys_sched_getattr(bogus_pid, 0, 0, 0);
82 printf("sched_getattr(%d, NULL, 0, 0) = %s\n", (int) bogus_pid, errstr);
83
84 sys_sched_getattr(-1U, (unsigned long) attr, bogus_size, bogus_flags);
85 printf("sched_getattr(-1, %p, %s%u, %u) = %s\n",
86 attr,
87 # if defined __arm64__ || defined __aarch64__
88 "0xdefaced<<32|",
89 # else
90 "",
91 # endif
92 (unsigned) bogus_size, (unsigned) bogus_flags, errstr);
93
94 sys_sched_getattr(0, (unsigned long) efault, sizeof(*attr), 0);
95 printf("sched_getattr(0, %p, %u, 0) = %s\n",
96 efault, (unsigned) sizeof(*attr), errstr);
97
98 if (sys_sched_getattr(0, (unsigned long) attr, sizeof(*attr), 0))
99 perror_msg_and_skip("sched_getattr");
100 printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
101 printxval(schedulers, attr->sched_policy, NULL);
102 printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
103 ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
104 ", sched_period=%" PRIu64 "}, %u, 0) = 0\n",
105 attr->sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
106 attr->sched_nice,
107 attr->sched_priority,
108 attr->sched_runtime,
109 attr->sched_deadline,
110 attr->sched_period,
111 (unsigned) sizeof(*attr));
112
113 # if defined __arm64__ || defined __aarch64__
114 long rc =
115 # endif
116 sys_sched_getattr(F8ILL_KULONG_MASK, (unsigned long) attr,
117 F8ILL_KULONG_MASK | sizeof(*attr), F8ILL_KULONG_MASK);
118 # if defined __arm64__ || defined __aarch64__
119 if (rc) {
120 printf("sched_getattr(0, %p, 0xffffffff<<32|%u, 0) = %s\n",
121 attr, (unsigned) sizeof(*attr), errstr);
122 } else
123 # endif
124 {
125 printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
126 printxval(schedulers, attr->sched_policy, NULL);
127 printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
128 ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
129 ", sched_period=%" PRIu64 "}, %u, 0) = 0\n",
130 attr->sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
131 attr->sched_nice,
132 attr->sched_priority,
133 attr->sched_runtime,
134 attr->sched_deadline,
135 attr->sched_period,
136 (unsigned) sizeof(*attr));
137 }
138
139 sys_sched_setattr(bogus_pid, 0, 0);
140 printf("sched_setattr(%d, NULL, 0) = %s\n", (int) bogus_pid, errstr);
141
142 attr->sched_flags |= 1;
143
144 if (sys_sched_setattr(0, (unsigned long) attr, 0))
145 perror_msg_and_skip("sched_setattr");
146 printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
147 printxval(schedulers, attr->sched_policy, NULL);
148 printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
149 ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
150 ", sched_period=%" PRIu64 "}, 0) = 0\n",
151 "SCHED_FLAG_RESET_ON_FORK",
152 attr->sched_nice,
153 attr->sched_priority,
154 attr->sched_runtime,
155 attr->sched_deadline,
156 attr->sched_period);
157
158 sys_sched_setattr(F8ILL_KULONG_MASK, (unsigned long) attr,
159 F8ILL_KULONG_MASK);
160 printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
161 printxval(schedulers, attr->sched_policy, NULL);
162 printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
163 ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
164 ", sched_period=%" PRIu64 "}, 0) = 0\n",
165 "SCHED_FLAG_RESET_ON_FORK",
166 attr->sched_nice,
167 attr->sched_priority,
168 attr->sched_runtime,
169 attr->sched_deadline,
170 attr->sched_period);
171
172 *psize = attr->size;
173
174 sys_sched_setattr(0, (unsigned long) psize, 0);
175 printf("sched_setattr(0, %p, 0) = %s\n", psize, errstr);
176
177 attr->size = 0;
178
179 sys_sched_setattr(0, (unsigned long) attr, 0);
180 printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
181 printxval(schedulers, attr->sched_policy, NULL);
182 printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
183 ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
184 ", sched_period=%" PRIu64 "}, 0) = 0\n",
185 "SCHED_FLAG_RESET_ON_FORK",
186 attr->sched_nice,
187 attr->sched_priority,
188 attr->sched_runtime,
189 attr->sched_deadline,
190 attr->sched_period);
191
192 attr->size = 1;
193
194 sys_sched_setattr(0, (unsigned long) attr, 0);
195 printf("sched_setattr(0, {size=%u} => {size=%u}, 0) = %s\n",
196 1, attr->size, errstr);
197
198 attr->size = SCHED_ATTR_MIN_SIZE - 1;
199
200 sys_sched_setattr(0, (unsigned long) attr, 0);
201 printf("sched_setattr(0, {size=%u} => {size=%u}, 0) = %s\n",
202 SCHED_ATTR_MIN_SIZE - 1, attr->size, errstr);
203
204 attr->size = 0x90807060;
205 attr->sched_policy = 0xca7faced;
206 attr->sched_flags = 0xbadc0ded1057da78ULL;
207 attr->sched_nice = 0xafbfcfdf;
208 attr->sched_priority = 0xb8c8d8e8;
209 attr->sched_runtime = 0xbadcaffedeadf157ULL;
210 attr->sched_deadline = 0xc0de70a57badac75ULL;
211 attr->sched_period = 0xded1ca7edda7aca7ULL;
212
213 sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
214 printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
215 "sched_flags=%#" PRIx64 " /* SCHED_FLAG_??? */, "
216 "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
217 "sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 ", ...}, %u)"
218 " = %s\n",
219 (int) bogus_pid,
220 attr->size,
221 attr->sched_policy,
222 attr->sched_flags,
223 attr->sched_nice,
224 attr->sched_priority,
225 attr->sched_runtime,
226 attr->sched_deadline,
227 attr->sched_period,
228 (unsigned) bogus_flags, errstr);
229
230 if (F8ILL_KULONG_SUPPORTED) {
231 const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
232
233 sys_sched_getattr(0, ill, sizeof(*attr), 0);
234 printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
235 (unsigned long long) ill, (unsigned) sizeof(*attr),
236 errstr);
237
238 sys_sched_setattr(0, ill, 0);
239 printf("sched_setattr(0, %#llx, 0) = %s\n",
240 (unsigned long long) ill, errstr);
241 }
242
243
244 attr->size = 0x90807060;
245 attr->sched_policy = 0xca7faced;
246 attr->sched_flags = 0xfULL;
247 attr->sched_nice = 0xafbfcfdf;
248 attr->sched_priority = 0xb8c8d8e8;
249 attr->sched_runtime = 0xbadcaffedeadf157ULL;
250 attr->sched_deadline = 0xc0de70a57badac75ULL;
251 attr->sched_period = 0xded1ca7edda7aca7ULL;
252
253 sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
254 printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
255 "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
256 "SCHED_FLAG_DL_OVERRUN|0x8, "
257 "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
258 "sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 ", ...}, %u)"
259 " = %s\n",
260 (int) bogus_pid,
261 attr->size,
262 attr->sched_policy,
263 attr->sched_nice,
264 attr->sched_priority,
265 attr->sched_runtime,
266 attr->sched_deadline,
267 attr->sched_period,
268 (unsigned) bogus_flags, errstr);
269
270 if (F8ILL_KULONG_SUPPORTED) {
271 const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
272
273 sys_sched_getattr(0, ill, sizeof(*attr), 0);
274 printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
275 (unsigned long long) ill, (unsigned) sizeof(*attr),
276 errstr);
277
278 sys_sched_setattr(0, ill, 0);
279 printf("sched_setattr(0, %#llx, 0) = %s\n",
280 (unsigned long long) ill, errstr);
281 }
282
283 puts("+++ exited with 0 +++");
284 return 0;
285 }
286
287 #else
288
289 SKIP_MAIN_UNDEFINED("__NR_sched_getattr && __NR_sched_setattr")
290
291 #endif
292