userspace: add optional member to memory domains

Some systems may need to associate arch-specific data to
a memory domain. Add a Kconfig and `arch` field for this,
and a new arch API to initialize it.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2020-08-19 13:11:47 -07:00 committed by Anas Nashif
commit bc35b0b780
4 changed files with 54 additions and 0 deletions

View file

@ -64,6 +64,9 @@ struct k_mem_domain {
sys_dlist_t mem_domain_q; sys_dlist_t mem_domain_q;
/** number of partitions in the domain */ /** number of partitions in the domain */
uint8_t num_partitions; uint8_t num_partitions;
#ifdef CONFIG_ARCH_MEM_DOMAIN_DATA
struct arch_mem_domain arch;
#endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */
}; };
#else #else
/* To support use of IS_ENABLED for the APIs below */ /* To support use of IS_ENABLED for the APIs below */

View file

@ -520,6 +520,26 @@ static inline bool arch_is_user_context(void);
*/ */
int arch_mem_domain_max_partitions_get(void); int arch_mem_domain_max_partitions_get(void);
#ifdef CONFIG_ARCH_MEM_DOMAIN_DATA
/**
*
* @brief Architecture-specific hook for memory domain initialization
*
* Perform any tasks needed to initialize architecture-specific data within
* the memory domain, such as reserving memory for page tables. All members
* of the provided memory domain aside from `arch` will be initialized when
* this is called, but no threads will be a assigned yet.
*
* This function may fail if initializing the memory domain requires allocation,
* such as for page tables.
*
* @param domain The memory domain to initialize
* @retval 0 Success
* @retval -ENOMEM Insufficient memory
*/
int arch_mem_domain_init(struct k_mem_domain *domain);
#endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */
/** /**
* @brief Add a thread to a memory domain (arch-specific) * @brief Add a thread to a memory domain (arch-specific)
* *

View file

@ -696,6 +696,19 @@ config MAX_DOMAIN_PARTITIONS
help help
Configure the maximum number of partitions per memory domain. Configure the maximum number of partitions per memory domain.
config ARCH_MEM_DOMAIN_DATA
bool
depends on USERSPACE
help
This hidden option is selected by the target architecture if
architecture-specific data is needed on a per memory domain basis.
If so, the architecture defines a 'struct arch_mem_domain' which is
embedded within every struct k_mem_domain. The architecture
must also define the arch_mem_domain_init() function to set this up
when a memory domain is created.
Typical uses might be a set of page tables for that memory domain.
menu "SMP Options" menu "SMP Options"
config USE_SWITCH config USE_SWITCH

View file

@ -12,6 +12,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <spinlock.h> #include <spinlock.h>
#define LOG_LEVEL CONFIG_KERNEL_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_DECLARE(os);
static struct k_spinlock lock; static struct k_spinlock lock;
static uint8_t max_partitions; static uint8_t max_partitions;
@ -124,6 +128,20 @@ void k_mem_domain_init(struct k_mem_domain *domain, uint8_t num_parts,
sys_dlist_init(&domain->mem_domain_q); sys_dlist_init(&domain->mem_domain_q);
#ifdef CONFIG_ARCH_MEM_DOMAIN_DATA
int ret = arch_mem_domain_init(domain);
/* TODO propagate return values, see #24609.
*
* Not using an assertion here as this is a memory allocation error
*/
if (ret != 0) {
LOG_ERR("architecture-specific initialization failed for domain %p with %d",
domain, ret);
k_panic();
}
#endif
k_spin_unlock(&lock, key); k_spin_unlock(&lock, key);
} }