Zephyr Project API 3.7.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
mem_domain.c File Reference
#include "mem_protect.h"
#include <kernel_internal.h>
#include <zephyr/sys/libc-hooks.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.
 

Functions

 K_THREAD_STACK_DEFINE (child_stack,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
 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_STACK_SIZE, 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)
 
 ZTEST (mem_protect_domain, test_mem_domain_valid_access)
 Check if the mem_domain is configured and accessible for userspace.
 
 ZTEST (mem_protect_domain, test_mem_domain_invalid_access)
 Show that a user thread can't touch partitions not in its domain.
 
 ZTEST (mem_protect_domain, test_mem_domain_no_writes_to_ro)
 Show that a read-only partition can't be written to.
 
 ZTEST (mem_protect_domain, test_mem_domain_remove_add_partition)
 Show that adding/removing partitions works.
 
 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)
 
 ZTEST (mem_protect_domain, test_mem_domain_api_supervisor_only)
 Test access memory domain APIs allowed to supervisor threads only.
 
 ZTEST (mem_protect_domain, test_mem_domain_boot_threads)
 Show that boot threads belong to the default memory domain.
 
static K_SEM_DEFINE (spin_sem, 0, 1)
 
static void spin_entry (void *p1, void *p2, void *p3)
 
 ZTEST (mem_protect_domain, test_mem_domain_migration)
 
 ZTEST (mem_protect_domain, test_mem_part_overlap)
 Test system assert when new partition overlaps the existing partition.
 
 K_MEM_PARTITION_DEFINE (exceed_part, exceed_buf, sizeof(exceed_buf), K_MEM_PARTITION_P_RW_U_RW)
 
 ZTEST (mem_protect_domain, test_mem_part_assert_add_overmax)
 Test system assert when adding memory partitions more than possible.
 
 ZTEST (mem_protect_domain, test_mem_domain_remove_part_fail)
 
 ZTEST (mem_protect_domain, test_mem_domain_init_fail)
 Test error case of initializing memory domain fail.
 
 ZTEST (mem_protect_domain, test_mem_part_add_error_null)
 Test error case of adding null memory partition fail.
 
 K_MEM_PARTITION_DEFINE (nonsize_part, nosize_buf, sizeof(nosize_buf), K_MEM_PARTITION_P_RO_U_RO)
 
 ZTEST (mem_protect_domain, test_mem_part_add_error_zerosize)
 Test error case of adding zero sized memory partition fail.
 
 ZTEST (mem_protect_domain, test_mem_part_error_wraparound)
 Test error case of memory partition address wraparound.
 
 ZTEST (mem_protect_domain, test_mem_part_remove_error_zerosize)
 Test error case of removing memory partition fail.
 
void * mem_domain_setup (void)
 
 ZTEST_SUITE (mem_protect_domain, NULL, mem_domain_setup, NULL, NULL, NULL)
 

Variables

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 struct k_mem_domain test_domain_fail
 
static volatile uint8_t exceed_buf [MEM_REGION_ALLOC]
 
static volatile uint8_t nosize_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/5]

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

◆ K_MEM_PARTITION_DEFINE() [2/5]

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/5]

K_MEM_PARTITION_DEFINE ( nonsize_part  ,
nosize_buf  ,
sizeof(nosize_buf ,
K_MEM_PARTITION_P_RO_U_RO   
)

◆ K_MEM_PARTITION_DEFINE() [4/5]

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

◆ K_MEM_PARTITION_DEFINE() [5/5]

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_STACK_SIZE,
zzz_entry  ,
NULL  ,
NULL  ,
NULL  ,
,
,
 
)
static

◆ K_THREAD_STACK_DEFINE()

K_THREAD_STACK_DEFINE ( child_stack  ,
(512+CONFIG_TEST_EXTRA_STACK_SIZE)   
)

◆ 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

◆ mem_domain_setup()

void * mem_domain_setup ( void  )

◆ 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_setup()

void test_mem_domain_setup ( void  )

◆ ZTEST() [1/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_api_supervisor_only   
)

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()

◆ ZTEST() [2/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_boot_threads   
)

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.

◆ ZTEST() [3/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_init_fail   
)

Test error case of initializing memory domain fail.

Try to initialize a domain with invalid partition. k_mem_domain_init() should return non-zero.

◆ ZTEST() [4/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_invalid_access   
)

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

◆ ZTEST() [5/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_migration   
)

TESTPOINT: add to existing domain will do nothing

◆ ZTEST() [6/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_no_writes_to_ro   
)

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

◆ ZTEST() [7/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_remove_add_partition   
)

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.

◆ ZTEST() [8/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_remove_part_fail   
)

◆ ZTEST() [9/15]

ZTEST ( mem_protect_domain  ,
test_mem_domain_valid_access   
)

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.

◆ ZTEST() [10/15]

ZTEST ( mem_protect_domain  ,
test_mem_part_add_error_null   
)

Test error case of adding null memory partition fail.

Try to add a null partition to memory domain. k_mem_domain_add_partition() should return error.

◆ ZTEST() [11/15]

ZTEST ( mem_protect_domain  ,
test_mem_part_add_error_zerosize   
)

Test error case of adding zero sized memory partition fail.

Try to add a zero sized partition to memory domain. k_mem_domain_add_partition() should return error.

◆ ZTEST() [12/15]

ZTEST ( mem_protect_domain  ,
test_mem_part_assert_add_overmax   
)

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 k_mem_domain_add_partition() returns non-zero.

◆ ZTEST() [13/15]

ZTEST ( mem_protect_domain  ,
test_mem_part_error_wraparound   
)

Test error case of memory partition address wraparound.

Try to add a partition whose address is wraparound. k_mem_domain_add_partition() should return error.

◆ ZTEST() [14/15]

ZTEST ( mem_protect_domain  ,
test_mem_part_overlap   
)

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()

◆ ZTEST() [15/15]

ZTEST ( mem_protect_domain  ,
test_mem_part_remove_error_zerosize   
)

Test error case of removing memory partition fail.

Try to remove a partition size mismatched will result in k_mem_domain_remove_partition() returning error.

◆ ZTEST_SUITE()

ZTEST_SUITE ( mem_protect_domain  ,
NULL  ,
mem_domain_setup  ,
NULL  ,
NULL  ,
NULL   
)

◆ zzz_entry()

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

Variable Documentation

◆ child_thread

struct k_thread child_thread

◆ exceed_buf

volatile uint8_t exceed_buf[MEM_REGION_ALLOC]
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

◆ nosize_buf

volatile uint8_t nosize_buf[MEM_REGION_ALLOC]
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