Skip to content

Commit 2fcf762

Browse files
pabigotcarlescufi
authored andcommitted
userspace: update k_object API to support immutable objects
The k_object API associates mutable state structures with known kernel objects to support userspace. The kernel objects themselves are not modified by the API, and in some cases (e.g. device structures) may be const-qualified. Update the API so that pointers to these const kernel objects can be passed without casting away the const qualifier. Fixes #27399 Signed-off-by: Peter Bigot <[email protected]>
1 parent aac9e2c commit 2fcf762

File tree

5 files changed

+42
-35
lines changed

5 files changed

+42
-35
lines changed

include/kernel.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,24 +227,24 @@ struct z_object_assignment {
227227
*
228228
* @param obj Address of the kernel object
229229
*/
230-
void z_object_init(void *obj);
230+
void z_object_init(const void *obj);
231231
#else
232232
/* LCOV_EXCL_START */
233233
#define K_THREAD_ACCESS_GRANT(thread, ...)
234234

235235
/**
236236
* @internal
237237
*/
238-
static inline void z_object_init(void *obj)
238+
static inline void z_object_init(const void *obj)
239239
{
240240
ARG_UNUSED(obj);
241241
}
242242

243243
/**
244244
* @internal
245245
*/
246-
static inline void z_impl_k_object_access_grant(void *object,
247-
struct k_thread *thread)
246+
static inline void z_impl_k_object_access_grant(const void *object,
247+
struct k_thread *thread)
248248
{
249249
ARG_UNUSED(object);
250250
ARG_UNUSED(thread);
@@ -253,7 +253,7 @@ static inline void z_impl_k_object_access_grant(void *object,
253253
/**
254254
* @internal
255255
*/
256-
static inline void k_object_access_revoke(void *object,
256+
static inline void k_object_access_revoke(const void *object,
257257
struct k_thread *thread)
258258
{
259259
ARG_UNUSED(object);
@@ -263,12 +263,12 @@ static inline void k_object_access_revoke(void *object,
263263
/**
264264
* @internal
265265
*/
266-
static inline void z_impl_k_object_release(void *object)
266+
static inline void z_impl_k_object_release(const void *object)
267267
{
268268
ARG_UNUSED(object);
269269
}
270270

271-
static inline void k_object_access_all_grant(void *object)
271+
static inline void k_object_access_all_grant(const void *object)
272272
{
273273
ARG_UNUSED(object);
274274
}
@@ -285,7 +285,8 @@ static inline void k_object_access_all_grant(void *object)
285285
* @param object Address of kernel object
286286
* @param thread Thread to grant access to the object
287287
*/
288-
__syscall void k_object_access_grant(void *object, struct k_thread *thread);
288+
__syscall void k_object_access_grant(const void *object,
289+
struct k_thread *thread);
289290

290291
/**
291292
* Revoke a thread's access to a kernel object
@@ -297,7 +298,7 @@ __syscall void k_object_access_grant(void *object, struct k_thread *thread);
297298
* @param object Address of kernel object
298299
* @param thread Thread to remove access to the object
299300
*/
300-
void k_object_access_revoke(void *object, struct k_thread *thread);
301+
void k_object_access_revoke(const void *object, struct k_thread *thread);
301302

302303
/**
303304
* @brief Release an object
@@ -308,7 +309,7 @@ void k_object_access_revoke(void *object, struct k_thread *thread);
308309
* @param object The object to be released
309310
*
310311
*/
311-
__syscall void k_object_release(void *object);
312+
__syscall void k_object_release(const void *object);
312313

313314
/**
314315
* Grant all present and future threads access to an object
@@ -327,7 +328,7 @@ __syscall void k_object_release(void *object);
327328
*
328329
* @param object Address of kernel object
329330
*/
330-
void k_object_access_all_grant(void *object);
331+
void k_object_access_all_grant(const void *object);
331332

332333
/**
333334
* Allocate a kernel object of a designated type

include/syscall_handler.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ int z_object_validate(struct z_object *ko, enum k_objects otype,
8989
* @param ko If retval=-EPERM, struct z_object * that was looked up, or NULL
9090
* @param otype Expected type of the kernel object
9191
*/
92-
extern void z_dump_object_error(int retval, void *obj, struct z_object *ko,
93-
enum k_objects otype);
92+
extern void z_dump_object_error(int retval, const void *obj,
93+
struct z_object *ko, enum k_objects otype);
9494

9595
/**
9696
* Kernel object validation function
@@ -102,7 +102,7 @@ extern void z_dump_object_error(int retval, void *obj, struct z_object *ko,
102102
* @return Kernel object's metadata, or NULL if the parameter wasn't the
103103
* memory address of a kernel object
104104
*/
105-
extern struct z_object *z_object_find(void *obj);
105+
extern struct z_object *z_object_find(const void *obj);
106106

107107
typedef void (*_wordlist_cb_func_t)(struct z_object *ko, void *context);
108108

@@ -157,7 +157,7 @@ extern void z_thread_perms_all_clear(struct k_thread *thread);
157157
*
158158
* @param object Address of the kernel object
159159
*/
160-
void z_object_uninit(void *obj);
160+
void z_object_uninit(const void *obj);
161161

162162
/**
163163
* Initialize and reset permissions to only access by the caller
@@ -176,7 +176,7 @@ void z_object_uninit(void *obj);
176176
*
177177
* @param object Address of the kernel object
178178
*/
179-
void z_object_recycle(void *obj);
179+
void z_object_recycle(const void *obj);
180180

181181
/**
182182
* @brief Obtain the size of a C string passed from user mode
@@ -426,7 +426,7 @@ extern int z_user_string_copy(char *dst, const char *src, size_t maxlen);
426426
Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1)
427427

428428
static inline int z_obj_validation_check(struct z_object *ko,
429-
void *obj,
429+
const void *obj,
430430
enum k_objects otype,
431431
enum _obj_init_check init)
432432
{
@@ -446,8 +446,10 @@ static inline int z_obj_validation_check(struct z_object *ko,
446446
}
447447

448448
#define Z_SYSCALL_IS_OBJ(ptr, type, init) \
449-
Z_SYSCALL_VERIFY_MSG(z_obj_validation_check(z_object_find((void *)ptr), (void *)ptr, \
450-
type, init) == 0, "access denied")
449+
Z_SYSCALL_VERIFY_MSG(z_obj_validation_check( \
450+
z_object_find((const void *)ptr), \
451+
(const void *)ptr, \
452+
type, init) == 0, "access denied")
451453

452454
/**
453455
* @brief Runtime check driver object pointer for presence of operation

kernel/userspace.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ struct dyn_obj {
118118
uint8_t data[]; /* The object itself */
119119
};
120120

121-
extern struct z_object *z_object_gperf_find(void *obj);
121+
extern struct z_object *z_object_gperf_find(const void *obj);
122122
extern void z_object_gperf_wordlist_foreach(_wordlist_cb_func_t func,
123123
void *context);
124124

@@ -357,7 +357,7 @@ void k_object_free(void *obj)
357357
}
358358
}
359359

360-
struct z_object *z_object_find(void *obj)
360+
struct z_object *z_object_find(const void *obj)
361361
{
362362
struct z_object *ret;
363363

@@ -366,7 +366,11 @@ struct z_object *z_object_find(void *obj)
366366
if (ret == NULL) {
367367
struct dyn_obj *dynamic_obj;
368368

369-
dynamic_obj = dyn_object_find(obj);
369+
/* The cast to pointer-to-non-const violates MISRA
370+
* 11.8 but is justified since we know dynamic objects
371+
* were not declared with a const qualifier.
372+
*/
373+
dynamic_obj = dyn_object_find((void *)obj);
370374
if (dynamic_obj != NULL) {
371375
ret = &dynamic_obj->kobj;
372376
}
@@ -533,7 +537,7 @@ static void dump_permission_error(struct z_object *ko)
533537
LOG_HEXDUMP_ERR(ko->perms, sizeof(ko->perms), "permission bitmap");
534538
}
535539

536-
void z_dump_object_error(int retval, void *obj, struct z_object *ko,
540+
void z_dump_object_error(int retval, const void *obj, struct z_object *ko,
537541
enum k_objects otype)
538542
{
539543
switch (retval) {
@@ -561,7 +565,7 @@ void z_dump_object_error(int retval, void *obj, struct z_object *ko,
561565
}
562566
}
563567

564-
void z_impl_k_object_access_grant(void *object, struct k_thread *thread)
568+
void z_impl_k_object_access_grant(const void *object, struct k_thread *thread)
565569
{
566570
struct z_object *ko = z_object_find(object);
567571

@@ -570,7 +574,7 @@ void z_impl_k_object_access_grant(void *object, struct k_thread *thread)
570574
}
571575
}
572576

573-
void k_object_access_revoke(void *object, struct k_thread *thread)
577+
void k_object_access_revoke(const void *object, struct k_thread *thread)
574578
{
575579
struct z_object *ko = z_object_find(object);
576580

@@ -579,12 +583,12 @@ void k_object_access_revoke(void *object, struct k_thread *thread)
579583
}
580584
}
581585

582-
void z_impl_k_object_release(void *object)
586+
void z_impl_k_object_release(const void *object)
583587
{
584588
k_object_access_revoke(object, _current);
585589
}
586590

587-
void k_object_access_all_grant(void *object)
591+
void k_object_access_all_grant(const void *object)
588592
{
589593
struct z_object *ko = z_object_find(object);
590594

@@ -626,7 +630,7 @@ int z_object_validate(struct z_object *ko, enum k_objects otype,
626630
return 0;
627631
}
628632

629-
void z_object_init(void *obj)
633+
void z_object_init(const void *obj)
630634
{
631635
struct z_object *ko;
632636

@@ -651,7 +655,7 @@ void z_object_init(void *obj)
651655
ko->flags |= K_OBJ_FLAG_INITIALIZED;
652656
}
653657

654-
void z_object_recycle(void *obj)
658+
void z_object_recycle(const void *obj)
655659
{
656660
struct z_object *ko = z_object_find(obj);
657661

@@ -662,7 +666,7 @@ void z_object_recycle(void *obj)
662666
}
663667
}
664668

665-
void z_object_uninit(void *obj)
669+
void z_object_uninit(const void *obj)
666670
{
667671
struct z_object *ko;
668672

kernel/userspace_handler.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <syscall_handler.h>
99
#include <kernel_structs.h>
1010

11-
static struct z_object *validate_any_object(void *obj)
11+
static struct z_object *validate_any_object(const void *obj)
1212
{
1313
struct z_object *ko;
1414
int ret;
@@ -36,7 +36,7 @@ static struct z_object *validate_any_object(void *obj)
3636
* To avoid double z_object_find() lookups, we don't call the implementation
3737
* function, but call a level deeper.
3838
*/
39-
static inline void z_vrfy_k_object_access_grant(void *object,
39+
static inline void z_vrfy_k_object_access_grant(const void *object,
4040
struct k_thread *thread)
4141
{
4242
struct z_object *ko;
@@ -49,7 +49,7 @@ static inline void z_vrfy_k_object_access_grant(void *object,
4949
}
5050
#include <syscalls/k_object_access_grant_mrsh.c>
5151

52-
static inline void z_vrfy_k_object_release(void *object)
52+
static inline void z_vrfy_k_object_release(const void *object)
5353
{
5454
struct z_object *ko;
5555

scripts/gen_kobject_list.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ def get_symbols(elf):
711711
# turned into a string, we told gperf to expect binary strings that are not
712712
# NULL-terminated.
713713
footer = """%%
714-
struct z_object *z_object_gperf_find(void *obj)
714+
struct z_object *z_object_gperf_find(const void *obj)
715715
{
716716
return z_object_lookup((const char *)obj, sizeof(void *));
717717
}
@@ -728,7 +728,7 @@ def get_symbols(elf):
728728
}
729729
730730
#ifndef CONFIG_DYNAMIC_OBJECTS
731-
struct z_object *z_object_find(void *obj)
731+
struct z_object *z_object_find(const void *obj)
732732
ALIAS_OF(z_object_gperf_find);
733733
734734
void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context)

0 commit comments

Comments
 (0)