1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2014, Michael Ellerman, IBM Corp.
6 #define _GNU_SOURCE /* For CPU_ZERO etc. */
18 int bind_to_cpu(int cpu)
22 printf("Binding to cpu %d\n", cpu);
27 return sched_setaffinity(0, sizeof(mask), &mask);
30 #define PARENT_TOKEN 0xAA
31 #define CHILD_TOKEN 0x55
33 int sync_with_child(union pipe read_pipe, union pipe write_pipe)
35 char c = PARENT_TOKEN;
37 FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
38 FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
39 if (c != CHILD_TOKEN) /* sometimes expected */
45 int wait_for_parent(union pipe read_pipe)
49 FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
50 FAIL_IF(c != PARENT_TOKEN);
55 int notify_parent(union pipe write_pipe)
59 FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
64 int notify_parent_of_error(union pipe write_pipe)
66 char c = ~CHILD_TOKEN;
68 FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
73 int wait_for_child(pid_t child_pid)
77 if (waitpid(child_pid, &rc, 0) == -1) {
85 rc = 1; /* Signal or other */
90 int kill_child_and_wait(pid_t child_pid)
92 kill(child_pid, SIGTERM);
94 return wait_for_child(child_pid);
97 static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe)
102 * We are just here to eat cpu and die. So make sure we can be killed,
103 * and also don't do any custom SIGTERM handling.
105 signal(SIGTERM, SIG_DFL);
107 notify_parent(write_pipe);
108 wait_for_parent(read_pipe);
110 /* Soak up cpu forever */
116 pid_t eat_cpu(int (test_function)(void))
118 union pipe read_pipe, write_pipe;
122 cpu = pick_online_cpu();
124 FAIL_IF(bind_to_cpu(cpu));
126 if (pipe(read_pipe.fds) == -1)
129 if (pipe(write_pipe.fds) == -1)
134 exit(eat_cpu_child(write_pipe, read_pipe));
136 if (sync_with_child(read_pipe, write_pipe)) {
141 printf("main test running as pid %d\n", getpid());
143 rc = test_function();
150 struct addr_range libc, vdso;
152 int parse_proc_maps(void)
154 unsigned long start, end;
155 char execute, name[128];
159 f = fopen("/proc/self/maps", "r");
166 /* This skips line with no executable which is what we want */
167 rc = fscanf(f, "%lx-%lx %*c%*c%c%*c %*x %*d:%*d %*d %127s\n",
168 &start, &end, &execute, name);
175 if (strstr(name, "libc")) {
178 } else if (strstr(name, "[vdso]")) {
189 #define PARANOID_PATH "/proc/sys/kernel/perf_event_paranoid"
191 bool require_paranoia_below(int level)
200 f = fopen(PARANOID_PATH, "r");
206 if (!fgets(buf, sizeof(buf), f)) {
207 printf("Couldn't read " PARANOID_PATH "?\n");
211 current = strtol(buf, &end, 10);
214 printf("Couldn't parse " PARANOID_PATH "?\n");
218 if (current >= level)