You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
2.4 KiB
143 lines
2.4 KiB
/*
|
|
* Memory tagging testing code.
|
|
*
|
|
* Copyright (c) 2020, Arm Limited.
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#ifndef __TEST_MTE_H
|
|
#define __TEST_MTE_H
|
|
|
|
#include <stdlib.h>
|
|
|
|
#if __ARM_FEATURE_MEMORY_TAGGING && WANT_MTE_TEST
|
|
#include <arm_acle.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/prctl.h>
|
|
|
|
// These depend on a not yet merged kernel ABI.
|
|
#define PR_SET_TAGGED_ADDR_CTRL 55
|
|
#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
|
|
#define PR_MTE_TCF_SHIFT 1
|
|
#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
|
|
#define PR_MTE_TAG_SHIFT 3
|
|
#define PROT_MTE 0x20
|
|
|
|
#define MTE_GRANULE_SIZE 16
|
|
|
|
int
|
|
mte_enabled ()
|
|
{
|
|
static int enabled = -1;
|
|
if (enabled == -1)
|
|
{
|
|
int res = prctl (PR_SET_TAGGED_ADDR_CTRL,
|
|
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC
|
|
| (0xfffe << PR_MTE_TAG_SHIFT),
|
|
0, 0, 0);
|
|
enabled = (res == 0);
|
|
}
|
|
return enabled;
|
|
}
|
|
|
|
static void *
|
|
mte_mmap (size_t size)
|
|
{
|
|
if (mte_enabled ())
|
|
{
|
|
return mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_MTE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
}
|
|
else
|
|
{
|
|
return malloc (size);
|
|
}
|
|
}
|
|
|
|
void *
|
|
alignup_mte (void *p)
|
|
{
|
|
return (void *) (((uintptr_t) p + MTE_GRANULE_SIZE - 1)
|
|
& ~(MTE_GRANULE_SIZE - 1));
|
|
}
|
|
|
|
void *
|
|
aligndown_mte (void *p)
|
|
{
|
|
return (void *) ((uintptr_t) p & ~(MTE_GRANULE_SIZE - 1));
|
|
}
|
|
|
|
void *
|
|
untag_pointer (void *p)
|
|
{
|
|
return (void *) ((unsigned long long) p & (~0ULL >> 8));
|
|
}
|
|
|
|
void
|
|
tag_buffer_helper (void *p, int len)
|
|
{
|
|
char *ptr = p;
|
|
char *end = alignup_mte (ptr + len);
|
|
ptr = aligndown_mte (p);
|
|
for (; ptr < end; ptr += MTE_GRANULE_SIZE)
|
|
{
|
|
__arm_mte_set_tag (ptr);
|
|
}
|
|
}
|
|
|
|
void *
|
|
tag_buffer (void *p, int len, int test_mte)
|
|
{
|
|
if (test_mte && mte_enabled ())
|
|
{
|
|
p = __arm_mte_increment_tag (p, 1);
|
|
tag_buffer_helper (p, len);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
void *
|
|
untag_buffer (void *p, int len, int test_mte)
|
|
{
|
|
p = untag_pointer (p);
|
|
if (test_mte && mte_enabled ())
|
|
{
|
|
tag_buffer_helper (p, len);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
#else // __ARM_FEATURE_MEMORY_TAGGING
|
|
int
|
|
mte_enabled ()
|
|
{
|
|
return 0;
|
|
}
|
|
static void *
|
|
mte_mmap (size_t size)
|
|
{
|
|
return malloc (size);
|
|
}
|
|
void *
|
|
tag_buffer (void *p, int len, int test_mte)
|
|
{
|
|
(void) len;
|
|
(void) test_mte;
|
|
return p;
|
|
}
|
|
void *
|
|
untag_buffer (void *p, int len, int test_mte)
|
|
{
|
|
(void) len;
|
|
(void) test_mte;
|
|
return p;
|
|
}
|
|
void *
|
|
untag_pointer (void *p)
|
|
{
|
|
return p;
|
|
}
|
|
#endif // __ARM_FEATURE_MEMORY_TAGGING
|
|
|
|
#endif
|