Skip to content

Commit

Permalink
mtetest: add thread to control mte test separately
Browse files Browse the repository at this point in the history
After thread A holds the semaphore, it first accesses it safely. After releasing it, thread B closes MTE for unsafe access. After accessing, it switches back to thread A for unsafe access. At this time, an error should be reported.
log:
Process 1 holding lock
Process 2 holding lock
Process 1 holding lock again
default_fatal_handler: (IFSC/DFSC) for Data/Instruction aborts: synchronous tag check fault
arm64_exception_handler: CurrentEL: MODE_EL1
arm64_exception_handler: ESR_ELn: 0x96000011
arm64_exception_handler: FAR_ELn: 0xf00000040441700
arm64_exception_handler: ELR_ELn: 0x402ee5f4
print_ec_cause: DABT (current EL)
print_ec_cause: Data Abort taken without a change in Exception level

Signed-off-by: wangmingrong1 <[email protected]>
  • Loading branch information
W-M-R authored and xiaoxiang781216 committed Jan 7, 2025
1 parent a61fd58 commit edf44c8
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 6 deletions.
8 changes: 8 additions & 0 deletions testing/mtetest/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ config TESTING_MTE
default n
---help---
Enable MTE instruction set test

if TESTING_MTE

config TESTING_MTE_PRIORITY
int "Task priority"
default 101

endif
2 changes: 1 addition & 1 deletion testing/mtetest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ include $(APPDIR)/Make.defs

MAINSRC = mtetest.c
PROGNAME = mtetest
PRIORITY = $(CONFIG_TESTING_KASAN_PRIORITY)
PRIORITY = $(CONFIG_TESTING_MTE_PRIORITY)
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)

include $(APPDIR)/Application.mk
122 changes: 117 additions & 5 deletions testing/mtetest/mtetest.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,42 @@
#include <nuttx/config.h>
#include <nuttx/compiler.h>

#include <sys/wait.h>

#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <spawn.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/* Must be a multiple of sixteen */
#define MTETEST_BUFFER_LEN 512

#define SCTLR_TCF1_BIT (1ul << 40)

/****************************************************************************
* Private Type
****************************************************************************/

struct mte_test_s
{
FAR const char *name;
FAR void (*func)(void);
};

struct args_s
{
char *buffer;
size_t safe_len;
size_t len;
sem_t sem;
};

/****************************************************************************
* Private Function Prototypes
****************************************************************************/
Expand All @@ -55,6 +72,7 @@ static void mtetest2(void);
static void mtetest3(void);
static void mtetest4(void);
static void mtetest5(void);
static void switch_mtetest(void);

/****************************************************************************
* Private Data
Expand All @@ -71,6 +89,7 @@ static const struct mte_test_s g_mtetest[] =
{ "mtetest3", mtetest3 },
{ "mtetest4", mtetest4 },
{ "mtetest5", mtetest5 },
{ "Thread switch MTE test", switch_mtetest },
{ NULL, NULL }
};

Expand All @@ -95,7 +114,7 @@ static const struct mte_test_s g_mtetest[] =
* tagged.
****************************************************************************/

static void __attribute__((noinline)) tagset(void *p, size_t size)
static void tagset(const void *p, size_t size)
{
size_t i;
for (i = 0; i < size; i += 16)
Expand Down Expand Up @@ -123,7 +142,7 @@ static void __attribute__((noinline)) tagset(void *p, size_t size)
* correct memory tagging and access.
****************************************************************************/

static void __attribute__((noinline)) tagcheck(void *p, size_t size)
static void tagcheck(const void *p, size_t size)
{
size_t i;
void *c;
Expand All @@ -135,6 +154,15 @@ static void __attribute__((noinline)) tagcheck(void *p, size_t size)
}
}

/* Disable the mte function */

static void disable_mte(void)
{
uint64_t val = read_sysreg(sctlr_el1);
val &= ~SCTLR_TCF1_BIT;
write_sysreg(val, sctlr_el1);
}

/****************************************************************************
* Name: mtetest1
*
Expand Down Expand Up @@ -316,6 +344,90 @@ static void mtetest5(void)
assert(1 == *(p1 + 16));
}

/* The first entry gets the semaphore for safe access,
* and the next switch back to unsafe access
*/

static void *process1(void *arg)
{
struct args_s *args = (struct args_s *)arg;
int i;

while (1)
{
sem_wait(&args->sem);
printf("Process 1 holding lock\n");

for (i = 0; i < args->safe_len; i++)
{
args->buffer[i]++;
}

sem_post(&args->sem);
sleep(1);
printf("Process 1 holding lock again\n");
for (i = 0; i < args->len; i++)
{
args->buffer[i]++;
}

sem_post(&args->sem);
}

return NULL;
}

/* Disable unsafe access to MTE functions */

static void *process2(void *arg)
{
struct args_s *args = (struct args_s *)arg;
int i;

while (1)
{
sem_wait(&args->sem);

printf("Process 2 holding lock\n");
disable_mte();

for (i = 0; i < args->len; i++)
{
args->buffer[i]++;
}

sem_post(&args->sem);
sleep(1);
}

return NULL;
}

static void switch_mtetest(void)
{
struct args_s args;
pthread_t t1;
pthread_t t2;

sem_init(&args.sem, 1, 1);

asm("irg %0,%1,%2" : "=r"(args.buffer) : "r"(g_buffer), "r"(1l));
assert(args.buffer != g_buffer);

args.safe_len = sizeof(g_buffer) / 2;
args.len = sizeof(g_buffer);

tagset(args.buffer, args.safe_len);

pthread_create(&t1, NULL, process1, &args);
pthread_create(&t2, NULL, process2, &args);

pthread_join(t1, NULL);
pthread_join(t2, NULL);

sem_destroy(&args.sem);
}

static void spawn_test_process(const struct mte_test_s *test)
{
char *args[3];
Expand Down

0 comments on commit edf44c8

Please sign in to comment.