18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <errno.h>
38c2ecf20Sopenharmony_ci#include <string.h>
48c2ecf20Sopenharmony_ci#include <regex.h>
58c2ecf20Sopenharmony_ci#include <linux/kernel.h>
68c2ecf20Sopenharmony_ci#include <linux/zalloc.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "../../../perf-sys.h"
98c2ecf20Sopenharmony_ci#include "../../../util/perf_regs.h"
108c2ecf20Sopenharmony_ci#include "../../../util/debug.h"
118c2ecf20Sopenharmony_ci#include "../../../util/event.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ciconst struct sample_reg sample_reg_masks[] = {
148c2ecf20Sopenharmony_ci	SMPL_REG(AX, PERF_REG_X86_AX),
158c2ecf20Sopenharmony_ci	SMPL_REG(BX, PERF_REG_X86_BX),
168c2ecf20Sopenharmony_ci	SMPL_REG(CX, PERF_REG_X86_CX),
178c2ecf20Sopenharmony_ci	SMPL_REG(DX, PERF_REG_X86_DX),
188c2ecf20Sopenharmony_ci	SMPL_REG(SI, PERF_REG_X86_SI),
198c2ecf20Sopenharmony_ci	SMPL_REG(DI, PERF_REG_X86_DI),
208c2ecf20Sopenharmony_ci	SMPL_REG(BP, PERF_REG_X86_BP),
218c2ecf20Sopenharmony_ci	SMPL_REG(SP, PERF_REG_X86_SP),
228c2ecf20Sopenharmony_ci	SMPL_REG(IP, PERF_REG_X86_IP),
238c2ecf20Sopenharmony_ci	SMPL_REG(FLAGS, PERF_REG_X86_FLAGS),
248c2ecf20Sopenharmony_ci	SMPL_REG(CS, PERF_REG_X86_CS),
258c2ecf20Sopenharmony_ci	SMPL_REG(SS, PERF_REG_X86_SS),
268c2ecf20Sopenharmony_ci#ifdef HAVE_ARCH_X86_64_SUPPORT
278c2ecf20Sopenharmony_ci	SMPL_REG(R8, PERF_REG_X86_R8),
288c2ecf20Sopenharmony_ci	SMPL_REG(R9, PERF_REG_X86_R9),
298c2ecf20Sopenharmony_ci	SMPL_REG(R10, PERF_REG_X86_R10),
308c2ecf20Sopenharmony_ci	SMPL_REG(R11, PERF_REG_X86_R11),
318c2ecf20Sopenharmony_ci	SMPL_REG(R12, PERF_REG_X86_R12),
328c2ecf20Sopenharmony_ci	SMPL_REG(R13, PERF_REG_X86_R13),
338c2ecf20Sopenharmony_ci	SMPL_REG(R14, PERF_REG_X86_R14),
348c2ecf20Sopenharmony_ci	SMPL_REG(R15, PERF_REG_X86_R15),
358c2ecf20Sopenharmony_ci#endif
368c2ecf20Sopenharmony_ci	SMPL_REG2(XMM0, PERF_REG_X86_XMM0),
378c2ecf20Sopenharmony_ci	SMPL_REG2(XMM1, PERF_REG_X86_XMM1),
388c2ecf20Sopenharmony_ci	SMPL_REG2(XMM2, PERF_REG_X86_XMM2),
398c2ecf20Sopenharmony_ci	SMPL_REG2(XMM3, PERF_REG_X86_XMM3),
408c2ecf20Sopenharmony_ci	SMPL_REG2(XMM4, PERF_REG_X86_XMM4),
418c2ecf20Sopenharmony_ci	SMPL_REG2(XMM5, PERF_REG_X86_XMM5),
428c2ecf20Sopenharmony_ci	SMPL_REG2(XMM6, PERF_REG_X86_XMM6),
438c2ecf20Sopenharmony_ci	SMPL_REG2(XMM7, PERF_REG_X86_XMM7),
448c2ecf20Sopenharmony_ci	SMPL_REG2(XMM8, PERF_REG_X86_XMM8),
458c2ecf20Sopenharmony_ci	SMPL_REG2(XMM9, PERF_REG_X86_XMM9),
468c2ecf20Sopenharmony_ci	SMPL_REG2(XMM10, PERF_REG_X86_XMM10),
478c2ecf20Sopenharmony_ci	SMPL_REG2(XMM11, PERF_REG_X86_XMM11),
488c2ecf20Sopenharmony_ci	SMPL_REG2(XMM12, PERF_REG_X86_XMM12),
498c2ecf20Sopenharmony_ci	SMPL_REG2(XMM13, PERF_REG_X86_XMM13),
508c2ecf20Sopenharmony_ci	SMPL_REG2(XMM14, PERF_REG_X86_XMM14),
518c2ecf20Sopenharmony_ci	SMPL_REG2(XMM15, PERF_REG_X86_XMM15),
528c2ecf20Sopenharmony_ci	SMPL_REG_END
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistruct sdt_name_reg {
568c2ecf20Sopenharmony_ci	const char *sdt_name;
578c2ecf20Sopenharmony_ci	const char *uprobe_name;
588c2ecf20Sopenharmony_ci};
598c2ecf20Sopenharmony_ci#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m}
608c2ecf20Sopenharmony_ci#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic const struct sdt_name_reg sdt_reg_tbl[] = {
638c2ecf20Sopenharmony_ci	SDT_NAME_REG(eax, ax),
648c2ecf20Sopenharmony_ci	SDT_NAME_REG(rax, ax),
658c2ecf20Sopenharmony_ci	SDT_NAME_REG(al,  ax),
668c2ecf20Sopenharmony_ci	SDT_NAME_REG(ah,  ax),
678c2ecf20Sopenharmony_ci	SDT_NAME_REG(ebx, bx),
688c2ecf20Sopenharmony_ci	SDT_NAME_REG(rbx, bx),
698c2ecf20Sopenharmony_ci	SDT_NAME_REG(bl,  bx),
708c2ecf20Sopenharmony_ci	SDT_NAME_REG(bh,  bx),
718c2ecf20Sopenharmony_ci	SDT_NAME_REG(ecx, cx),
728c2ecf20Sopenharmony_ci	SDT_NAME_REG(rcx, cx),
738c2ecf20Sopenharmony_ci	SDT_NAME_REG(cl,  cx),
748c2ecf20Sopenharmony_ci	SDT_NAME_REG(ch,  cx),
758c2ecf20Sopenharmony_ci	SDT_NAME_REG(edx, dx),
768c2ecf20Sopenharmony_ci	SDT_NAME_REG(rdx, dx),
778c2ecf20Sopenharmony_ci	SDT_NAME_REG(dl,  dx),
788c2ecf20Sopenharmony_ci	SDT_NAME_REG(dh,  dx),
798c2ecf20Sopenharmony_ci	SDT_NAME_REG(esi, si),
808c2ecf20Sopenharmony_ci	SDT_NAME_REG(rsi, si),
818c2ecf20Sopenharmony_ci	SDT_NAME_REG(sil, si),
828c2ecf20Sopenharmony_ci	SDT_NAME_REG(edi, di),
838c2ecf20Sopenharmony_ci	SDT_NAME_REG(rdi, di),
848c2ecf20Sopenharmony_ci	SDT_NAME_REG(dil, di),
858c2ecf20Sopenharmony_ci	SDT_NAME_REG(ebp, bp),
868c2ecf20Sopenharmony_ci	SDT_NAME_REG(rbp, bp),
878c2ecf20Sopenharmony_ci	SDT_NAME_REG(bpl, bp),
888c2ecf20Sopenharmony_ci	SDT_NAME_REG(rsp, sp),
898c2ecf20Sopenharmony_ci	SDT_NAME_REG(esp, sp),
908c2ecf20Sopenharmony_ci	SDT_NAME_REG(spl, sp),
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	/* rNN registers */
938c2ecf20Sopenharmony_ci	SDT_NAME_REG(r8b,  r8),
948c2ecf20Sopenharmony_ci	SDT_NAME_REG(r8w,  r8),
958c2ecf20Sopenharmony_ci	SDT_NAME_REG(r8d,  r8),
968c2ecf20Sopenharmony_ci	SDT_NAME_REG(r9b,  r9),
978c2ecf20Sopenharmony_ci	SDT_NAME_REG(r9w,  r9),
988c2ecf20Sopenharmony_ci	SDT_NAME_REG(r9d,  r9),
998c2ecf20Sopenharmony_ci	SDT_NAME_REG(r10b, r10),
1008c2ecf20Sopenharmony_ci	SDT_NAME_REG(r10w, r10),
1018c2ecf20Sopenharmony_ci	SDT_NAME_REG(r10d, r10),
1028c2ecf20Sopenharmony_ci	SDT_NAME_REG(r11b, r11),
1038c2ecf20Sopenharmony_ci	SDT_NAME_REG(r11w, r11),
1048c2ecf20Sopenharmony_ci	SDT_NAME_REG(r11d, r11),
1058c2ecf20Sopenharmony_ci	SDT_NAME_REG(r12b, r12),
1068c2ecf20Sopenharmony_ci	SDT_NAME_REG(r12w, r12),
1078c2ecf20Sopenharmony_ci	SDT_NAME_REG(r12d, r12),
1088c2ecf20Sopenharmony_ci	SDT_NAME_REG(r13b, r13),
1098c2ecf20Sopenharmony_ci	SDT_NAME_REG(r13w, r13),
1108c2ecf20Sopenharmony_ci	SDT_NAME_REG(r13d, r13),
1118c2ecf20Sopenharmony_ci	SDT_NAME_REG(r14b, r14),
1128c2ecf20Sopenharmony_ci	SDT_NAME_REG(r14w, r14),
1138c2ecf20Sopenharmony_ci	SDT_NAME_REG(r14d, r14),
1148c2ecf20Sopenharmony_ci	SDT_NAME_REG(r15b, r15),
1158c2ecf20Sopenharmony_ci	SDT_NAME_REG(r15w, r15),
1168c2ecf20Sopenharmony_ci	SDT_NAME_REG(r15d, r15),
1178c2ecf20Sopenharmony_ci	SDT_NAME_REG_END,
1188c2ecf20Sopenharmony_ci};
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/*
1218c2ecf20Sopenharmony_ci * Perf only supports OP which is in  +/-NUM(REG)  form.
1228c2ecf20Sopenharmony_ci * Here plus-minus sign, NUM and parenthesis are optional,
1238c2ecf20Sopenharmony_ci * only REG is mandatory.
1248c2ecf20Sopenharmony_ci *
1258c2ecf20Sopenharmony_ci * SDT events also supports indirect addressing mode with a
1268c2ecf20Sopenharmony_ci * symbol as offset, scaled mode and constants in OP. But
1278c2ecf20Sopenharmony_ci * perf does not support them yet. Below are few examples.
1288c2ecf20Sopenharmony_ci *
1298c2ecf20Sopenharmony_ci * OP with scaled mode:
1308c2ecf20Sopenharmony_ci *     (%rax,%rsi,8)
1318c2ecf20Sopenharmony_ci *     10(%ras,%rsi,8)
1328c2ecf20Sopenharmony_ci *
1338c2ecf20Sopenharmony_ci * OP with indirect addressing mode:
1348c2ecf20Sopenharmony_ci *     check_action(%rip)
1358c2ecf20Sopenharmony_ci *     mp_+52(%rip)
1368c2ecf20Sopenharmony_ci *     44+mp_(%rip)
1378c2ecf20Sopenharmony_ci *
1388c2ecf20Sopenharmony_ci * OP with constant values:
1398c2ecf20Sopenharmony_ci *     $0
1408c2ecf20Sopenharmony_ci *     $123
1418c2ecf20Sopenharmony_ci *     $-1
1428c2ecf20Sopenharmony_ci */
1438c2ecf20Sopenharmony_ci#define SDT_OP_REGEX  "^([+\\-]?)([0-9]*)(\\(?)(%[a-z][a-z0-9]+)(\\)?)$"
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic regex_t sdt_op_regex;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistatic int sdt_init_op_regex(void)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	static int initialized;
1508c2ecf20Sopenharmony_ci	int ret = 0;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	if (initialized)
1538c2ecf20Sopenharmony_ci		return 0;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	ret = regcomp(&sdt_op_regex, SDT_OP_REGEX, REG_EXTENDED);
1568c2ecf20Sopenharmony_ci	if (ret < 0) {
1578c2ecf20Sopenharmony_ci		pr_debug4("Regex compilation error.\n");
1588c2ecf20Sopenharmony_ci		return ret;
1598c2ecf20Sopenharmony_ci	}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	initialized = 1;
1628c2ecf20Sopenharmony_ci	return 0;
1638c2ecf20Sopenharmony_ci}
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci/*
1668c2ecf20Sopenharmony_ci * Max x86 register name length is 5(ex: %r15d). So, 6th char
1678c2ecf20Sopenharmony_ci * should always contain NULL. This helps to find register name
1688c2ecf20Sopenharmony_ci * length using strlen, insted of maintaing one more variable.
1698c2ecf20Sopenharmony_ci */
1708c2ecf20Sopenharmony_ci#define SDT_REG_NAME_SIZE  6
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci/*
1738c2ecf20Sopenharmony_ci * The uprobe parser does not support all gas register names;
1748c2ecf20Sopenharmony_ci * so, we have to replace them (ex. for x86_64: %rax -> %ax).
1758c2ecf20Sopenharmony_ci * Note: If register does not require renaming, just copy
1768c2ecf20Sopenharmony_ci * paste as it is, but don't leave it empty.
1778c2ecf20Sopenharmony_ci */
1788c2ecf20Sopenharmony_cistatic void sdt_rename_register(char *sdt_reg, int sdt_len, char *uprobe_reg)
1798c2ecf20Sopenharmony_ci{
1808c2ecf20Sopenharmony_ci	int i = 0;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	for (i = 0; sdt_reg_tbl[i].sdt_name != NULL; i++) {
1838c2ecf20Sopenharmony_ci		if (!strncmp(sdt_reg_tbl[i].sdt_name, sdt_reg, sdt_len)) {
1848c2ecf20Sopenharmony_ci			strcpy(uprobe_reg, sdt_reg_tbl[i].uprobe_name);
1858c2ecf20Sopenharmony_ci			return;
1868c2ecf20Sopenharmony_ci		}
1878c2ecf20Sopenharmony_ci	}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	strncpy(uprobe_reg, sdt_reg, sdt_len);
1908c2ecf20Sopenharmony_ci}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ciint arch_sdt_arg_parse_op(char *old_op, char **new_op)
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	char new_reg[SDT_REG_NAME_SIZE] = {0};
1958c2ecf20Sopenharmony_ci	int new_len = 0, ret;
1968c2ecf20Sopenharmony_ci	/*
1978c2ecf20Sopenharmony_ci	 * rm[0]:  +/-NUM(REG)
1988c2ecf20Sopenharmony_ci	 * rm[1]:  +/-
1998c2ecf20Sopenharmony_ci	 * rm[2]:  NUM
2008c2ecf20Sopenharmony_ci	 * rm[3]:  (
2018c2ecf20Sopenharmony_ci	 * rm[4]:  REG
2028c2ecf20Sopenharmony_ci	 * rm[5]:  )
2038c2ecf20Sopenharmony_ci	 */
2048c2ecf20Sopenharmony_ci	regmatch_t rm[6];
2058c2ecf20Sopenharmony_ci	/*
2068c2ecf20Sopenharmony_ci	 * Max prefix length is 2 as it may contains sign(+/-)
2078c2ecf20Sopenharmony_ci	 * and displacement 0 (Both sign and displacement 0 are
2088c2ecf20Sopenharmony_ci	 * optional so it may be empty). Use one more character
2098c2ecf20Sopenharmony_ci	 * to hold last NULL so that strlen can be used to find
2108c2ecf20Sopenharmony_ci	 * prefix length, instead of maintaing one more variable.
2118c2ecf20Sopenharmony_ci	 */
2128c2ecf20Sopenharmony_ci	char prefix[3] = {0};
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	ret = sdt_init_op_regex();
2158c2ecf20Sopenharmony_ci	if (ret < 0)
2168c2ecf20Sopenharmony_ci		return ret;
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	/*
2198c2ecf20Sopenharmony_ci	 * If unsupported OR does not match with regex OR
2208c2ecf20Sopenharmony_ci	 * register name too long, skip it.
2218c2ecf20Sopenharmony_ci	 */
2228c2ecf20Sopenharmony_ci	if (strchr(old_op, ',') || strchr(old_op, '$') ||
2238c2ecf20Sopenharmony_ci	    regexec(&sdt_op_regex, old_op, 6, rm, 0)   ||
2248c2ecf20Sopenharmony_ci	    rm[4].rm_eo - rm[4].rm_so > SDT_REG_NAME_SIZE) {
2258c2ecf20Sopenharmony_ci		pr_debug4("Skipping unsupported SDT argument: %s\n", old_op);
2268c2ecf20Sopenharmony_ci		return SDT_ARG_SKIP;
2278c2ecf20Sopenharmony_ci	}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	/*
2308c2ecf20Sopenharmony_ci	 * Prepare prefix.
2318c2ecf20Sopenharmony_ci	 * If SDT OP has parenthesis but does not provide
2328c2ecf20Sopenharmony_ci	 * displacement, add 0 for displacement.
2338c2ecf20Sopenharmony_ci	 *     SDT         Uprobe     Prefix
2348c2ecf20Sopenharmony_ci	 *     -----------------------------
2358c2ecf20Sopenharmony_ci	 *     +24(%rdi)   +24(%di)   +
2368c2ecf20Sopenharmony_ci	 *     24(%rdi)    +24(%di)   +
2378c2ecf20Sopenharmony_ci	 *     %rdi        %di
2388c2ecf20Sopenharmony_ci	 *     (%rdi)      +0(%di)    +0
2398c2ecf20Sopenharmony_ci	 *     -80(%rbx)   -80(%bx)   -
2408c2ecf20Sopenharmony_ci	 */
2418c2ecf20Sopenharmony_ci	if (rm[3].rm_so != rm[3].rm_eo) {
2428c2ecf20Sopenharmony_ci		if (rm[1].rm_so != rm[1].rm_eo)
2438c2ecf20Sopenharmony_ci			prefix[0] = *(old_op + rm[1].rm_so);
2448c2ecf20Sopenharmony_ci		else if (rm[2].rm_so != rm[2].rm_eo)
2458c2ecf20Sopenharmony_ci			prefix[0] = '+';
2468c2ecf20Sopenharmony_ci		else
2478c2ecf20Sopenharmony_ci			scnprintf(prefix, sizeof(prefix), "+0");
2488c2ecf20Sopenharmony_ci	}
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	/* Rename register */
2518c2ecf20Sopenharmony_ci	sdt_rename_register(old_op + rm[4].rm_so, rm[4].rm_eo - rm[4].rm_so,
2528c2ecf20Sopenharmony_ci			    new_reg);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	/* Prepare final OP which should be valid for uprobe_events */
2558c2ecf20Sopenharmony_ci	new_len = strlen(prefix)              +
2568c2ecf20Sopenharmony_ci		  (rm[2].rm_eo - rm[2].rm_so) +
2578c2ecf20Sopenharmony_ci		  (rm[3].rm_eo - rm[3].rm_so) +
2588c2ecf20Sopenharmony_ci		  strlen(new_reg)             +
2598c2ecf20Sopenharmony_ci		  (rm[5].rm_eo - rm[5].rm_so) +
2608c2ecf20Sopenharmony_ci		  1;					/* NULL */
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	*new_op = zalloc(new_len);
2638c2ecf20Sopenharmony_ci	if (!*new_op)
2648c2ecf20Sopenharmony_ci		return -ENOMEM;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	scnprintf(*new_op, new_len, "%.*s%.*s%.*s%.*s%.*s",
2678c2ecf20Sopenharmony_ci		  strlen(prefix), prefix,
2688c2ecf20Sopenharmony_ci		  (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so,
2698c2ecf20Sopenharmony_ci		  (int)(rm[3].rm_eo - rm[3].rm_so), old_op + rm[3].rm_so,
2708c2ecf20Sopenharmony_ci		  strlen(new_reg), new_reg,
2718c2ecf20Sopenharmony_ci		  (int)(rm[5].rm_eo - rm[5].rm_so), old_op + rm[5].rm_so);
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	return SDT_ARG_VALID;
2748c2ecf20Sopenharmony_ci}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ciuint64_t arch__intr_reg_mask(void)
2778c2ecf20Sopenharmony_ci{
2788c2ecf20Sopenharmony_ci	struct perf_event_attr attr = {
2798c2ecf20Sopenharmony_ci		.type			= PERF_TYPE_HARDWARE,
2808c2ecf20Sopenharmony_ci		.config			= PERF_COUNT_HW_CPU_CYCLES,
2818c2ecf20Sopenharmony_ci		.sample_type		= PERF_SAMPLE_REGS_INTR,
2828c2ecf20Sopenharmony_ci		.sample_regs_intr	= PERF_REG_EXTENDED_MASK,
2838c2ecf20Sopenharmony_ci		.precise_ip		= 1,
2848c2ecf20Sopenharmony_ci		.disabled 		= 1,
2858c2ecf20Sopenharmony_ci		.exclude_kernel		= 1,
2868c2ecf20Sopenharmony_ci	};
2878c2ecf20Sopenharmony_ci	int fd;
2888c2ecf20Sopenharmony_ci	/*
2898c2ecf20Sopenharmony_ci	 * In an unnamed union, init it here to build on older gcc versions
2908c2ecf20Sopenharmony_ci	 */
2918c2ecf20Sopenharmony_ci	attr.sample_period = 1;
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	event_attr_init(&attr);
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
2968c2ecf20Sopenharmony_ci	if (fd != -1) {
2978c2ecf20Sopenharmony_ci		close(fd);
2988c2ecf20Sopenharmony_ci		return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK);
2998c2ecf20Sopenharmony_ci	}
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	return PERF_REGS_MASK;
3028c2ecf20Sopenharmony_ci}
303