diff --git a/doc/reference/usermode/kernelobjects.rst b/doc/reference/usermode/kernelobjects.rst index f493d32ac4e..c12145042d9 100644 --- a/doc/reference/usermode/kernelobjects.rst +++ b/doc/reference/usermode/kernelobjects.rst @@ -128,9 +128,8 @@ includes: instance of :cpp:enum:`k_objects`. * A set of flags for that object. This is currently used to track initialization state and whether an object is public or not. -* An extra data field. This is currently used for thread stack objects - to denote how large the stack is, and for thread objects to indicate - the thread's index in kernel object permission bitfields. +* An extra data field. The semantics of this field vary by object type, see + the definition of :c:type:`union z_object_data`. Dynamic objects allocated at runtime are tracked in a runtime red/black tree which is used in parallel to the gperf table when validating object pointers. diff --git a/include/kernel.h b/include/kernel.h index 9d1d4e076e4..18758bfbd3b 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -135,6 +135,7 @@ struct k_poll_signal; struct k_mem_domain; struct k_mem_partition; struct k_futex; +struct z_futex_data; /** * @brief Kernel Object Types @@ -165,6 +166,24 @@ enum k_objects { */ #ifdef CONFIG_USERSPACE +/* Object extra data. Only some objects use this, determined by object type */ +union z_object_data { + /* Backing mutex for K_OBJ_SYS_MUTEX */ + struct k_mutex *mutex; + + /* Numerical thread ID for K_OBJ_THREAD */ + unsigned int thread_id; + + /* Stack buffer size for K_OBJ__THREAD_STACK_ELEMENT */ + size_t stack_size; + + /* Futex wait queue and spinlock for K_OBJ_FUTEX */ + struct z_futex_data *futex_data; + + /* All other objects */ + int unused; +}; + /* Table generated by gperf, these objects are retrieved via * z_object_find() */ struct _k_object { @@ -172,7 +191,7 @@ struct _k_object { u8_t perms[CONFIG_MAX_THREAD_BYTES]; u8_t type; u8_t flags; - uintptr_t data; + union z_object_data data; } __packed __aligned(4); struct _k_object_assignment { diff --git a/kernel/futex.c b/kernel/futex.c index c31fb0892ac..8507cd2d014 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -21,7 +21,7 @@ static struct z_futex_data *k_futex_find_data(struct k_futex *futex) return NULL; } - return (struct z_futex_data *)obj->data; + return obj->data.futex_data; } int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all) diff --git a/kernel/thread.c b/kernel/thread.c index 751cc392e81..67c55309c69 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -664,9 +664,9 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, /* Testing less-than-or-equal since additional room may have been * allocated for alignment constraints */ - Z_OOPS(Z_SYSCALL_VERIFY_MSG(total_size <= stack_object->data, - "stack size %zu is too big, max is %lu", - total_size, stack_object->data)); + Z_OOPS(Z_SYSCALL_VERIFY_MSG(total_size <= stack_object->data.stack_size, + "stack size %zu is too big, max is %zu", + total_size, stack_object->data.stack_size)); /* User threads may only create other user threads and they can't * be marked as essential diff --git a/kernel/userspace.c b/kernel/userspace.c index 240f4fbea45..d27781d2108 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -263,7 +263,7 @@ void *z_impl_k_object_alloc(enum k_objects otype) return NULL; } - dyn_obj->kobj.data = tidx; + dyn_obj->kobj.data.thread_id = tidx; } /* The allocating thread implicitly gets permission on kernel objects @@ -297,7 +297,7 @@ void k_object_free(void *obj) sys_dlist_remove(&dyn_obj->obj_list); if (dyn_obj->kobj.type == K_OBJ_THREAD) { - thread_idx_free(dyn_obj->kobj.data); + thread_idx_free(dyn_obj->kobj.data.thread_id); } } k_spin_unlock(&objfree_lock, key); @@ -340,7 +340,7 @@ void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) } #endif /* CONFIG_DYNAMIC_OBJECTS */ -static int thread_index_get(struct k_thread *thread) +static unsigned int thread_index_get(struct k_thread *thread) { struct _k_object *ko; @@ -350,7 +350,7 @@ static int thread_index_get(struct k_thread *thread) return -1; } - return ko->data; + return ko->data.thread_id; } static void unref_check(struct _k_object *ko, uintptr_t index) diff --git a/lib/os/mutex.c b/lib/os/mutex.c index 84f207074ff..0e952e8e940 100644 --- a/lib/os/mutex.c +++ b/lib/os/mutex.c @@ -18,7 +18,7 @@ static struct k_mutex *get_k_mutex(struct sys_mutex *mutex) return NULL; } - return (struct k_mutex *)obj->data; + return obj->data.mutex; } static bool check_sys_mutex_addr(struct sys_mutex *addr) diff --git a/scripts/elf_helper.py b/scripts/elf_helper.py index 44b53162e2e..f5842d2f50f 100644 --- a/scripts/elf_helper.py +++ b/scripts/elf_helper.py @@ -71,10 +71,10 @@ class KobjectInstance: self.data = thread_counter thread_counter = thread_counter + 1 elif self.type_obj.name == "sys_mutex": - self.data = "(uintptr_t)(&kernel_mutexes[%d])" % sys_mutex_counter + self.data = "&kernel_mutexes[%d]" % sys_mutex_counter sys_mutex_counter += 1 elif self.type_obj.name == "k_futex": - self.data = "(uintptr_t)(&futex_data[%d])" % futex_counter + self.data = "&futex_data[%d]" % futex_counter futex_counter += 1 else: self.data = 0 diff --git a/scripts/gen_kobject_list.py b/scripts/gen_kobject_list.py index e565835844a..18954fa539d 100755 --- a/scripts/gen_kobject_list.py +++ b/scripts/gen_kobject_list.py @@ -144,6 +144,12 @@ void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context) #endif """ +metadata_names = { + "K_OBJ_THREAD" : "thread_id", + "K_OBJ__THREAD_STACK_ELEMENT" : "stack_size", + "K_OBJ_SYS_MUTEX" : "mutex", + "K_OBJ_FUTEX" : "futex_data" +} def write_gperf_table(fp, eh, objs, static_begin, static_end): fp.write(header) @@ -204,7 +210,13 @@ def write_gperf_table(fp, eh, objs, static_begin, static_end): if is_driver: flags += " | K_OBJ_FLAG_DRIVER" - fp.write("\", {}, %s, %s, %s\n" % (obj_type, flags, str(ko.data))) + if ko.type_name in metadata_names: + tname = metadata_names[ko.type_name] + else: + tname = "unused" + + fp.write("\", {}, %s, %s, { .%s = %s }\n" % (obj_type, flags, + tname, str(ko.data))) if obj_type == "K_OBJ_THREAD": idx = math.floor(ko.data / 8)