| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2016 Google, Inc. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This software is licensed under the terms of the GNU General Public |
|---|
| 5 | | - * License version 2, as published by the Free Software Foundation, and |
|---|
| 6 | | - * may be copied, distributed, and modified under those terms. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 9 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | | - * GNU General Public License for more details. |
|---|
| 12 | | - * |
|---|
| 13 | 4 | */ |
|---|
| 14 | 5 | |
|---|
| 15 | 6 | #define _GNU_SOURCE |
|---|
| .. | .. |
|---|
| 56 | 47 | _exit(0); |
|---|
| 57 | 48 | } |
|---|
| 58 | 49 | |
|---|
| 59 | | -bool run_test(int cpu) |
|---|
| 50 | +int run_test(int cpu) |
|---|
| 60 | 51 | { |
|---|
| 61 | 52 | int status; |
|---|
| 62 | 53 | pid_t pid = fork(); |
|---|
| .. | .. |
|---|
| 64 | 55 | |
|---|
| 65 | 56 | if (pid < 0) { |
|---|
| 66 | 57 | ksft_print_msg("fork() failed: %s\n", strerror(errno)); |
|---|
| 67 | | - return false; |
|---|
| 58 | + return KSFT_FAIL; |
|---|
| 68 | 59 | } |
|---|
| 69 | 60 | if (pid == 0) |
|---|
| 70 | 61 | child(cpu); |
|---|
| .. | .. |
|---|
| 72 | 63 | wpid = waitpid(pid, &status, __WALL); |
|---|
| 73 | 64 | if (wpid != pid) { |
|---|
| 74 | 65 | ksft_print_msg("waitpid() failed: %s\n", strerror(errno)); |
|---|
| 75 | | - return false; |
|---|
| 66 | + return KSFT_FAIL; |
|---|
| 76 | 67 | } |
|---|
| 77 | 68 | if (!WIFSTOPPED(status)) { |
|---|
| 78 | 69 | ksft_print_msg("child did not stop: %s\n", strerror(errno)); |
|---|
| 79 | | - return false; |
|---|
| 70 | + return KSFT_FAIL; |
|---|
| 80 | 71 | } |
|---|
| 81 | 72 | if (WSTOPSIG(status) != SIGSTOP) { |
|---|
| 82 | 73 | ksft_print_msg("child did not stop with SIGSTOP: %s\n", |
|---|
| 83 | 74 | strerror(errno)); |
|---|
| 84 | | - return false; |
|---|
| 75 | + return KSFT_FAIL; |
|---|
| 85 | 76 | } |
|---|
| 86 | 77 | |
|---|
| 87 | 78 | if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) { |
|---|
| 88 | 79 | if (errno == EIO) { |
|---|
| 89 | | - ksft_exit_skip( |
|---|
| 80 | + ksft_print_msg( |
|---|
| 90 | 81 | "ptrace(PTRACE_SINGLESTEP) not supported on this architecture: %s\n", |
|---|
| 91 | 82 | strerror(errno)); |
|---|
| 83 | + return KSFT_SKIP; |
|---|
| 92 | 84 | } |
|---|
| 93 | 85 | ksft_print_msg("ptrace(PTRACE_SINGLESTEP) failed: %s\n", |
|---|
| 94 | 86 | strerror(errno)); |
|---|
| 95 | | - return false; |
|---|
| 87 | + return KSFT_FAIL; |
|---|
| 96 | 88 | } |
|---|
| 97 | 89 | |
|---|
| 98 | 90 | wpid = waitpid(pid, &status, __WALL); |
|---|
| 99 | 91 | if (wpid != pid) { |
|---|
| 100 | 92 | ksft_print_msg("waitpid() failed: $s\n", strerror(errno)); |
|---|
| 101 | | - return false; |
|---|
| 93 | + return KSFT_FAIL; |
|---|
| 102 | 94 | } |
|---|
| 103 | 95 | if (WIFEXITED(status)) { |
|---|
| 104 | 96 | ksft_print_msg("child did not single-step: %s\n", |
|---|
| 105 | 97 | strerror(errno)); |
|---|
| 106 | | - return false; |
|---|
| 98 | + return KSFT_FAIL; |
|---|
| 107 | 99 | } |
|---|
| 108 | 100 | if (!WIFSTOPPED(status)) { |
|---|
| 109 | 101 | ksft_print_msg("child did not stop: %s\n", strerror(errno)); |
|---|
| 110 | | - return false; |
|---|
| 102 | + return KSFT_FAIL; |
|---|
| 111 | 103 | } |
|---|
| 112 | 104 | if (WSTOPSIG(status) != SIGTRAP) { |
|---|
| 113 | 105 | ksft_print_msg("child did not stop with SIGTRAP: %s\n", |
|---|
| 114 | 106 | strerror(errno)); |
|---|
| 115 | | - return false; |
|---|
| 107 | + return KSFT_FAIL; |
|---|
| 116 | 108 | } |
|---|
| 117 | 109 | |
|---|
| 118 | 110 | if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) { |
|---|
| 119 | 111 | ksft_print_msg("ptrace(PTRACE_CONT) failed: %s\n", |
|---|
| 120 | 112 | strerror(errno)); |
|---|
| 121 | | - return false; |
|---|
| 113 | + return KSFT_FAIL; |
|---|
| 122 | 114 | } |
|---|
| 123 | 115 | |
|---|
| 124 | 116 | wpid = waitpid(pid, &status, __WALL); |
|---|
| 125 | 117 | if (wpid != pid) { |
|---|
| 126 | 118 | ksft_print_msg("waitpid() failed: %s\n", strerror(errno)); |
|---|
| 127 | | - return false; |
|---|
| 119 | + return KSFT_FAIL; |
|---|
| 128 | 120 | } |
|---|
| 129 | 121 | if (!WIFEXITED(status)) { |
|---|
| 130 | 122 | ksft_print_msg("child did not exit after PTRACE_CONT: %s\n", |
|---|
| 131 | 123 | strerror(errno)); |
|---|
| 132 | | - return false; |
|---|
| 124 | + return KSFT_FAIL; |
|---|
| 133 | 125 | } |
|---|
| 134 | 126 | |
|---|
| 135 | | - return true; |
|---|
| 127 | + return KSFT_PASS; |
|---|
| 136 | 128 | } |
|---|
| 137 | 129 | |
|---|
| 138 | 130 | void suspend(void) |
|---|
| .. | .. |
|---|
| 173 | 165 | int opt; |
|---|
| 174 | 166 | bool do_suspend = true; |
|---|
| 175 | 167 | bool succeeded = true; |
|---|
| 168 | + unsigned int tests = 0; |
|---|
| 176 | 169 | cpu_set_t available_cpus; |
|---|
| 177 | 170 | int err; |
|---|
| 178 | 171 | int cpu; |
|---|
| .. | .. |
|---|
| 191 | 184 | } |
|---|
| 192 | 185 | } |
|---|
| 193 | 186 | |
|---|
| 194 | | - if (do_suspend) |
|---|
| 195 | | - suspend(); |
|---|
| 196 | | - |
|---|
| 197 | 187 | err = sched_getaffinity(0, sizeof(available_cpus), &available_cpus); |
|---|
| 198 | 188 | if (err < 0) |
|---|
| 199 | 189 | ksft_exit_fail_msg("sched_getaffinity() failed\n"); |
|---|
| 200 | 190 | |
|---|
| 201 | 191 | for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { |
|---|
| 202 | | - bool test_success; |
|---|
| 192 | + if (!CPU_ISSET(cpu, &available_cpus)) |
|---|
| 193 | + continue; |
|---|
| 194 | + tests++; |
|---|
| 195 | + } |
|---|
| 196 | + |
|---|
| 197 | + if (do_suspend) |
|---|
| 198 | + suspend(); |
|---|
| 199 | + |
|---|
| 200 | + ksft_set_plan(tests); |
|---|
| 201 | + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { |
|---|
| 202 | + int test_success; |
|---|
| 203 | 203 | |
|---|
| 204 | 204 | if (!CPU_ISSET(cpu, &available_cpus)) |
|---|
| 205 | 205 | continue; |
|---|
| 206 | 206 | |
|---|
| 207 | 207 | test_success = run_test(cpu); |
|---|
| 208 | | - if (test_success) { |
|---|
| 208 | + switch (test_success) { |
|---|
| 209 | + case KSFT_PASS: |
|---|
| 209 | 210 | ksft_test_result_pass("CPU %d\n", cpu); |
|---|
| 210 | | - } else { |
|---|
| 211 | + break; |
|---|
| 212 | + case KSFT_SKIP: |
|---|
| 213 | + ksft_test_result_skip("CPU %d\n", cpu); |
|---|
| 214 | + break; |
|---|
| 215 | + case KSFT_FAIL: |
|---|
| 211 | 216 | ksft_test_result_fail("CPU %d\n", cpu); |
|---|
| 212 | 217 | succeeded = false; |
|---|
| 218 | + break; |
|---|
| 213 | 219 | } |
|---|
| 214 | 220 | } |
|---|
| 215 | 221 | |
|---|