// SPDX-License-Identifier: GPL-2.0
/*
 * Test for perf events with SIGTRAP across all threads.
 *
 * Copyright (C) 2021, Google LLC.
 */

#define _GNU_SOURCE

/* We need the latest siginfo from the kernel repo. */
#include <sys/types.h>
#include <asm/siginfo.h>
#define __have_siginfo_t 1
#define __have_sigval_t 1
#define __have_sigevent_t 1
#define __siginfo_t_defined
#define __sigval_t_defined
#define __sigevent_t_defined
#define _BITS_SIGINFO_CONSTS_H 1
#define _BITS_SIGEVENT_CONSTS_H 1

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <linux/hw_breakpoint.h>
#include <linux/perf_event.h>
#include <pthread.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <unistd.h>

#include "../kselftest_harness.h"

#define NUM_THREADS 5

/* Data shared between test body, threads, and signal handler. */
static struct {
	int tids_want_signal;		/* Which threads still want a signal. */
	int signal_count;		/* Sanity check number of signals received. */
	volatile int iterate_on;	/* Variable to set breakpoint on. */
	siginfo_t first_siginfo;	/* First observed siginfo_t. */
} ctx;

/* Unique value to check si_perf_data is correctly set from perf_event_attr::sig_data. */
#define TEST_SIG_DATA(addr, id) (~(unsigned long)(addr) + id)

static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr,
					      unsigned long id)
{
	struct perf_event_attr attr = {
		.type		= PERF_TYPE_BREAKPOINT,
		.size		= sizeof(attr),
		.sample_period	= 1,
		.disabled	= !enabled,
		.bp_addr	= (unsigned long)addr,
		.bp_type	= HW_BREAKPOINT_RW,
		.bp_len		= HW_BREAKPOINT_LEN_1,
		.inherit	= 1, /* Children inherit events ... */
		.inherit_thread = 1, /* ... but only cloned with CLONE_THREAD. */
		.remove_on_exec = 1, /* Required by sigtrap. */
		.sigtrap	= 1, /* Request synchronous SIGTRAP on event. */
		.sig_data	= TEST_SIG_DATA(addr, id),
		.exclude_kernel = 1, /* To allow */
		.exclude_hv     = 1, /* running as !root */
	};
	return attr;
}

static void sigtrap_handler(int signum, siginfo_t *info, void *ucontext)
{
	if (info->si_code != TRAP_PERF) {
		fprintf(stderr, "%s: unexpected si_code %d\n", __func__, info->si_code);
		return;
	}

	/*
	 * The data in siginfo_t we're interested in should all be the same
	 * across threads.
	 */
	if (!__atomic_fetch_add(&ctx.signal_count, 1, __ATOMIC_RELAXED))
		ctx.first_siginfo = *info;
	__atomic_fetch_sub(&ctx.tids_want_signal, syscall(__NR_gettid), __ATOMIC_RELAXED);
}

static void *test_thread(void *arg)
{
	pthread_barrier_t *barrier = (pthread_barrier_t *)arg;
	pid_t tid = syscall(__NR_gettid);
	int iter;
	int i;

	pthread_barrier_wait(barrier);

	__atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED);
	iter = ctx.iterate_on; /* read */
	if (iter >= 0) {
		for (i = 0; i < iter - 1; i++) {
			__atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED);
			ctx.iterate_on = iter; /* idempotent write */
		}
	} else {
		while (ctx.iterate_on);
	}

	return NULL;
}

FIXTURE(sigtrap_threads)
{
	struct sigaction oldact;
	pthread_t threads[NUM_THREADS];
	pthread_barrier_t barrier;
	int fd;
};

FIXTURE_SETUP(sigtrap_threads)
{
	struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on, 0);
	struct sigaction action = {};
	int i;

	memset(&ctx, 0, sizeof(ctx));

	/* Initialize sigtrap handler. */
	action.sa_flags = SA_SIGINFO | SA_NODEFER;
	action.sa_sigaction = sigtrap_handler;
	sigemptyset(&action.sa_mask);
	ASSERT_EQ(sigaction(SIGTRAP, &action, &self->oldact), 0);

	/* Initialize perf event. */
	self->fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, PERF_FLAG_FD_CLOEXEC);
	ASSERT_NE(self->fd, -1);

	/* Spawn threads inheriting perf event. */
	pthread_barrier_init(&self->barrier, NULL, NUM_THREADS + 1);
	for (i = 0; i < NUM_THREADS; i++)
		ASSERT_EQ(pthread_create(&self->threads[i], NULL, test_thread, &self->barrier), 0);
}

FIXTURE_TEARDOWN(sigtrap_threads)
{
	pthread_barrier_destroy(&self->barrier);
	close(self->fd);
	sigaction(SIGTRAP, &self->oldact, NULL);
}

static void run_test_threads(struct __test_metadata *_metadata,
			     FIXTURE_DATA(sigtrap_threads) *self)
{
	int i;

	pthread_barrier_wait(&self->barrier);
	for (i = 0; i < NUM_THREADS; i++)
		ASSERT_EQ(pthread_join(self->threads[i], NULL), 0);
}

TEST_F(sigtrap_threads, remain_disabled)
{
	run_test_threads(_metadata, self);
	EXPECT_EQ(ctx.signal_count, 0);
	EXPECT_NE(ctx.tids_want_signal, 0);
}

TEST_F(sigtrap_threads, enable_event)
{
	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
	run_test_threads(_metadata, self);

	EXPECT_EQ(ctx.signal_count, NUM_THREADS);
	EXPECT_EQ(ctx.tids_want_signal, 0);
	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));

	/* Check enabled for parent. */
	ctx.iterate_on = 0;
	EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1);
}

/* Test that modification propagates to all inherited events. */
TEST_F(sigtrap_threads, modify_and_enable_event)
{
	struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on, 42);

	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &new_attr), 0);
	run_test_threads(_metadata, self);

	EXPECT_EQ(ctx.signal_count, NUM_THREADS);
	EXPECT_EQ(ctx.tids_want_signal, 0);
	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 42));

	/* Check enabled for parent. */
	ctx.iterate_on = 0;
	EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1);
}

/* Stress test event + signal handling. */
TEST_F(sigtrap_threads, signal_stress)
{
	ctx.iterate_on = 3000;

	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
	run_test_threads(_metadata, self);
	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0);

	EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on);
	EXPECT_EQ(ctx.tids_want_signal, 0);
	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
}

TEST_F(sigtrap_threads, signal_stress_with_disable)
{
	const int target_count = NUM_THREADS * 3000;
	int i;

	ctx.iterate_on = -1;

	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
	pthread_barrier_wait(&self->barrier);
	while (__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED) < target_count) {
		EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0);
		EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
	}
	ctx.iterate_on = 0;
	for (i = 0; i < NUM_THREADS; i++)
		ASSERT_EQ(pthread_join(self->threads[i], NULL), 0);
	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0);

	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
}

TEST_HARNESS_MAIN
