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