// SPDX-License-Identifier: GPL-2.0
/*
 * Inspired by breakpoint overflow test done by
 * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests
 * (git://github.com/deater/perf_event_tests)
 */

/*
 * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
 * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
 */
#define __SANE_USERSPACE_TYPES__

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/mman.h>
#include <linux/compiler.h>
#include <linux/hw_breakpoint.h>

#include "tests.h"
#include "debug.h"
#include "event.h"
#include "parse-events.h"
#include "perf-sys.h"
#include "cloexec.h"

static int fd1;
static int fd2;
static int fd3;
static int overflows;
static int overflows_2;

volatile long the_var;


/*
 * Use ASM to ensure watchpoint and breakpoint can be triggered
 * at one instruction.
 */
#if defined (__x86_64__)
extern void __test_function(volatile long *ptr);
asm (
	".pushsection .text;"
	".globl __test_function\n"
	".type __test_function, @function;"
	"__test_function:\n"
	"incq (%rdi)\n"
	"ret\n"
	".popsection\n");
#else
static void __test_function(volatile long *ptr)
{
	*ptr = 0x1234;
}
#endif

static noinline int test_function(void)
{
	__test_function(&the_var);
	the_var++;
	return time(NULL);
}

static void sig_handler_2(int signum __maybe_unused,
			  siginfo_t *oh __maybe_unused,
			  void *uc __maybe_unused)
{
	overflows_2++;
	if (overflows_2 > 10) {
		ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
		ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
		ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
	}
}

static void sig_handler(int signum __maybe_unused,
			siginfo_t *oh __maybe_unused,
			void *uc __maybe_unused)
{
	overflows++;

	if (overflows > 10) {
		/*
		 * This should be executed only once during
		 * this test, if we are here for the 10th
		 * time, consider this the recursive issue.
		 *
		 * We can get out of here by disable events,
		 * so no new SIGIO is delivered.
		 */
		ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
		ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
		ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
	}
}

static int __event(bool is_x, void *addr, int sig)
{
	struct perf_event_attr pe;
	int fd;

	memset(&pe, 0, sizeof(struct perf_event_attr));
	pe.type = PERF_TYPE_BREAKPOINT;
	pe.size = sizeof(struct perf_event_attr);

	pe.config = 0;
	pe.bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
	pe.bp_addr = (unsigned long) addr;
	pe.bp_len = is_x ? default_breakpoint_len() : sizeof(long);

	pe.sample_period = 1;
	pe.sample_type = PERF_SAMPLE_IP;
	pe.wakeup_events = 1;

	pe.disabled = 1;
	pe.exclude_kernel = 1;
	pe.exclude_hv = 1;

	fd = sys_perf_event_open(&pe, 0, -1, -1,
				 perf_event_open_cloexec_flag());
	if (fd < 0) {
		pr_debug("failed opening event %llx\n", pe.config);
		return TEST_FAIL;
	}

	fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
	fcntl(fd, F_SETSIG, sig);
	fcntl(fd, F_SETOWN, getpid());

	ioctl(fd, PERF_EVENT_IOC_RESET, 0);

	return fd;
}

static int bp_event(void *addr, int sig)
{
	return __event(true, addr, sig);
}

static int wp_event(void *addr, int sig)
{
	return __event(false, addr, sig);
}

static long long bp_count(int fd)
{
	long long count;
	int ret;

	ret = read(fd, &count, sizeof(long long));
	if (ret != sizeof(long long)) {
		pr_debug("failed to read: %d\n", ret);
		return TEST_FAIL;
	}

	return count;
}

static int test__bp_signal(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
	struct sigaction sa;
	long long count1, count2, count3;

	if (!BP_SIGNAL_IS_SUPPORTED) {
		pr_debug("Test not supported on this architecture");
		return TEST_SKIP;
	}

	/* setup SIGIO signal handler */
	memset(&sa, 0, sizeof(struct sigaction));
	sa.sa_sigaction = (void *) sig_handler;
	sa.sa_flags = SA_SIGINFO;

	if (sigaction(SIGIO, &sa, NULL) < 0) {
		pr_debug("failed setting up signal handler\n");
		return TEST_FAIL;
	}

	sa.sa_sigaction = (void *) sig_handler_2;
	if (sigaction(SIGUSR1, &sa, NULL) < 0) {
		pr_debug("failed setting up signal handler 2\n");
		return TEST_FAIL;
	}

	/*
	 * We create following events:
	 *
	 * fd1 - breakpoint event on __test_function with SIGIO
	 *       signal configured. We should get signal
	 *       notification each time the breakpoint is hit
	 *
	 * fd2 - breakpoint event on sig_handler with SIGUSR1
	 *       configured. We should get SIGUSR1 each time when
	 *       breakpoint is hit
	 *
	 * fd3 - watchpoint event on __test_function with SIGIO
	 *       configured.
	 *
	 * Following processing should happen:
	 *   Exec:               Action:                       Result:
	 *   incq (%rdi)       - fd1 event breakpoint hit   -> count1 == 1
	 *                     - SIGIO is delivered
	 *   sig_handler       - fd2 event breakpoint hit   -> count2 == 1
	 *                     - SIGUSR1 is delivered
	 *   sig_handler_2                                  -> overflows_2 == 1  (nested signal)
	 *   sys_rt_sigreturn  - return from sig_handler_2
	 *   overflows++                                    -> overflows = 1
	 *   sys_rt_sigreturn  - return from sig_handler
	 *   incq (%rdi)       - fd3 event watchpoint hit   -> count3 == 1       (wp and bp in one insn)
	 *                     - SIGIO is delivered
	 *   sig_handler       - fd2 event breakpoint hit   -> count2 == 2
	 *                     - SIGUSR1 is delivered
	 *   sig_handler_2                                  -> overflows_2 == 2  (nested signal)
	 *   sys_rt_sigreturn  - return from sig_handler_2
	 *   overflows++                                    -> overflows = 2
	 *   sys_rt_sigreturn  - return from sig_handler
	 *   the_var++         - fd3 event watchpoint hit   -> count3 == 2       (standalone watchpoint)
	 *                     - SIGIO is delivered
	 *   sig_handler       - fd2 event breakpoint hit   -> count2 == 3
	 *                     - SIGUSR1 is delivered
	 *   sig_handler_2                                  -> overflows_2 == 3  (nested signal)
	 *   sys_rt_sigreturn  - return from sig_handler_2
	 *   overflows++                                    -> overflows == 3
	 *   sys_rt_sigreturn  - return from sig_handler
	 *
	 * The test case check following error conditions:
	 * - we get stuck in signal handler because of debug
	 *   exception being triggered recursively due to
	 *   the wrong RF EFLAG management
	 *
	 * - we never trigger the sig_handler breakpoint due
	 *   to the wrong RF EFLAG management
	 *
	 */

	fd1 = bp_event(__test_function, SIGIO);
	fd2 = bp_event(sig_handler, SIGUSR1);
	fd3 = wp_event((void *)&the_var, SIGIO);

	ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
	ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
	ioctl(fd3, PERF_EVENT_IOC_ENABLE, 0);

	/*
	 * Kick off the test by triggering 'fd1'
	 * breakpoint.
	 */
	test_function();

	ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
	ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
	ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);

	count1 = bp_count(fd1);
	count2 = bp_count(fd2);
	count3 = bp_count(fd3);

	close(fd1);
	close(fd2);
	close(fd3);

	pr_debug("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n",
		 count1, count2, count3, overflows, overflows_2);

	if (count1 != 1) {
		if (count1 == 11)
			pr_debug("failed: RF EFLAG recursion issue detected\n");
		else
			pr_debug("failed: wrong count for bp1: %lld, expected 1\n", count1);
	}

	if (overflows != 3)
		pr_debug("failed: wrong overflow (%d) hit, expected 3\n", overflows);

	if (overflows_2 != 3)
		pr_debug("failed: wrong overflow_2 (%d) hit, expected 3\n", overflows_2);

	if (count2 != 3)
		pr_debug("failed: wrong count for bp2 (%lld), expected 3\n", count2);

	if (count3 != 2)
		pr_debug("failed: wrong count for bp3 (%lld), expected 2\n", count3);

	return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
		TEST_OK : TEST_FAIL;
}

DEFINE_SUITE("Breakpoint overflow signal handler", bp_signal);
