1/* 2 * Memory tagging testing code. 3 * 4 * Copyright (c) 2020, Arm Limited. 5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6 */ 7 8#ifndef __TEST_MTE_H 9#define __TEST_MTE_H 10 11#include <stdlib.h> 12 13#if __ARM_FEATURE_MEMORY_TAGGING && WANT_MTE_TEST 14#include <arm_acle.h> 15#include <sys/mman.h> 16#include <sys/prctl.h> 17 18// These depend on a not yet merged kernel ABI. 19#define PR_SET_TAGGED_ADDR_CTRL 55 20#define PR_TAGGED_ADDR_ENABLE (1UL << 0) 21#define PR_MTE_TCF_SHIFT 1 22#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) 23#define PR_MTE_TAG_SHIFT 3 24#define PROT_MTE 0x20 25 26#define MTE_GRANULE_SIZE 16 27 28int 29mte_enabled () 30{ 31 static int enabled = -1; 32 if (enabled == -1) 33 { 34 int res = prctl (PR_SET_TAGGED_ADDR_CTRL, 35 PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC 36 | (0xfffe << PR_MTE_TAG_SHIFT), 37 0, 0, 0); 38 enabled = (res == 0); 39 } 40 return enabled; 41} 42 43static void * 44mte_mmap (size_t size) 45{ 46 if (mte_enabled ()) 47 { 48 return mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_MTE, 49 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 50 } 51 else 52 { 53 return malloc (size); 54 } 55} 56 57void * 58alignup_mte (void *p) 59{ 60 return (void *) (((uintptr_t) p + MTE_GRANULE_SIZE - 1) 61 & ~(MTE_GRANULE_SIZE - 1)); 62} 63 64void * 65aligndown_mte (void *p) 66{ 67 return (void *) ((uintptr_t) p & ~(MTE_GRANULE_SIZE - 1)); 68} 69 70void * 71untag_pointer (void *p) 72{ 73 return (void *) ((unsigned long long) p & (~0ULL >> 8)); 74} 75 76void 77tag_buffer_helper (void *p, int len) 78{ 79 char *ptr = p; 80 char *end = alignup_mte (ptr + len); 81 ptr = aligndown_mte (p); 82 for (; ptr < end; ptr += MTE_GRANULE_SIZE) 83 { 84 __arm_mte_set_tag (ptr); 85 } 86} 87 88void * 89tag_buffer (void *p, int len, int test_mte) 90{ 91 if (test_mte && mte_enabled ()) 92 { 93 p = __arm_mte_increment_tag (p, 1); 94 tag_buffer_helper (p, len); 95 } 96 return p; 97} 98 99void * 100untag_buffer (void *p, int len, int test_mte) 101{ 102 p = untag_pointer (p); 103 if (test_mte && mte_enabled ()) 104 { 105 tag_buffer_helper (p, len); 106 } 107 return p; 108} 109 110#else // __ARM_FEATURE_MEMORY_TAGGING 111int 112mte_enabled () 113{ 114 return 0; 115} 116static void * 117mte_mmap (size_t size) 118{ 119 return malloc (size); 120} 121void * 122tag_buffer (void *p, int len, int test_mte) 123{ 124 (void) len; 125 (void) test_mte; 126 return p; 127} 128void * 129untag_buffer (void *p, int len, int test_mte) 130{ 131 (void) len; 132 (void) test_mte; 133 return p; 134} 135void * 136untag_pointer (void *p) 137{ 138 return p; 139} 140#endif // __ARM_FEATURE_MEMORY_TAGGING 141 142#endif 143