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 <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2020-08-25 17:02:38 -07:00 committed by Anas Nashif
commit 00f71b0d63
6 changed files with 42 additions and 63 deletions

View file

@ -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

View file

@ -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
*/

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);
}