Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
mem_domain.c File Reference
#include "mem_protect.h"
#include <kernel_internal.h>

Macros

#define PARTS_USED   2
 
#define NUM_RW_PARTS   (CONFIG_MAX_DOMAIN_PARTITIONS - PARTS_USED)
 
#define PRIO   K_PRIO_PREEMPT(1)
 Show that moving a thread from one domain to another works. More...
 

Functions

static K_THREAD_STACK_DEFINE (child_stack, 512+CONFIG_TEST_EXTRA_STACKSIZE)
 
 K_MEM_PARTITION_DEFINE (ro_part, ro_buf, sizeof(ro_buf), K_MEM_PARTITION_P_RO_U_RO)
 
 K_MEM_PARTITION_DEFINE (overlap_part, ro_buf, sizeof(ro_buf), K_MEM_PARTITION_P_RW_U_RW)
 
static void zzz_entry (void *p1, void *p2, void *p3)
 
static K_THREAD_DEFINE (zzz_thread, 256+CONFIG_TEST_EXTRA_STACKSIZE, zzz_entry, NULL, NULL, NULL, 0, 0, 0)
 
void test_mem_domain_setup (void)
 
static void spawn_child_thread (k_thread_entry_t entry, struct k_mem_domain *domain, bool should_fault)
 
static void rw_part_access (void *p1, void *p2, void *p3)
 
static void ro_part_access (void *p1, void *p2, void *p3)
 
static void ro_write_entry (void *p1, void *p2, void *p3)
 
void test_mem_domain_valid_access (void)
 Check if the mem_domain is configured and accessible for userspace. More...
 
void test_mem_domain_invalid_access (void)
 Show that a user thread can't touch partitions not in its domain. More...
 
void test_mem_domain_no_writes_to_ro (void)
 Show that a read-only partition can't be written to. More...
 
void test_mem_domain_remove_add_partition (void)
 Show that adding/removing partitions works. More...
 
 K_MEM_PARTITION_DEFINE (no_access_part, no_access_buf, sizeof(no_access_buf), K_MEM_PARTITION_P_RW_U_RW)
 
static void mem_domain_init_entry (void *p1, void *p2, void *p3)
 
static void mem_domain_add_partition_entry (void *p1, void *p2, void *p3)
 
static void mem_domain_remove_partition_entry (void *p1, void *p2, void *p3)
 
static void mem_domain_add_thread_entry (void *p1, void *p2, void *p3)
 
void test_mem_domain_api_supervisor_only (void)
 Test access memory domain APIs allowed to supervisor threads only. More...
 
void test_mem_domain_boot_threads (void)
 Show that boot threads belong to the default memory domain. More...
 
static K_SEM_DEFINE (spin_sem, 0, 1)
 
static void spin_entry (void *p1, void *p2, void *p3)
 
void test_mem_domain_migration (void)
 
void test_mem_part_overlap (void)
 Test system assert when new partition overlaps the existing partition. More...
 
void post_fatal_error_handler (unsigned int reason, const z_arch_esf_t *pEsf)
 
 K_MEM_PARTITION_DEFINE (exceed_part, exceed_buf, sizeof(exceed_buf), K_MEM_PARTITION_P_RW_U_RW)
 
void test_mem_part_assert_add_overmax (void)
 Test system assert when adding memory partitions more than possible. More...
 
void test_mem_domain_remove_part_fail (void)
 
void test_mem_domain_init_fail (void)
 Test error case of initializing memory domain fail. More...
 

Variables

static struct k_thread child_thread
 
static struct k_mem_domain test_domain
 
ZTEST_BMEM int num_rw_parts
 
static volatile uint8_t rw_bufs [(CONFIG_MAX_DOMAIN_PARTITIONS - 2)][MEM_REGION_ALLOC]
 
static struct k_mem_partition rw_parts [(CONFIG_MAX_DOMAIN_PARTITIONS - 2)]
 
static volatile uint8_t ro_buf [MEM_REGION_ALLOC]
 
static struct k_mem_domain no_access_domain
 
static volatile uint8_t no_access_buf [MEM_REGION_ALLOC]
 
static ZTEST_BMEM volatile bool spin_done
 
static ZTEST_BMEM bool need_recover_spinlock
 
static struct k_mem_domain test_domain_fail
 
static volatile uint8_t exceed_buf [MEM_REGION_ALLOC]
 

Macro Definition Documentation

◆ NUM_RW_PARTS

#define NUM_RW_PARTS   (CONFIG_MAX_DOMAIN_PARTITIONS - PARTS_USED)

◆ PARTS_USED

#define PARTS_USED   2

◆ PRIO

#define PRIO   K_PRIO_PREEMPT(1)

Show that moving a thread from one domain to another works.

Start a thread and have it spin. Then while it is spinning, show that adding it to another memory domain doesn't cause any faults.

This test is of particular importance on SMP systems where the child thread is spinning on a different CPU concurrently with the migration operation.

See also
k_mem_domain_add_thread()

Function Documentation

◆ K_MEM_PARTITION_DEFINE() [1/4]

K_MEM_PARTITION_DEFINE ( exceed_part  ,
exceed_buf  ,
sizeof(exceed_buf ,
K_MEM_PARTITION_P_RW_U_RW   
)

◆ K_MEM_PARTITION_DEFINE() [2/4]

K_MEM_PARTITION_DEFINE ( no_access_part  ,
no_access_buf  ,
sizeof(no_access_buf ,
K_MEM_PARTITION_P_RW_U_RW   
)

◆ K_MEM_PARTITION_DEFINE() [3/4]

K_MEM_PARTITION_DEFINE ( overlap_part  ,
ro_buf  ,
sizeof(ro_buf ,
K_MEM_PARTITION_P_RW_U_RW   
)

◆ K_MEM_PARTITION_DEFINE() [4/4]

K_MEM_PARTITION_DEFINE ( ro_part  ,
ro_buf  ,
sizeof(ro_buf ,
K_MEM_PARTITION_P_RO_U_RO   
)

◆ K_SEM_DEFINE()

static K_SEM_DEFINE ( spin_sem  ,
,
 
)
static

◆ K_THREAD_DEFINE()

static K_THREAD_DEFINE ( zzz_thread  ,
256+  CONFIG_TEST_EXTRA_STACKSIZE,
zzz_entry  ,
NULL  ,
NULL  ,
NULL  ,
,
,
 
)
static

◆ K_THREAD_STACK_DEFINE()

static K_THREAD_STACK_DEFINE ( child_stack  ,
512+  CONFIG_TEST_EXTRA_STACKSIZE 
)
static

◆ mem_domain_add_partition_entry()

static void mem_domain_add_partition_entry ( void p1,
void p2,
void p3 
)
static

◆ mem_domain_add_thread_entry()

static void mem_domain_add_thread_entry ( void p1,
void p2,
void p3 
)
static

◆ mem_domain_init_entry()

static void mem_domain_init_entry ( void p1,
void p2,
void p3 
)
static

◆ mem_domain_remove_partition_entry()

static void mem_domain_remove_partition_entry ( void p1,
void p2,
void p3 
)
static

◆ post_fatal_error_handler()

void post_fatal_error_handler ( unsigned int  reason,
const z_arch_esf_t *  pEsf 
)

◆ ro_part_access()

static void ro_part_access ( void p1,
void p2,
void p3 
)
static

◆ ro_write_entry()

static void ro_write_entry ( void p1,
void p2,
void p3 
)
static

◆ rw_part_access()

static void rw_part_access ( void p1,
void p2,
void p3 
)
static

◆ spawn_child_thread()

static void spawn_child_thread ( k_thread_entry_t  entry,
struct k_mem_domain domain,
bool  should_fault 
)
static

◆ spin_entry()

static void spin_entry ( void p1,
void p2,
void p3 
)
static

◆ test_mem_domain_api_supervisor_only()

void test_mem_domain_api_supervisor_only ( void  )

Test access memory domain APIs allowed to supervisor threads only.

Show that invoking any of the memory domain APIs from user mode leads to a fault.

See also
k_mem_domain_init(), k_mem_domain_add_partition(), k_mem_domain_remove_partition(), k_mem_domain_add_thread()

◆ test_mem_domain_boot_threads()

void test_mem_domain_boot_threads ( void  )

Show that boot threads belong to the default memory domain.

Static threads and the main thread are supposed to start as members of the default memory domain. Prove this is the case by examining the memory domain membership of z_main_thread and a static thread.

◆ test_mem_domain_init_fail()

void test_mem_domain_init_fail ( void  )

Test error case of initializing memory domain fail.

Try to initialize a domain with invalid partition, then see if an expected fatal error happens. And while the fatal error happened, the memory domain spinlock is held, we need to release them to make other follow test case.

◆ test_mem_domain_invalid_access()

void test_mem_domain_invalid_access ( void  )

Show that a user thread can't touch partitions not in its domain.

◆ test_mem_domain_migration()

void test_mem_domain_migration ( void  )

TESTPOINT: add to existing domain will do nothing

◆ test_mem_domain_no_writes_to_ro()

void test_mem_domain_no_writes_to_ro ( void  )

Show that a read-only partition can't be written to.

◆ test_mem_domain_remove_add_partition()

void test_mem_domain_remove_add_partition ( void  )

Show that adding/removing partitions works.

Show that removing a partition doesn't affect access to other partitions. Show that removing a partition generates a fault if its data is accessed. Show that adding a partition back restores access from a user thread.

◆ test_mem_domain_remove_part_fail()

void test_mem_domain_remove_part_fail ( void  )

◆ test_mem_domain_setup()

void test_mem_domain_setup ( void  )

◆ test_mem_domain_valid_access()

void test_mem_domain_valid_access ( void  )

Check if the mem_domain is configured and accessible for userspace.

Join a memory domain with a read-write memory partition and a read-only partition within it, and show that the data in the partition is accessible as expected by the permissions provided.

◆ test_mem_part_assert_add_overmax()

void test_mem_part_assert_add_overmax ( void  )

Test system assert when adding memory partitions more than possible.

  • Add memory partitions one by one and more than architecture allows to add.
  • When partitions added more than it is allowed by architecture, test that system assert for that case works correctly.

◆ test_mem_part_overlap()

void test_mem_part_overlap ( void  )

Test system assert when new partition overlaps the existing partition.

Test Objective:

  • Test assertion if the new partition overlaps existing partition in domain

Testing techniques:

  • System testing

Prerequisite Conditions:

  • N/A

Input Specifications:

  • N/A

Test Procedure:

  1. Define testing memory partition overlap_part with the same start ro_buf as has the existing memory partition ro_part
  2. Try to add overlap_part to the memory domain. When adding the new partition to the memory domain the system will assert that new partition overlaps with the existing partition ro_part .

Expected Test Result:

  • Must happen an assertion error indicating that the new partition overlaps the existing one.

Pass/Fail Criteria:

  • Success if the overlap assertion will happen.
  • Failure if the overlap assertion will not happen.

Assumptions and Constraints:

  • N/A
See also
k_mem_domain_add_partition()

◆ zzz_entry()

static void zzz_entry ( void p1,
void p2,
void p3 
)
static

Variable Documentation

◆ child_thread

struct k_thread child_thread
static

◆ exceed_buf

volatile uint8_t exceed_buf[MEM_REGION_ALLOC]
static

◆ need_recover_spinlock

ZTEST_BMEM bool need_recover_spinlock
static

◆ no_access_buf

volatile uint8_t no_access_buf[MEM_REGION_ALLOC]
static

◆ no_access_domain

struct k_mem_domain no_access_domain
static

◆ num_rw_parts

ZTEST_BMEM int num_rw_parts

◆ ro_buf

volatile uint8_t ro_buf[MEM_REGION_ALLOC]
static

◆ rw_bufs

volatile uint8_t rw_bufs[(CONFIG_MAX_DOMAIN_PARTITIONS - 2)][MEM_REGION_ALLOC]
static

◆ rw_parts

struct k_mem_partition rw_parts[(CONFIG_MAX_DOMAIN_PARTITIONS - 2)]
static

◆ spin_done

ZTEST_BMEM volatile bool spin_done
static

◆ test_domain

struct k_mem_domain test_domain
static

◆ test_domain_fail

struct k_mem_domain test_domain_fail
static