Line data Source code
1 0 : /*
2 : * Copyright (c) 2020 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 : #ifndef ZEPHYR_INCLUDE_SYS_KOBJECT_H
7 : #define ZEPHYR_INCLUDE_SYS_KOBJECT_H
8 :
9 : #include <stdint.h>
10 : #include <stddef.h>
11 :
12 : #include <zephyr/sys/iterable_sections.h>
13 : #include <zephyr/sys/internal/kobject_internal.h>
14 :
15 : #ifdef __cplusplus
16 : extern "C" {
17 : #endif
18 :
19 : struct k_thread;
20 : struct k_mutex;
21 : struct z_futex_data;
22 :
23 : /**
24 : * @brief Kernel Object Types
25 : *
26 : * This enumeration needs to be kept in sync with the lists of kernel objects
27 : * and subsystems in scripts/build/gen_kobject_list.py, as well as the otype_to_str()
28 : * function in kernel/userspace.c
29 : */
30 0 : enum k_objects {
31 : K_OBJ_ANY,
32 :
33 : /** @cond
34 : * Doxygen should ignore this build-time generated include file
35 : * when generating API documentation. Enumeration values are
36 : * generated during build by gen_kobject_list.py. It includes
37 : * basic kernel objects (e.g. pipes and mutexes) and driver types.
38 : */
39 : #include <zephyr/kobj-types-enum.h>
40 : /** @endcond
41 : */
42 :
43 : K_OBJ_LAST
44 : };
45 : /**
46 : * @defgroup usermode_apis User Mode APIs
47 : * @ingroup kernel_apis
48 : * @{
49 : */
50 :
51 : #ifdef CONFIG_USERSPACE
52 :
53 : /**
54 : * @brief Grant a static thread access to a list of kernel objects
55 : *
56 : * For threads declared with K_THREAD_DEFINE(), grant the thread access to
57 : * a set of kernel objects. These objects do not need to be in an initialized
58 : * state. The permissions will be granted when the threads are initialized
59 : * in the early boot sequence.
60 : *
61 : * All arguments beyond the first must be pointers to kernel objects.
62 : *
63 : * @param name_ Name of the thread, as passed to K_THREAD_DEFINE()
64 : */
65 1 : #define K_THREAD_ACCESS_GRANT(name_, ...) \
66 : static void * const _CONCAT(_object_list_, name_)[] = \
67 : { __VA_ARGS__, NULL }; \
68 : static const STRUCT_SECTION_ITERABLE(k_object_assignment, \
69 : _CONCAT(_object_access_, name_)) = \
70 : { (&_k_thread_obj_ ## name_), \
71 : (_CONCAT(_object_list_, name_)) }
72 :
73 : /** Object initialized */
74 1 : #define K_OBJ_FLAG_INITIALIZED BIT(0)
75 : /** Object is Public */
76 1 : #define K_OBJ_FLAG_PUBLIC BIT(1)
77 : /** Object allocated */
78 1 : #define K_OBJ_FLAG_ALLOC BIT(2)
79 : /** Driver Object */
80 1 : #define K_OBJ_FLAG_DRIVER BIT(3)
81 :
82 : /**
83 : * Grant a thread access to a kernel object
84 : *
85 : * The thread will be granted access to the object if the caller is from
86 : * supervisor mode, or the caller is from user mode AND has permissions
87 : * on both the object and the thread whose access is being granted.
88 : *
89 : * @param object Address of kernel object
90 : * @param thread Thread to grant access to the object
91 : */
92 1 : __syscall void k_object_access_grant(const void *object,
93 : struct k_thread *thread);
94 :
95 : /**
96 : * Revoke a thread's access to a kernel object
97 : *
98 : * The thread will lose access to the object if the caller is from
99 : * supervisor mode, or the caller is from user mode AND has permissions
100 : * on both the object and the thread whose access is being revoked.
101 : *
102 : * @param object Address of kernel object
103 : * @param thread Thread to remove access to the object
104 : */
105 1 : void k_object_access_revoke(const void *object, struct k_thread *thread);
106 :
107 : /**
108 : * @brief Release an object
109 : *
110 : * Allows user threads to drop their own permission on an object
111 : * Their permissions are automatically cleared when a thread terminates.
112 : *
113 : * @param object The object to be released
114 : *
115 : */
116 1 : __syscall void k_object_release(const void *object);
117 :
118 : /**
119 : * Grant all present and future threads access to an object
120 : *
121 : * If the caller is from supervisor mode, or the caller is from user mode and
122 : * have sufficient permissions on the object, then that object will have
123 : * permissions granted to it for *all* current and future threads running in
124 : * the system, effectively becoming a public kernel object.
125 : *
126 : * Use of this API should be avoided on systems that are running untrusted code
127 : * as it is possible for such code to derive the addresses of kernel objects
128 : * and perform unwanted operations on them.
129 : *
130 : * It is not possible to revoke permissions on public objects; once public,
131 : * any thread may use it.
132 : *
133 : * @param object Address of kernel object
134 : */
135 1 : void k_object_access_all_grant(const void *object);
136 :
137 : /**
138 : * Check if a kernel object is of certain type and is valid.
139 : *
140 : * This checks if the kernel object exists, of certain type,
141 : * and has been initialized.
142 : *
143 : * @param obj Address of the kernel object
144 : * @param otype Object type (use K_OBJ_ANY for ignoring type checking)
145 : * @return True if kernel object (@a obj) exists, of certain type, and
146 : * has been initialized. False otherwise.
147 : */
148 1 : bool k_object_is_valid(const void *obj, enum k_objects otype);
149 :
150 : #else
151 : /* LCOV_EXCL_START */
152 : #define K_THREAD_ACCESS_GRANT(thread, ...)
153 :
154 : /**
155 : * @internal
156 : */
157 : static inline void z_impl_k_object_access_grant(const void *object,
158 : struct k_thread *thread)
159 : {
160 : ARG_UNUSED(object);
161 : ARG_UNUSED(thread);
162 : }
163 :
164 : /**
165 : * @internal
166 : */
167 : static inline void k_object_access_revoke(const void *object,
168 : struct k_thread *thread)
169 : {
170 : ARG_UNUSED(object);
171 : ARG_UNUSED(thread);
172 : }
173 :
174 : /**
175 : * @internal
176 : */
177 : static inline void z_impl_k_object_release(const void *object)
178 : {
179 : ARG_UNUSED(object);
180 : }
181 :
182 : static inline void k_object_access_all_grant(const void *object)
183 : {
184 : ARG_UNUSED(object);
185 : }
186 :
187 : static inline bool k_object_is_valid(const void *obj, enum k_objects otype)
188 : {
189 : ARG_UNUSED(obj);
190 : ARG_UNUSED(otype);
191 :
192 : return true;
193 : }
194 :
195 : /* LCOV_EXCL_STOP */
196 : #endif /* !CONFIG_USERSPACE */
197 :
198 : #if defined(CONFIG_DYNAMIC_OBJECTS) || defined(__DOXYGEN__)
199 : /**
200 : * Allocate a kernel object of a designated type
201 : *
202 : * This will instantiate at runtime a kernel object of the specified type,
203 : * returning a pointer to it. The object will be returned in an uninitialized
204 : * state, with the calling thread being granted permission on it. The memory
205 : * for the object will be allocated out of the calling thread's resource pool.
206 : *
207 : * @note This function is available only if @kconfig{CONFIG_DYNAMIC_OBJECTS}
208 : * is selected.
209 : *
210 : * @note Thread stack object has to use k_object_alloc_size() since stacks may
211 : * have different sizes.
212 : *
213 : * @param otype Requested kernel object type
214 : * @return A pointer to the allocated kernel object, or NULL if memory wasn't
215 : * available
216 : */
217 1 : __syscall void *k_object_alloc(enum k_objects otype);
218 :
219 : /**
220 : * Allocate a kernel object of a designated type and a given size
221 : *
222 : * This will instantiate at runtime a kernel object of the specified type,
223 : * returning a pointer to it. The object will be returned in an uninitialized
224 : * state, with the calling thread being granted permission on it. The memory
225 : * for the object will be allocated out of the calling thread's resource pool.
226 : *
227 : * This function is specially helpful for thread stack objects because
228 : * their sizes can vary. Other objects should probably look k_object_alloc().
229 : *
230 : * @note This function is available only if @kconfig{CONFIG_DYNAMIC_OBJECTS}
231 : * is selected.
232 : *
233 : * @param otype Requested kernel object type
234 : * @param size Requested kernel object size
235 : * @return A pointer to the allocated kernel object, or NULL if memory wasn't
236 : * available
237 : */
238 1 : __syscall void *k_object_alloc_size(enum k_objects otype, size_t size);
239 :
240 : /**
241 : * Free a kernel object previously allocated with k_object_alloc()
242 : *
243 : * This will return memory for a kernel object back to resource pool it was
244 : * allocated from. Care must be exercised that the object will not be used
245 : * during or after when this call is made.
246 : *
247 : * @note This function is available only if @kconfig{CONFIG_DYNAMIC_OBJECTS}
248 : * is selected.
249 : *
250 : * @param obj Pointer to the kernel object memory address.
251 : */
252 1 : void k_object_free(void *obj);
253 : #else
254 :
255 : /* LCOV_EXCL_START */
256 : static inline void *z_impl_k_object_alloc(enum k_objects otype)
257 : {
258 : ARG_UNUSED(otype);
259 :
260 : return NULL;
261 : }
262 :
263 : static inline void *z_impl_k_object_alloc_size(enum k_objects otype,
264 : size_t size)
265 : {
266 : ARG_UNUSED(otype);
267 : ARG_UNUSED(size);
268 :
269 : return NULL;
270 : }
271 :
272 : /**
273 : * @brief Free an object
274 : *
275 : * @param obj
276 : */
277 : static inline void k_object_free(void *obj)
278 : {
279 : ARG_UNUSED(obj);
280 : }
281 : /* LCOV_EXCL_STOP */
282 : #endif /* CONFIG_DYNAMIC_OBJECTS */
283 :
284 : /** @} */
285 :
286 : #include <zephyr/syscalls/kobject.h>
287 : #ifdef __cplusplus
288 : }
289 : #endif
290 :
291 : #endif
|