diff --git a/include/app_memory/mem_domain.h b/include/app_memory/mem_domain.h index c1946bca75e..845c8154d67 100644 --- a/include/app_memory/mem_domain.h +++ b/include/app_memory/mem_domain.h @@ -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. diff --git a/kernel/include/kswap.h b/kernel/include/kswap.h index 7a0b42f17fb..8bf5721eb36 100644 --- a/kernel/include/kswap.h +++ b/kernel/include/kswap.h @@ -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; diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c index 1589ad4f12e..97f3e10532f 100644 --- a/kernel/mem_domain.c +++ b/kernel/mem_domain.c @@ -11,6 +11,7 @@ #include #include #include +#include #define LOG_LEVEL CONFIG_KERNEL_LOG_LEVEL #include @@ -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; } diff --git a/kernel/thread.c b/kernel/thread.c index e8050b23524..1bbffd8dd19 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -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);