This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new edf44c881 mtetest: add thread to control mte test separately
edf44c881 is described below

commit edf44c881b6a390f8c2bcd62aac8adb176429558
Author: wangmingrong1 <[email protected]>
AuthorDate: Tue Jan 7 11:52:09 2025 +0800

    mtetest: add thread to control mte test separately
    
    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]>
---
 testing/mtetest/Kconfig   |   8 +++
 testing/mtetest/Makefile  |   2 +-
 testing/mtetest/mtetest.c | 122 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/testing/mtetest/Kconfig b/testing/mtetest/Kconfig
index e4574d581..d00f5ac4f 100644
--- a/testing/mtetest/Kconfig
+++ b/testing/mtetest/Kconfig
@@ -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
diff --git a/testing/mtetest/Makefile b/testing/mtetest/Makefile
index 9d9a3239f..73599309f 100644
--- a/testing/mtetest/Makefile
+++ b/testing/mtetest/Makefile
@@ -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
diff --git a/testing/mtetest/mtetest.c b/testing/mtetest/mtetest.c
index 351c38b22..ac2f0bf1a 100644
--- a/testing/mtetest/mtetest.c
+++ b/testing/mtetest/mtetest.c
@@ -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
  ****************************************************************************/
@@ -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
@@ -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 }
 };
 
@@ -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)
@@ -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;
@@ -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
  *
@@ -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];

Reply via email to