userspace: introduce default memory domain
We make a policy change here: all threads are members of a memory domain, never NULL. We introduce a default memory domain for threads that haven't been assigned to or inherited another one. Primary motivation for this change is better MMU support, as one common configuration will be to maintain page tables at the memory domain level. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
1a9f490353
commit
9bfc8d82d0
4 changed files with 31 additions and 23 deletions
|
@ -92,6 +92,18 @@ struct k_mem_domain {
|
|||
struct arch_mem_domain arch;
|
||||
#endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */
|
||||
};
|
||||
|
||||
/**
|
||||
* Default memory domain
|
||||
*
|
||||
* All threads are a member of some memory domain, even if running in
|
||||
* supervisor mode. Threads belong to this default memory domain if they
|
||||
* haven't been added to or inherited membership from some other domain.
|
||||
*
|
||||
* This memory domain has the z_libc_partition partition for the C library
|
||||
* added to it if exists.
|
||||
*/
|
||||
extern struct k_mem_domain k_mem_domain_default;
|
||||
#else
|
||||
/* To support use of IS_ENABLED for the APIs below */
|
||||
struct k_mem_domain;
|
||||
|
@ -164,7 +176,8 @@ extern void k_mem_domain_remove_partition(struct k_mem_domain *domain,
|
|||
/**
|
||||
* @brief Add a thread into a memory domain.
|
||||
*
|
||||
* Add a thread into a memory domain.
|
||||
* Add a thread into a memory domain. It will be removed from whatever
|
||||
* memory domain it previously belonged to.
|
||||
*
|
||||
* @param domain The memory domain that the thread is going to be added into.
|
||||
* @param thread ID of thread going to be added into the memory domain.
|
||||
|
|
|
@ -197,7 +197,7 @@ static inline void z_dummy_thread_init(struct k_thread *dummy_thread)
|
|||
dummy_thread->stack_info.size = 0U;
|
||||
#endif
|
||||
#ifdef CONFIG_USERSPACE
|
||||
dummy_thread->mem_domain_info.mem_domain = 0;
|
||||
dummy_thread->mem_domain_info.mem_domain = &k_mem_domain_default;
|
||||
#endif
|
||||
|
||||
_current_cpu->current = dummy_thread;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <sys/__assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <spinlock.h>
|
||||
#include <sys/libc-hooks.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_KERNEL_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
|
@ -19,6 +20,8 @@ LOG_MODULE_DECLARE(os);
|
|||
static struct k_spinlock lock;
|
||||
static uint8_t max_partitions;
|
||||
|
||||
struct k_mem_domain k_mem_domain_default;
|
||||
|
||||
#if __ASSERT_ON
|
||||
static bool check_add_partition(struct k_mem_domain *domain,
|
||||
struct k_mem_partition *part)
|
||||
|
@ -225,12 +228,12 @@ void k_mem_domain_add_thread(struct k_mem_domain *domain, k_tid_t thread)
|
|||
|
||||
__ASSERT_NO_MSG(domain != NULL);
|
||||
__ASSERT_NO_MSG(thread != NULL);
|
||||
__ASSERT(thread->mem_domain_info.mem_domain == NULL,
|
||||
"thread %p belongs to a different memory domain %p",
|
||||
thread, thread->mem_domain_info.mem_domain);
|
||||
|
||||
key = k_spin_lock(&lock);
|
||||
|
||||
if (thread->mem_domain_info.mem_domain != NULL) {
|
||||
sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node);
|
||||
arch_mem_domain_thread_remove(thread);
|
||||
}
|
||||
sys_dlist_append(&domain->mem_domain_q,
|
||||
&thread->mem_domain_info.mem_domain_q_node);
|
||||
thread->mem_domain_info.mem_domain = domain;
|
||||
|
@ -242,18 +245,7 @@ void k_mem_domain_add_thread(struct k_mem_domain *domain, k_tid_t thread)
|
|||
|
||||
void k_mem_domain_remove_thread(k_tid_t thread)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
|
||||
__ASSERT_NO_MSG(thread != NULL);
|
||||
__ASSERT(thread->mem_domain_info.mem_domain != NULL,
|
||||
"thread does not belong to a memory domain");
|
||||
|
||||
key = k_spin_lock(&lock);
|
||||
arch_mem_domain_thread_remove(thread);
|
||||
|
||||
sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node);
|
||||
thread->mem_domain_info.mem_domain = NULL;
|
||||
k_spin_unlock(&lock, key);
|
||||
k_mem_domain_add_thread(&k_mem_domain_default, thread);
|
||||
}
|
||||
|
||||
static int init_mem_domain_module(struct device *arg)
|
||||
|
@ -268,6 +260,11 @@ static int init_mem_domain_module(struct device *arg)
|
|||
*/
|
||||
__ASSERT(max_partitions <= CONFIG_MAX_DOMAIN_PARTITIONS, "");
|
||||
|
||||
k_mem_domain_init(&k_mem_domain_default, 0, NULL);
|
||||
#ifdef Z_LIBC_PARTITION_EXISTS
|
||||
k_mem_domain_add_partition(&k_mem_domain_default, &z_libc_partition);
|
||||
#endif /* Z_LIBC_PARTITION_EXISTS */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -537,7 +537,6 @@ char *z_setup_new_thread(struct k_thread *new_thread,
|
|||
z_object_init(new_thread);
|
||||
z_object_init(stack);
|
||||
new_thread->stack_obj = stack;
|
||||
new_thread->mem_domain_info.mem_domain = NULL;
|
||||
new_thread->syscall_frame = NULL;
|
||||
|
||||
/* Any given thread has access to itself */
|
||||
|
@ -601,10 +600,9 @@ char *z_setup_new_thread(struct k_thread *new_thread,
|
|||
#endif
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* New threads inherit any memory domain membership by the parent */
|
||||
if (_current->mem_domain_info.mem_domain != NULL) {
|
||||
k_mem_domain_add_thread(_current->mem_domain_info.mem_domain,
|
||||
new_thread);
|
||||
}
|
||||
new_thread->mem_domain_info.mem_domain = NULL;
|
||||
k_mem_domain_add_thread(_current->mem_domain_info.mem_domain,
|
||||
new_thread);
|
||||
|
||||
if ((options & K_INHERIT_PERMS) != 0U) {
|
||||
z_thread_perms_inherit(_current, new_thread);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue