xref: /linux/tools/testing/selftests/arm64/mte/mte_common_util.h (revision 3ae8cef210dd52ae95fd5a87f9bea0932bd4e470)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2020 ARM Limited */
3 
4 #ifndef _MTE_COMMON_UTIL_H
5 #define _MTE_COMMON_UTIL_H
6 
7 #include <signal.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <sys/auxv.h>
11 #include <sys/mman.h>
12 #include <sys/prctl.h>
13 #include "mte_def.h"
14 #include "kselftest.h"
15 
16 enum mte_mem_type {
17 	USE_MALLOC,
18 	USE_MMAP,
19 	USE_MPROTECT,
20 };
21 
22 enum mte_mode {
23 	MTE_NONE_ERR,
24 	MTE_SYNC_ERR,
25 	MTE_ASYNC_ERR,
26 };
27 
28 struct mte_fault_cxt {
29 	/* Address start which triggers mte tag fault */
30 	unsigned long trig_addr;
31 	/* Address range for mte tag fault and negative value means underflow */
32 	ssize_t trig_range;
33 	/* siginfo si code */
34 	unsigned long trig_si_code;
35 	/* Flag to denote if correct fault caught */
36 	bool fault_valid;
37 };
38 
39 extern struct mte_fault_cxt cur_mte_cxt;
40 extern bool mtefar_support;
41 
42 /* MTE utility functions */
43 void mte_default_handler(int signum, siginfo_t *si, void *uc);
44 void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *),
45 			 bool export_tags);
46 void mte_wait_after_trig(void);
47 void *mte_allocate_memory(size_t size, int mem_type, int mapping, bool tags);
48 void *mte_allocate_memory_tag_range(size_t size, int mem_type, int mapping,
49 				    size_t range_before, size_t range_after);
50 void *mte_allocate_file_memory(size_t size, int mem_type, int mapping,
51 			       bool tags, int fd);
52 void *mte_allocate_file_memory_tag_range(size_t size, int mem_type, int mapping,
53 					 size_t range_before, size_t range_after, int fd);
54 void mte_free_memory(void *ptr, size_t size, int mem_type, bool tags);
55 void mte_free_memory_tag_range(void *ptr, size_t size, int mem_type,
56 			       size_t range_before, size_t range_after);
57 void *mte_insert_tags(void *ptr, size_t size);
58 void mte_clear_tags(void *ptr, size_t size);
59 void *mte_insert_atag(void *ptr);
60 void *mte_clear_atag(void *ptr);
61 int mte_default_setup(void);
62 void mte_restore_setup(void);
63 int mte_switch_mode(int mte_option, unsigned long incl_mask);
64 void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range);
65 
66 /* Common utility functions */
67 int create_temp_file(void);
68 
69 /* Assembly MTE utility functions */
70 void *mte_insert_random_tag(void *ptr);
71 void *mte_insert_new_tag(void *ptr);
72 void *mte_get_tag_address(void *ptr);
73 void mte_set_tag_address_range(void *ptr, int range);
74 void mte_clear_tag_address_range(void *ptr, int range);
75 void mte_disable_pstate_tco(void);
76 void mte_enable_pstate_tco(void);
77 unsigned int mte_get_pstate_tco(void);
78 
79 /* Test framework static inline functions/macros */
80 static inline void evaluate_test(int err, const char *msg)
81 {
82 	switch (err) {
83 	case KSFT_PASS:
84 		ksft_test_result_pass("%s", msg);
85 		break;
86 	case KSFT_FAIL:
87 		ksft_test_result_fail("%s", msg);
88 		break;
89 	case KSFT_SKIP:
90 		ksft_test_result_skip("%s", msg);
91 		break;
92 	default:
93 		ksft_test_result_error("Unknown return code %d from %s",
94 				       err, msg);
95 		break;
96 	}
97 }
98 
99 static inline int check_allocated_memory(void *ptr, size_t size,
100 					 int mem_type, bool tags)
101 {
102 	if (ptr == NULL) {
103 		ksft_print_msg("FAIL: memory allocation\n");
104 		return KSFT_FAIL;
105 	}
106 
107 	if (tags && !MT_FETCH_TAG((uintptr_t)ptr)) {
108 		ksft_print_msg("FAIL: tag not found at addr(%p)\n", ptr);
109 		mte_free_memory((void *)ptr, size, mem_type, false);
110 		return KSFT_FAIL;
111 	}
112 
113 	return KSFT_PASS;
114 }
115 
116 static inline int check_allocated_memory_range(void *ptr, size_t size, int mem_type,
117 					       size_t range_before, size_t range_after)
118 {
119 	if (ptr == NULL) {
120 		ksft_print_msg("FAIL: memory allocation\n");
121 		return KSFT_FAIL;
122 	}
123 
124 	if (!MT_FETCH_TAG((uintptr_t)ptr)) {
125 		ksft_print_msg("FAIL: tag not found at addr(%p)\n", ptr);
126 		mte_free_memory_tag_range((void *)ptr, size, mem_type, range_before,
127 					  range_after);
128 		return KSFT_FAIL;
129 	}
130 	return KSFT_PASS;
131 }
132 
133 #endif /* _MTE_COMMON_UTIL_H */
134