// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.*/

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <test_progs.h>
#include <bpf/btf.h>
#include "rcu_read_lock.skel.h"
#include "cgroup_helpers.h"

static unsigned long long cgroup_id;

static void test_success(void)
{
	struct rcu_read_lock *skel;
	int err;

	skel = rcu_read_lock__open();
	if (!ASSERT_OK_PTR(skel, "skel_open"))
		return;

	skel->bss->target_pid = syscall(SYS_gettid);

	bpf_program__set_autoload(skel->progs.get_cgroup_id, true);
	bpf_program__set_autoload(skel->progs.task_succ, true);
	bpf_program__set_autoload(skel->progs.two_regions, true);
	bpf_program__set_autoload(skel->progs.non_sleepable_1, true);
	bpf_program__set_autoload(skel->progs.non_sleepable_2, true);
	bpf_program__set_autoload(skel->progs.task_trusted_non_rcuptr, true);
	err = rcu_read_lock__load(skel);
	if (!ASSERT_OK(err, "skel_load"))
		goto out;

	err = rcu_read_lock__attach(skel);
	if (!ASSERT_OK(err, "skel_attach"))
		goto out;

	syscall(SYS_getpgid);

	ASSERT_EQ(skel->bss->task_storage_val, 2, "task_storage_val");
	ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");
out:
	rcu_read_lock__destroy(skel);
}

static void test_rcuptr_acquire(void)
{
	struct rcu_read_lock *skel;
	int err;

	skel = rcu_read_lock__open();
	if (!ASSERT_OK_PTR(skel, "skel_open"))
		return;

	skel->bss->target_pid = syscall(SYS_gettid);

	bpf_program__set_autoload(skel->progs.task_acquire, true);
	err = rcu_read_lock__load(skel);
	if (!ASSERT_OK(err, "skel_load"))
		goto out;

	err = rcu_read_lock__attach(skel);
	ASSERT_OK(err, "skel_attach");
out:
	rcu_read_lock__destroy(skel);
}

static const char * const inproper_region_tests[] = {
	"miss_lock",
	"no_lock",
	"miss_unlock",
	"non_sleepable_rcu_mismatch",
	"inproper_sleepable_helper",
	"inproper_sleepable_kfunc",
	"nested_rcu_region",
};

static void test_inproper_region(void)
{
	struct rcu_read_lock *skel;
	struct bpf_program *prog;
	int i, err;

	for (i = 0; i < ARRAY_SIZE(inproper_region_tests); i++) {
		skel = rcu_read_lock__open();
		if (!ASSERT_OK_PTR(skel, "skel_open"))
			return;

		prog = bpf_object__find_program_by_name(skel->obj, inproper_region_tests[i]);
		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
			goto out;
		bpf_program__set_autoload(prog, true);
		err = rcu_read_lock__load(skel);
		ASSERT_ERR(err, "skel_load");
out:
		rcu_read_lock__destroy(skel);
	}
}

static const char * const rcuptr_misuse_tests[] = {
	"task_untrusted_rcuptr",
	"cross_rcu_region",
};

static void test_rcuptr_misuse(void)
{
	struct rcu_read_lock *skel;
	struct bpf_program *prog;
	int i, err;

	for (i = 0; i < ARRAY_SIZE(rcuptr_misuse_tests); i++) {
		skel = rcu_read_lock__open();
		if (!ASSERT_OK_PTR(skel, "skel_open"))
			return;

		prog = bpf_object__find_program_by_name(skel->obj, rcuptr_misuse_tests[i]);
		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
			goto out;
		bpf_program__set_autoload(prog, true);
		err = rcu_read_lock__load(skel);
		ASSERT_ERR(err, "skel_load");
out:
		rcu_read_lock__destroy(skel);
	}
}

void test_rcu_read_lock(void)
{
	int cgroup_fd;

	cgroup_fd = test__join_cgroup("/rcu_read_lock");
	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /rcu_read_lock"))
		goto out;

	cgroup_id = get_cgroup_id("/rcu_read_lock");
	if (test__start_subtest("success"))
		test_success();
	if (test__start_subtest("rcuptr_acquire"))
		test_rcuptr_acquire();
	if (test__start_subtest("negative_tests_inproper_region"))
		test_inproper_region();
	if (test__start_subtest("negative_tests_rcuptr_misuse"))
		test_rcuptr_misuse();
	close(cgroup_fd);
out:;
}
