Line data Source code
1 0 : /* 2 : * Copyright (c) 2017 Linaro Limited 3 : * Copyright (c) 2018-2020 Intel Corporation 4 : * 5 : * SPDX-License-Identifier: Apache-2.0 6 : */ 7 : 8 : #ifndef ZEPHYR_INCLUDE_APP_MEMORY_MEM_DOMAIN_H_ 9 : #define ZEPHYR_INCLUDE_APP_MEMORY_MEM_DOMAIN_H_ 10 : 11 : #include <stdint.h> 12 : #include <stddef.h> 13 : #include <zephyr/sys/dlist.h> 14 : #include <zephyr/toolchain.h> 15 : #include <zephyr/kernel/thread.h> 16 : 17 : #ifdef __cplusplus 18 : extern "C" { 19 : #endif 20 : 21 : /** 22 : * @defgroup mem_domain_apis Memory domain APIs 23 : * @ingroup kernel_apis 24 : * @{ 25 : */ 26 : 27 : #ifdef CONFIG_USERSPACE 28 : /** 29 : * @def K_MEM_PARTITION_DEFINE 30 : * 31 : * @brief Statically declare a memory partition 32 : */ 33 : #ifdef _ARCH_MEM_PARTITION_ALIGN_CHECK 34 : #define K_MEM_PARTITION_DEFINE(name, start, size, attr) \ 35 : _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size); \ 36 : struct k_mem_partition name =\ 37 : { (uintptr_t)start, size, attr} 38 : #else 39 1 : #define K_MEM_PARTITION_DEFINE(name, start, size, attr) \ 40 : struct k_mem_partition name =\ 41 : { (uintptr_t)start, size, attr} 42 : #endif /* _ARCH_MEM_PARTITION_ALIGN_CHECK */ 43 : 44 : /** 45 : * @brief Memory Partition 46 : * 47 : * A memory partition is a region of memory in the linear address space 48 : * with a specific access policy. 49 : * 50 : * The alignment of the starting address, and the alignment of the size 51 : * value may have varying requirements based on the capabilities of the 52 : * underlying memory management hardware; arbitrary values are unlikely 53 : * to work. 54 : */ 55 1 : struct k_mem_partition { 56 : /** start address of memory partition */ 57 1 : uintptr_t start; 58 : /** size of memory partition */ 59 1 : size_t size; 60 : /** attribute of memory partition */ 61 1 : k_mem_partition_attr_t attr; 62 : }; 63 : 64 : /** 65 : * @brief Memory Domain 66 : * 67 : * A memory domain is a collection of memory partitions, used to represent 68 : * a user thread's access policy for the linear address space. A thread 69 : * may be a member of only one memory domain, but any memory domain may 70 : * have multiple threads that are members. 71 : * 72 : * Supervisor threads may also be a member of a memory domain; this has 73 : * no implications on their memory access but can be useful as any child 74 : * threads inherit the memory domain membership of the parent. 75 : * 76 : * A user thread belonging to a memory domain with no active partitions 77 : * will have guaranteed access to its own stack buffer, program text, 78 : * and read-only data. 79 : */ 80 1 : struct k_mem_domain { 81 : #ifdef CONFIG_ARCH_MEM_DOMAIN_DATA 82 : struct arch_mem_domain arch; 83 : #endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */ 84 : /** partitions in the domain */ 85 1 : struct k_mem_partition partitions[CONFIG_MAX_DOMAIN_PARTITIONS]; 86 : /** Doubly linked list of member threads */ 87 1 : sys_dlist_t mem_domain_q; 88 : /** number of active partitions in the domain */ 89 1 : uint8_t num_partitions; 90 : }; 91 : 92 : /** 93 : * Default memory domain 94 : * 95 : * All threads are a member of some memory domain, even if running in 96 : * supervisor mode. Threads belong to this default memory domain if they 97 : * haven't been added to or inherited membership from some other domain. 98 : * 99 : * This memory domain has the z_libc_partition partition for the C library 100 : * added to it if exists. 101 : */ 102 1 : extern struct k_mem_domain k_mem_domain_default; 103 : #else 104 : /* To support use of IS_ENABLED for the APIs below */ 105 : struct k_mem_domain; 106 : struct k_mem_partition; 107 : #endif /* CONFIG_USERSPACE */ 108 : 109 : /** 110 : * @brief Initialize a memory domain. 111 : * 112 : * Initialize a memory domain with given name and memory partitions. 113 : * 114 : * See documentation for k_mem_domain_add_partition() for details about 115 : * partition constraints. 116 : * 117 : * Do not call k_mem_domain_init() on the same memory domain more than once, 118 : * doing so is undefined behavior. 119 : * 120 : * @param domain The memory domain to be initialized. 121 : * @param num_parts The number of array items of "parts" parameter. 122 : * @param parts An array of pointers to the memory partitions. Can be NULL 123 : * if num_parts is zero. 124 : * 125 : * @retval 0 if successful 126 : * @retval -EINVAL if invalid parameters supplied 127 : * @retval -ENOMEM if insufficient memory 128 : */ 129 1 : int k_mem_domain_init(struct k_mem_domain *domain, uint8_t num_parts, 130 : struct k_mem_partition *parts[]); 131 : 132 : /** 133 : * @brief Add a memory partition into a memory domain. 134 : * 135 : * Add a memory partition into a memory domain. Partitions must conform to 136 : * the following constraints: 137 : * 138 : * - Partitions in the same memory domain may not overlap each other. 139 : * - Partitions must not be defined which expose private kernel 140 : * data structures or kernel objects. 141 : * - The starting address alignment, and the partition size must conform to 142 : * the constraints of the underlying memory management hardware, which 143 : * varies per architecture. 144 : * - Memory domain partitions are only intended to control access to memory 145 : * from user mode threads. 146 : * - If CONFIG_EXECUTE_XOR_WRITE is enabled, the partition must not allow 147 : * both writes and execution. 148 : * 149 : * Violating these constraints may lead to CPU exceptions or undefined 150 : * behavior. 151 : * 152 : * @param domain The memory domain to be added a memory partition. 153 : * @param part The memory partition to be added 154 : * 155 : * @retval 0 if successful 156 : * @retval -EINVAL if invalid parameters supplied 157 : * @retval -ENOSPC if no free partition slots available 158 : */ 159 1 : int k_mem_domain_add_partition(struct k_mem_domain *domain, 160 : struct k_mem_partition *part); 161 : 162 : /** 163 : * @brief Remove a memory partition from a memory domain. 164 : * 165 : * Remove a memory partition from a memory domain. 166 : * 167 : * @param domain The memory domain to be removed a memory partition. 168 : * @param part The memory partition to be removed 169 : * 170 : * @retval 0 if successful 171 : * @retval -EINVAL if invalid parameters supplied 172 : * @retval -ENOENT if no matching partition found 173 : */ 174 1 : int k_mem_domain_remove_partition(struct k_mem_domain *domain, 175 : struct k_mem_partition *part); 176 : 177 : /** 178 : * @brief Add a thread into a memory domain. 179 : * 180 : * Add a thread into a memory domain. It will be removed from whatever 181 : * memory domain it previously belonged to. 182 : * 183 : * @param domain The memory domain that the thread is going to be added into. 184 : * @param thread ID of thread going to be added into the memory domain. 185 : * 186 : * @return 0 if successful, fails otherwise. 187 : */ 188 1 : int k_mem_domain_add_thread(struct k_mem_domain *domain, 189 : k_tid_t thread); 190 : 191 : #ifdef __cplusplus 192 : } 193 : #endif 194 : 195 : /** @} */ 196 : #endif /* ZEPHYR_INCLUDE_APP_MEMORY_MEM_DOMAIN_H_ */