130 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/* Copyright (C) 2020 ARM Limited */3 4#ifndef _MTE_COMMON_UTIL_H5#define _MTE_COMMON_UTIL_H6 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 16enum mte_mem_type {17 USE_MALLOC,18 USE_MMAP,19 USE_MPROTECT,20};21 22enum mte_mode {23 MTE_NONE_ERR,24 MTE_SYNC_ERR,25 MTE_ASYNC_ERR,26};27 28struct 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 39extern struct mte_fault_cxt cur_mte_cxt;40 41/* MTE utility functions */42void mte_default_handler(int signum, siginfo_t *si, void *uc);43void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *));44void mte_wait_after_trig(void);45void *mte_allocate_memory(size_t size, int mem_type, int mapping, bool tags);46void *mte_allocate_memory_tag_range(size_t size, int mem_type, int mapping,47 size_t range_before, size_t range_after);48void *mte_allocate_file_memory(size_t size, int mem_type, int mapping,49 bool tags, int fd);50void *mte_allocate_file_memory_tag_range(size_t size, int mem_type, int mapping,51 size_t range_before, size_t range_after, int fd);52void mte_free_memory(void *ptr, size_t size, int mem_type, bool tags);53void mte_free_memory_tag_range(void *ptr, size_t size, int mem_type,54 size_t range_before, size_t range_after);55void *mte_insert_tags(void *ptr, size_t size);56void mte_clear_tags(void *ptr, size_t size);57int mte_default_setup(void);58void mte_restore_setup(void);59int mte_switch_mode(int mte_option, unsigned long incl_mask);60void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range);61 62/* Common utility functions */63int create_temp_file(void);64 65/* Assembly MTE utility functions */66void *mte_insert_random_tag(void *ptr);67void *mte_insert_new_tag(void *ptr);68void *mte_get_tag_address(void *ptr);69void mte_set_tag_address_range(void *ptr, int range);70void mte_clear_tag_address_range(void *ptr, int range);71void mte_disable_pstate_tco(void);72void mte_enable_pstate_tco(void);73unsigned int mte_get_pstate_tco(void);74 75/* Test framework static inline functions/macros */76static inline void evaluate_test(int err, const char *msg)77{78 switch (err) {79 case KSFT_PASS:80 ksft_test_result_pass(msg);81 break;82 case KSFT_FAIL:83 ksft_test_result_fail(msg);84 break;85 case KSFT_SKIP:86 ksft_test_result_skip(msg);87 break;88 default:89 ksft_test_result_error("Unknown return code %d from %s",90 err, msg);91 break;92 }93}94 95static inline int check_allocated_memory(void *ptr, size_t size,96 int mem_type, bool tags)97{98 if (ptr == NULL) {99 ksft_print_msg("FAIL: memory allocation\n");100 return KSFT_FAIL;101 }102 103 if (tags && !MT_FETCH_TAG((uintptr_t)ptr)) {104 ksft_print_msg("FAIL: tag not found at addr(%p)\n", ptr);105 mte_free_memory((void *)ptr, size, mem_type, false);106 return KSFT_FAIL;107 }108 109 return KSFT_PASS;110}111 112static inline int check_allocated_memory_range(void *ptr, size_t size, int mem_type,113 size_t range_before, size_t range_after)114{115 if (ptr == NULL) {116 ksft_print_msg("FAIL: memory allocation\n");117 return KSFT_FAIL;118 }119 120 if (!MT_FETCH_TAG((uintptr_t)ptr)) {121 ksft_print_msg("FAIL: tag not found at addr(%p)\n", ptr);122 mte_free_memory_tag_range((void *)ptr, size, mem_type, range_before,123 range_after);124 return KSFT_FAIL;125 }126 return KSFT_PASS;127}128 129#endif /* _MTE_COMMON_UTIL_H */130