userspace: add K_THREAD_ACCCESS_GRANT()
It's possible to declare static threads that start up as K_USER, but these threads can't do much since they start with permissions on no kernel objects other than their own thread object. Rather than do some run-time synchronization to have some other thread grant the necessary permissions, we introduce macros to conveniently assign object permissions to these threads when they are brought up at boot by the kernel. The tables generated here are constant and live in ROM when possible. Example usage: K_THREAD_DEFINE(my_thread, STACK_SIZE, my_thread_entry, NULL, NULL, NULL, 0, K_USER, K_NO_WAIT); K_THREAD_ACCESS_GRANT(my_thread, &my_sem, &my_mutex, &my_pipe); Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
493852bac3
commit
877f82e847
4 changed files with 63 additions and 2 deletions
|
@ -181,6 +181,32 @@ struct _k_object {
|
||||||
u32_t data;
|
u32_t data;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct _k_object_assignment {
|
||||||
|
struct k_thread *thread;
|
||||||
|
void * const *objects;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Grant a static thread access to a list of kernel objects
|
||||||
|
*
|
||||||
|
* For threads declared with K_THREAD_DEFINE(), grant the thread access to
|
||||||
|
* a set of kernel objects. These objects do not need to be in an initialized
|
||||||
|
* state. The permissions will be granted when the threads are initialized
|
||||||
|
* in the early boot sequence.
|
||||||
|
*
|
||||||
|
* All arguments beyond the first must be pointers to kernel objects.
|
||||||
|
*
|
||||||
|
* @param name_ Name of the thread, as passed to K_THREAD_DEFINE()
|
||||||
|
*/
|
||||||
|
#define K_THREAD_ACCESS_GRANT(name_, ...) \
|
||||||
|
static void * const _CONCAT(_object_list_, name_)[] = \
|
||||||
|
{ __VA_ARGS__, NULL }; \
|
||||||
|
static __used __in_section_unique(object_access) \
|
||||||
|
const struct _k_object_assignment \
|
||||||
|
_CONCAT(_object_access_, name_) = \
|
||||||
|
{ (&_k_thread_obj_ ## name_), \
|
||||||
|
(_CONCAT(_object_list_, name_)) }
|
||||||
|
|
||||||
#define K_OBJ_FLAG_INITIALIZED BIT(0)
|
#define K_OBJ_FLAG_INITIALIZED BIT(0)
|
||||||
#define K_OBJ_FLAG_PUBLIC BIT(1)
|
#define K_OBJ_FLAG_PUBLIC BIT(1)
|
||||||
|
|
||||||
|
@ -195,6 +221,9 @@ struct _k_object {
|
||||||
*/
|
*/
|
||||||
void _k_object_init(void *obj);
|
void _k_object_init(void *obj);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#define K_THREAD_ACCESS_GRANT(thread, ...)
|
||||||
|
|
||||||
static inline void _k_object_init(void *obj)
|
static inline void _k_object_init(void *obj)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(obj);
|
ARG_UNUSED(obj);
|
||||||
|
|
|
@ -24,7 +24,17 @@
|
||||||
__init_array_end = .;
|
__init_array_end = .;
|
||||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_USERSPACE
|
||||||
|
/* Build-time assignment of permissions to kernel objects to
|
||||||
|
* threads declared with K_THREAD_DEFINE()
|
||||||
|
*/
|
||||||
|
SECTION_PROLOGUE(object_access, (OPTIONAL),)
|
||||||
|
{
|
||||||
|
__object_access_start = .;
|
||||||
|
KEEP(*(".object_access.*"))
|
||||||
|
__object_access_end = .;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
SECTION_PROLOGUE (devconfig, (OPTIONAL),)
|
SECTION_PROLOGUE (devconfig, (OPTIONAL),)
|
||||||
{
|
{
|
||||||
__devconfig_start = .;
|
__devconfig_start = .;
|
||||||
|
|
|
@ -590,6 +590,25 @@ void _k_thread_single_abort(struct k_thread *thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MULTITHREADING
|
#ifdef CONFIG_MULTITHREADING
|
||||||
|
#ifdef CONFIG_USERSPACE
|
||||||
|
extern char __object_access_start[];
|
||||||
|
extern char __object_access_end[];
|
||||||
|
|
||||||
|
static void grant_static_access(void)
|
||||||
|
{
|
||||||
|
struct _k_object_assignment *pos;
|
||||||
|
|
||||||
|
for (pos = (struct _k_object_assignment *)__object_access_start;
|
||||||
|
pos < (struct _k_object_assignment *)__object_access_end;
|
||||||
|
pos++) {
|
||||||
|
for (int i = 0; pos->objects[i] != NULL; i++) {
|
||||||
|
k_object_access_grant(pos->objects[i],
|
||||||
|
pos->thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_USERSPACE */
|
||||||
|
|
||||||
void _init_static_threads(void)
|
void _init_static_threads(void)
|
||||||
{
|
{
|
||||||
unsigned int key;
|
unsigned int key;
|
||||||
|
@ -609,6 +628,9 @@ void _init_static_threads(void)
|
||||||
thread_data->init_thread->init_data = thread_data;
|
thread_data->init_thread->init_data = thread_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_USERSPACE
|
||||||
|
grant_static_access();
|
||||||
|
#endif
|
||||||
_sched_lock();
|
_sched_lock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -489,7 +489,7 @@ class SizeCalculator:
|
||||||
"_k_queue_area", "_net_buf_pool_area", "app_datas",
|
"_k_queue_area", "_net_buf_pool_area", "app_datas",
|
||||||
"kobject_data", "mmu_tables"]
|
"kobject_data", "mmu_tables"]
|
||||||
# These get copied into RAM only on non-XIP
|
# These get copied into RAM only on non-XIP
|
||||||
ro_sections = ["text", "ctors", "init_array", "reset",
|
ro_sections = ["text", "ctors", "init_array", "reset", "object_access",
|
||||||
"rodata", "devconfig", "net_l2", "vector"]
|
"rodata", "devconfig", "net_l2", "vector"]
|
||||||
|
|
||||||
def __init__(self, filename, extra_sections):
|
def __init__(self, filename, extra_sections):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue