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