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