xref: /freebsd-src/contrib/arm-optimized-routines/string/test/mte.h (revision 072a4ba82a01476eaee33781ccd241033eefcf0b)
131914882SAlex Richardson /*
231914882SAlex Richardson  * Memory tagging testing code.
331914882SAlex Richardson  *
431914882SAlex Richardson  * Copyright (c) 2020, Arm Limited.
5*072a4ba8SAndrew Turner  * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
631914882SAlex Richardson  */
731914882SAlex Richardson 
831914882SAlex Richardson #ifndef __TEST_MTE_H
931914882SAlex Richardson #define __TEST_MTE_H
1031914882SAlex Richardson 
1131914882SAlex Richardson #include <stdlib.h>
1231914882SAlex Richardson 
1331914882SAlex Richardson #if __ARM_FEATURE_MEMORY_TAGGING && WANT_MTE_TEST
1431914882SAlex Richardson #include <arm_acle.h>
1531914882SAlex Richardson #include <sys/mman.h>
1631914882SAlex Richardson #include <sys/prctl.h>
1731914882SAlex Richardson 
1831914882SAlex Richardson // These depend on a not yet merged kernel ABI.
1931914882SAlex Richardson #define PR_SET_TAGGED_ADDR_CTRL 55
2031914882SAlex Richardson #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
2131914882SAlex Richardson #define PR_MTE_TCF_SHIFT 1
2231914882SAlex Richardson #define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
2331914882SAlex Richardson #define PR_MTE_TAG_SHIFT 3
2431914882SAlex Richardson #define PROT_MTE 0x20
2531914882SAlex Richardson 
2631914882SAlex Richardson #define MTE_GRANULE_SIZE 16
2731914882SAlex Richardson 
2831914882SAlex Richardson int
mte_enabled()2931914882SAlex Richardson mte_enabled ()
3031914882SAlex Richardson {
3131914882SAlex Richardson   static int enabled = -1;
3231914882SAlex Richardson   if (enabled == -1)
3331914882SAlex Richardson     {
3431914882SAlex Richardson       int res = prctl (PR_SET_TAGGED_ADDR_CTRL,
3531914882SAlex Richardson 		       PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC
3631914882SAlex Richardson 			 | (0xfffe << PR_MTE_TAG_SHIFT),
3731914882SAlex Richardson 		       0, 0, 0);
3831914882SAlex Richardson       enabled = (res == 0);
3931914882SAlex Richardson     }
4031914882SAlex Richardson   return enabled;
4131914882SAlex Richardson }
4231914882SAlex Richardson 
4331914882SAlex Richardson static void *
mte_mmap(size_t size)4431914882SAlex Richardson mte_mmap (size_t size)
4531914882SAlex Richardson {
4631914882SAlex Richardson   if (mte_enabled ())
4731914882SAlex Richardson     {
4831914882SAlex Richardson       return mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_MTE,
4931914882SAlex Richardson 		   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
5031914882SAlex Richardson     }
5131914882SAlex Richardson   else
5231914882SAlex Richardson     {
5331914882SAlex Richardson       return malloc (size);
5431914882SAlex Richardson     }
5531914882SAlex Richardson }
5631914882SAlex Richardson 
5731914882SAlex Richardson void *
alignup_mte(void * p)5831914882SAlex Richardson alignup_mte (void *p)
5931914882SAlex Richardson {
6031914882SAlex Richardson   return (void *) (((uintptr_t) p + MTE_GRANULE_SIZE - 1)
6131914882SAlex Richardson 		   & ~(MTE_GRANULE_SIZE - 1));
6231914882SAlex Richardson }
6331914882SAlex Richardson 
6431914882SAlex Richardson void *
aligndown_mte(void * p)6531914882SAlex Richardson aligndown_mte (void *p)
6631914882SAlex Richardson {
6731914882SAlex Richardson   return (void *) ((uintptr_t) p & ~(MTE_GRANULE_SIZE - 1));
6831914882SAlex Richardson }
6931914882SAlex Richardson 
7031914882SAlex Richardson void *
untag_pointer(void * p)7131914882SAlex Richardson untag_pointer (void *p)
7231914882SAlex Richardson {
7331914882SAlex Richardson   return (void *) ((unsigned long long) p & (~0ULL >> 8));
7431914882SAlex Richardson }
7531914882SAlex Richardson 
7631914882SAlex Richardson void
tag_buffer_helper(void * p,int len)7731914882SAlex Richardson tag_buffer_helper (void *p, int len)
7831914882SAlex Richardson {
7931914882SAlex Richardson   char *ptr = p;
8031914882SAlex Richardson   char *end = alignup_mte (ptr + len);
8131914882SAlex Richardson   ptr = aligndown_mte (p);
8231914882SAlex Richardson   for (; ptr < end; ptr += MTE_GRANULE_SIZE)
8331914882SAlex Richardson     {
8431914882SAlex Richardson       __arm_mte_set_tag (ptr);
8531914882SAlex Richardson     }
8631914882SAlex Richardson }
8731914882SAlex Richardson 
8831914882SAlex Richardson void *
tag_buffer(void * p,int len,int test_mte)8931914882SAlex Richardson tag_buffer (void *p, int len, int test_mte)
9031914882SAlex Richardson {
9131914882SAlex Richardson   if (test_mte && mte_enabled ())
9231914882SAlex Richardson     {
9331914882SAlex Richardson       p = __arm_mte_increment_tag (p, 1);
9431914882SAlex Richardson       tag_buffer_helper (p, len);
9531914882SAlex Richardson     }
9631914882SAlex Richardson   return p;
9731914882SAlex Richardson }
9831914882SAlex Richardson 
9931914882SAlex Richardson void *
untag_buffer(void * p,int len,int test_mte)10031914882SAlex Richardson untag_buffer (void *p, int len, int test_mte)
10131914882SAlex Richardson {
10231914882SAlex Richardson   p = untag_pointer (p);
10331914882SAlex Richardson   if (test_mte && mte_enabled ())
10431914882SAlex Richardson     {
10531914882SAlex Richardson       tag_buffer_helper (p, len);
10631914882SAlex Richardson     }
10731914882SAlex Richardson   return p;
10831914882SAlex Richardson }
10931914882SAlex Richardson 
11031914882SAlex Richardson #else  // __ARM_FEATURE_MEMORY_TAGGING
11131914882SAlex Richardson int
mte_enabled()11231914882SAlex Richardson mte_enabled ()
11331914882SAlex Richardson {
11431914882SAlex Richardson   return 0;
11531914882SAlex Richardson }
11631914882SAlex Richardson static void *
mte_mmap(size_t size)11731914882SAlex Richardson mte_mmap (size_t size)
11831914882SAlex Richardson {
11931914882SAlex Richardson   return malloc (size);
12031914882SAlex Richardson }
12131914882SAlex Richardson void *
tag_buffer(void * p,int len,int test_mte)12231914882SAlex Richardson tag_buffer (void *p, int len, int test_mte)
12331914882SAlex Richardson {
12431914882SAlex Richardson   (void) len;
12531914882SAlex Richardson   (void) test_mte;
12631914882SAlex Richardson   return p;
12731914882SAlex Richardson }
12831914882SAlex Richardson void *
untag_buffer(void * p,int len,int test_mte)12931914882SAlex Richardson untag_buffer (void *p, int len, int test_mte)
13031914882SAlex Richardson {
13131914882SAlex Richardson   (void) len;
13231914882SAlex Richardson   (void) test_mte;
13331914882SAlex Richardson   return p;
13431914882SAlex Richardson }
13531914882SAlex Richardson void *
untag_pointer(void * p)13631914882SAlex Richardson untag_pointer (void *p)
13731914882SAlex Richardson {
13831914882SAlex Richardson   return p;
13931914882SAlex Richardson }
14031914882SAlex Richardson #endif // __ARM_FEATURE_MEMORY_TAGGING
14131914882SAlex Richardson 
14231914882SAlex Richardson #endif
143