userspace: do not auto-cleanup static objects
Dynamic kernel objects enforce that the permission state of an object is also a reference count; using a kernel object without permission regardless of caller privilege level is a programming bug. However, this is not the case for static objects. In particular, supervisor threads are allowed to use any object they like without worrying about permissions, and the logic here was causing cleanup functions to be called over and over again on kernel objects that were actually in use. The automatic cleanup mechanism was intended for dynamic objects anyway, so just skip it entirely for static objects. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
1d50a09575
commit
7ecc359f2c
1 changed files with 21 additions and 19 deletions
|
@ -331,11 +331,23 @@ static int thread_index_get(struct k_thread *t)
|
||||||
return ko->data;
|
return ko->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unref_check(struct _k_object *ko)
|
static void unref_check(struct _k_object *ko, int index)
|
||||||
{
|
{
|
||||||
|
int key = irq_lock();
|
||||||
|
|
||||||
|
sys_bitfield_clear_bit((mem_addr_t)&ko->perms, index);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DYNAMIC_OBJECTS
|
||||||
|
struct dyn_obj *dyn_obj =
|
||||||
|
CONTAINER_OF(ko, struct dyn_obj, kobj);
|
||||||
|
|
||||||
|
if ((ko->flags & K_OBJ_FLAG_ALLOC) == 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < CONFIG_MAX_THREAD_BYTES; i++) {
|
for (int i = 0; i < CONFIG_MAX_THREAD_BYTES; i++) {
|
||||||
if (ko->perms[i] != 0) {
|
if (ko->perms[i] != 0) {
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,15 +371,12 @@ static void unref_check(struct _k_object *ko)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_OBJECTS
|
rb_remove(&obj_rb_tree, &dyn_obj->node);
|
||||||
if ((ko->flags & K_OBJ_FLAG_ALLOC) != 0) {
|
sys_dlist_remove(&dyn_obj->obj_list);
|
||||||
struct dyn_obj *dyn_obj =
|
k_free(dyn_obj);
|
||||||
CONTAINER_OF(ko, struct dyn_obj, kobj);
|
out:
|
||||||
rb_remove(&obj_rb_tree, &dyn_obj->node);
|
|
||||||
sys_dlist_remove(&dyn_obj->obj_list);
|
|
||||||
k_free(dyn_obj);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
irq_unlock(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wordlist_cb(struct _k_object *ko, void *ctx_ptr)
|
static void wordlist_cb(struct _k_object *ko, void *ctx_ptr)
|
||||||
|
@ -407,22 +416,15 @@ void _thread_perms_clear(struct _k_object *ko, struct k_thread *thread)
|
||||||
int index = thread_index_get(thread);
|
int index = thread_index_get(thread);
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
unsigned int key = irq_lock();
|
unref_check(ko, index);
|
||||||
|
|
||||||
sys_bitfield_clear_bit((mem_addr_t)&ko->perms, index);
|
|
||||||
unref_check(ko);
|
|
||||||
irq_unlock(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_perms_cb(struct _k_object *ko, void *ctx_ptr)
|
static void clear_perms_cb(struct _k_object *ko, void *ctx_ptr)
|
||||||
{
|
{
|
||||||
int id = (int)ctx_ptr;
|
int id = (int)ctx_ptr;
|
||||||
unsigned int key = irq_lock();
|
|
||||||
|
|
||||||
sys_bitfield_clear_bit((mem_addr_t)&ko->perms, id);
|
unref_check(ko, id);
|
||||||
unref_check(ko);
|
|
||||||
irq_unlock(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _thread_perms_all_clear(struct k_thread *thread)
|
void _thread_perms_all_clear(struct k_thread *thread)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue