From 00f71b0d637234515da2cbaed09909bc61e544b7 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Tue, 25 Aug 2020 17:02:38 -0700 Subject: [PATCH] kernel: add CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API Saves us a few bytes of program text on arches that don't need these implemented, currently all uniprocessor MPU-based systems. Signed-off-by: Andrew Boie --- arch/Kconfig | 1 + arch/arc/core/mpu/arc_core_mpu.c | 36 ------------------- .../core/aarch32/cortex_m/mpu/arm_core_mpu.c | 27 -------------- include/sys/arch_interface.h | 2 ++ kernel/Kconfig | 29 +++++++++++++++ kernel/mem_domain.c | 10 ++++++ 6 files changed, 42 insertions(+), 63 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 960a1c942e4..9c5e669329b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -43,6 +43,7 @@ config X86 select ARCH_HAS_CUSTOM_SWAP_TO_MAIN if !X86_64 select ARCH_SUPPORTS_COREDUMP select CPU_HAS_MMU + select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE help x86 architecture diff --git a/arch/arc/core/mpu/arc_core_mpu.c b/arch/arc/core/mpu/arc_core_mpu.c index 6a756388504..0cf1e8081bd 100644 --- a/arch/arc/core/mpu/arc_core_mpu.c +++ b/arch/arc/core/mpu/arc_core_mpu.c @@ -32,42 +32,6 @@ int arch_mem_domain_max_partitions_get(void) return arc_core_mpu_get_max_domain_partition_regions(); } -/* - * Reset MPU region for a single memory partition - */ -void arch_mem_domain_partition_remove(struct k_mem_domain *domain, - uint32_t partition_id) -{ - /* No-op on this architecture */ -} - -/* - * Configure MPU memory domain - */ -void arch_mem_domain_thread_add(struct k_thread *thread) -{ - /* No-op on this architecture */ -} - -/* - * Destroy MPU regions for the mem domain - */ -void arch_mem_domain_destroy(struct k_mem_domain *domain) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_partition_add(struct k_mem_domain *domain, - uint32_t partition_id) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_thread_remove(struct k_thread *thread) -{ - /* No-op on this architecture */ -} - /* * Validate the given buffer is user accessible or not */ diff --git a/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c b/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c index a35b113f8e2..01d7f2a87b5 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c +++ b/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c @@ -323,33 +323,6 @@ int arch_mem_domain_max_partitions_get(void) return ARM_CORE_MPU_MAX_DOMAIN_PARTITIONS_GET(available_regions); } -void arch_mem_domain_thread_add(struct k_thread *thread) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_destroy(struct k_mem_domain *domain) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_partition_remove(struct k_mem_domain *domain, - uint32_t partition_id) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_partition_add(struct k_mem_domain *domain, - uint32_t partition_id) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_thread_remove(struct k_thread *thread) -{ - /* No-op on this architecture */ -} - int arch_buffer_validate(void *addr, size_t size, int write) { return arm_core_mpu_buffer_validate(addr, size, write); diff --git a/include/sys/arch_interface.h b/include/sys/arch_interface.h index f15617d4be1..980d28d765d 100644 --- a/include/sys/arch_interface.h +++ b/include/sys/arch_interface.h @@ -540,6 +540,7 @@ int arch_mem_domain_max_partitions_get(void); int arch_mem_domain_init(struct k_mem_domain *domain); #endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */ +#ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API /** * @brief Add a thread to a memory domain (arch-specific) * @@ -606,6 +607,7 @@ void arch_mem_domain_partition_add(struct k_mem_domain *domain, * @param domain The memory domain structure which needs to be deleted. */ void arch_mem_domain_destroy(struct k_mem_domain *domain); +#endif /* CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API */ /** * @brief Check memory region permissions diff --git a/kernel/Kconfig b/kernel/Kconfig index 2870d8cc948..14be7a3d390 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -709,6 +709,35 @@ config ARCH_MEM_DOMAIN_DATA Typical uses might be a set of page tables for that memory domain. +config ARCH_MEM_DOMAIN_SYNCHRONOUS_API + bool + depends on USERSPACE + help + This hidden option is selected by the target architecture if + modifying a memory domain's partitions at runtime, or changing + a memory domain's thread membership requires synchronous calls + into the architecture layer. + + If enabled, the architecture layer must implement the following + APIs: + + arch_mem_domain_thread_add + arch_mem_domain_thread_remove + arch_mem_domain_partition_remove + arch_mem_domain_partition_add + arch_mem_domain_destroy + + It's important to note that although supervisor threads can be + members of memory domains, they have no implications on supervisor + thread access to memory. Memory domain APIs may only be invoked from + supervisor mode. + + For these reasons, on uniprocessor systems unless memory access + policy is managed in separate software constructions like page + tables, these APIs don't need to be implemented as the underlying + memory management hardware will be reprogrammed on context switch + anyway. + menu "SMP Options" config USE_SWITCH diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c index e00a7b2b5d2..90d4b6a6770 100644 --- a/kernel/mem_domain.c +++ b/kernel/mem_domain.c @@ -146,7 +146,9 @@ void k_mem_domain_destroy(struct k_mem_domain *domain) key = k_spin_lock(&lock); +#ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API arch_mem_domain_destroy(domain); +#endif SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) { struct k_thread *thread = @@ -190,7 +192,9 @@ void k_mem_domain_add_partition(struct k_mem_domain *domain, domain->num_partitions++; +#ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API arch_mem_domain_partition_add(domain, p_idx); +#endif k_spin_unlock(&lock, key); } @@ -218,7 +222,9 @@ void k_mem_domain_remove_partition(struct k_mem_domain *domain, LOG_DBG("remove partition base %lx size %zu from domain %p\n", part->start, part->size, domain); +#ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API arch_mem_domain_partition_remove(domain, p_idx); +#endif /* A zero-sized partition denotes it's a free partition */ domain->partitions[p_idx].size = 0U; @@ -240,7 +246,9 @@ void k_mem_domain_add_thread(struct k_mem_domain *domain, k_tid_t thread) LOG_DBG("remove thread %p from memory domain %p\n", thread, thread->mem_domain_info.mem_domain); sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node); +#ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API arch_mem_domain_thread_remove(thread); +#endif } LOG_DBG("add thread %p to domain %p\n", thread, domain); @@ -248,7 +256,9 @@ void k_mem_domain_add_thread(struct k_mem_domain *domain, k_tid_t thread) &thread->mem_domain_info.mem_domain_q_node); thread->mem_domain_info.mem_domain = domain; +#ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API arch_mem_domain_thread_add(thread); +#endif k_spin_unlock(&lock, key); }