// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2014, Michael Ellerman, IBM Corp.
 */

#define _GNU_SOURCE	/* For CPU_ZERO etc. */

#include <errno.h>
#include <sched.h>
#include <setjmp.h>
#include <stdlib.h>
#include <sys/wait.h>

#include "utils.h"
#include "lib.h"

#define PARENT_TOKEN	0xAA
#define CHILD_TOKEN	0x55

int sync_with_child(union pipe read_pipe, union pipe write_pipe)
{
	char c = PARENT_TOKEN;

	FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
	FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
	if (c != CHILD_TOKEN) /* sometimes expected */
		return 1;

	return 0;
}

int wait_for_parent(union pipe read_pipe)
{
	char c;

	FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
	FAIL_IF(c != PARENT_TOKEN);

	return 0;
}

int notify_parent(union pipe write_pipe)
{
	char c = CHILD_TOKEN;

	FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);

	return 0;
}

int notify_parent_of_error(union pipe write_pipe)
{
	char c = ~CHILD_TOKEN;

	FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);

	return 0;
}

int wait_for_child(pid_t child_pid)
{
	int rc;

	if (waitpid(child_pid, &rc, 0) == -1) {
		perror("waitpid");
		return 1;
	}

	if (WIFEXITED(rc))
		rc = WEXITSTATUS(rc);
	else
		rc = 1; /* Signal or other */

	return rc;
}

int kill_child_and_wait(pid_t child_pid)
{
	kill(child_pid, SIGTERM);

	return wait_for_child(child_pid);
}

static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe)
{
	volatile int i = 0;

	/*
	 * We are just here to eat cpu and die. So make sure we can be killed,
	 * and also don't do any custom SIGTERM handling.
	 */
	signal(SIGTERM, SIG_DFL);

	notify_parent(write_pipe);
	wait_for_parent(read_pipe);

	/* Soak up cpu forever */
	while (1) i++;

	return 0;
}

pid_t eat_cpu(int (test_function)(void))
{
	union pipe read_pipe, write_pipe;
	int rc;
	pid_t pid;

	FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0);

	if (pipe(read_pipe.fds) == -1)
		return -1;

	if (pipe(write_pipe.fds) == -1)
		return -1;

	pid = fork();
	if (pid == 0)
		exit(eat_cpu_child(write_pipe, read_pipe));

	if (sync_with_child(read_pipe, write_pipe)) {
		rc = -1;
		goto out;
	}

	printf("main test running as pid %d\n", getpid());

	rc = test_function();
out:
	kill(pid, SIGKILL);

	return rc;
}

struct addr_range libc, vdso;

int parse_proc_maps(void)
{
	unsigned long start, end;
	char execute, name[128];
	FILE *f;
	int rc;

	f = fopen("/proc/self/maps", "r");
	if (!f) {
		perror("fopen");
		return -1;
	}

	do {
		/* This skips line with no executable which is what we want */
		rc = fscanf(f, "%lx-%lx %*c%*c%c%*c %*x %*d:%*d %*d %127s\n",
			    &start, &end, &execute, name);
		if (rc <= 0)
			break;

		if (execute != 'x')
			continue;

		if (strstr(name, "libc")) {
			libc.first = start;
			libc.last = end - 1;
		} else if (strstr(name, "[vdso]")) {
			vdso.first = start;
			vdso.last = end - 1;
		}
	} while(1);

	fclose(f);

	return 0;
}

#define PARANOID_PATH	"/proc/sys/kernel/perf_event_paranoid"

bool require_paranoia_below(int level)
{
	int err;
	long current;

	err = read_long(PARANOID_PATH, &current, 10);
	if (err) {
		printf("Couldn't parse " PARANOID_PATH "?\n");
		return false;
	}

	return current < level;
}
