18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <signal.h>
38c2ecf20Sopenharmony_ci#include <stdlib.h>
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include "tests.h"
68c2ecf20Sopenharmony_ci#include "debug.h"
78c2ecf20Sopenharmony_ci#include "perf-hooks.h"
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistatic void sigsegv_handler(int sig __maybe_unused)
108c2ecf20Sopenharmony_ci{
118c2ecf20Sopenharmony_ci	pr_debug("SIGSEGV is observed as expected, try to recover.\n");
128c2ecf20Sopenharmony_ci	perf_hooks__recover();
138c2ecf20Sopenharmony_ci	signal(SIGSEGV, SIG_DFL);
148c2ecf20Sopenharmony_ci	raise(SIGSEGV);
158c2ecf20Sopenharmony_ci	exit(-1);
168c2ecf20Sopenharmony_ci}
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistatic void the_hook(void *_hook_flags)
208c2ecf20Sopenharmony_ci{
218c2ecf20Sopenharmony_ci	int *hook_flags = _hook_flags;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	*hook_flags = 1234;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	/* Generate a segfault, test perf_hooks__recover */
268c2ecf20Sopenharmony_ci	raise(SIGSEGV);
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciint test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	int hook_flags = 0;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	signal(SIGSEGV, sigsegv_handler);
348c2ecf20Sopenharmony_ci	perf_hooks__set_hook("test", the_hook, &hook_flags);
358c2ecf20Sopenharmony_ci	perf_hooks__invoke_test();
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	/* hook is triggered? */
388c2ecf20Sopenharmony_ci	if (hook_flags != 1234) {
398c2ecf20Sopenharmony_ci		pr_debug("Setting failed: %d (%p)\n", hook_flags, &hook_flags);
408c2ecf20Sopenharmony_ci		return TEST_FAIL;
418c2ecf20Sopenharmony_ci	}
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	/* the buggy hook is removed? */
448c2ecf20Sopenharmony_ci	if (perf_hooks__get_hook("test"))
458c2ecf20Sopenharmony_ci		return TEST_FAIL;
468c2ecf20Sopenharmony_ci	return TEST_OK;
478c2ecf20Sopenharmony_ci}
48