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