// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ptrace.h>
#include <asm/ptrace.h>
#include <errno.h>
#include "debug.h"
#include "tests/tests.h"
#include "arch-tests.h"

static noinline int bp_1(void)
{
	pr_debug("in %s\n", __func__);
	return 0;
}

static noinline int bp_2(void)
{
	pr_debug("in %s\n", __func__);
	return 0;
}

static int spawn_child(void)
{
	int child = fork();

	if (child == 0) {
		/*
		 * The child sets itself for as tracee and
		 * waits in signal for parent to trace it,
		 * then it calls bp_1 and quits.
		 */
		int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL);

		if (err) {
			pr_debug("failed to PTRACE_TRACEME\n");
			exit(1);
		}

		raise(SIGCONT);
		bp_1();
		exit(0);
	}

	return child;
}

/*
 * This tests creates HW breakpoint, tries to
 * change it and checks it was properly changed.
 */
static int bp_modify1(void)
{
	pid_t child;
	int status;
	unsigned long rip = 0, dr7 = 1;

	child = spawn_child();

	waitpid(child, &status, 0);
	if (WIFEXITED(status)) {
		pr_debug("tracee exited prematurely 1\n");
		return TEST_FAIL;
	}

	/*
	 * The parent does following steps:
	 *  - creates a new breakpoint (id 0) for bp_2 function
	 *  - changes that breakponit to bp_1 function
	 *  - waits for the breakpoint to hit and checks
	 *    it has proper rip of bp_1 function
	 *  - detaches the child
	 */
	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[0]), bp_2)) {
		pr_debug("failed to set breakpoint, 1st time: %s\n",
			 strerror(errno));
		goto out;
	}

	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[0]), bp_1)) {
		pr_debug("failed to set breakpoint, 2nd time: %s\n",
			 strerror(errno));
		goto out;
	}

	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[7]), dr7)) {
		pr_debug("failed to set dr7: %s\n", strerror(errno));
		goto out;
	}

	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
		pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
		goto out;
	}

	waitpid(child, &status, 0);
	if (WIFEXITED(status)) {
		pr_debug("tracee exited prematurely 2\n");
		return TEST_FAIL;
	}

	rip = ptrace(PTRACE_PEEKUSER, child,
		     offsetof(struct user_regs_struct, rip), NULL);
	if (rip == (unsigned long) -1) {
		pr_debug("failed to PTRACE_PEEKUSER: %s\n",
			 strerror(errno));
		goto out;
	}

	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);

out:
	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
		pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
		return TEST_FAIL;
	}

	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
}

/*
 * This tests creates HW breakpoint, tries to
 * change it to bogus value and checks the original
 * breakpoint is hit.
 */
static int bp_modify2(void)
{
	pid_t child;
	int status;
	unsigned long rip = 0, dr7 = 1;

	child = spawn_child();

	waitpid(child, &status, 0);
	if (WIFEXITED(status)) {
		pr_debug("tracee exited prematurely 1\n");
		return TEST_FAIL;
	}

	/*
	 * The parent does following steps:
	 *  - creates a new breakpoint (id 0) for bp_1 function
	 *  - tries to change that breakpoint to (-1) address
	 *  - waits for the breakpoint to hit and checks
	 *    it has proper rip of bp_1 function
	 *  - detaches the child
	 */
	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[0]), bp_1)) {
		pr_debug("failed to set breakpoint: %s\n",
			 strerror(errno));
		goto out;
	}

	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[7]), dr7)) {
		pr_debug("failed to set dr7: %s\n", strerror(errno));
		goto out;
	}

	if (!ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) {
		pr_debug("failed, breakpoint set to bogus address\n");
		goto out;
	}

	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
		pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
		goto out;
	}

	waitpid(child, &status, 0);
	if (WIFEXITED(status)) {
		pr_debug("tracee exited prematurely 2\n");
		return TEST_FAIL;
	}

	rip = ptrace(PTRACE_PEEKUSER, child,
		     offsetof(struct user_regs_struct, rip), NULL);
	if (rip == (unsigned long) -1) {
		pr_debug("failed to PTRACE_PEEKUSER: %s\n",
			 strerror(errno));
		goto out;
	}

	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);

out:
	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
		pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
		return TEST_FAIL;
	}

	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
}

int test__bp_modify(struct test *test __maybe_unused,
		    int subtest __maybe_unused)
{
	TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1());
	TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2());

	return 0;
}
