mm: introduce update memory flags api

There are cases when attributes of mapped virtual memory need
to be updated. E.g. in case there is loadable library/module
code loaded to the l2 memory then memory needs to be read-write.
After the code is loaded and is ready to be executed then
attributes of mapped memory should be updated to
read-only/executable without loosing memory contents.

Signed-off-by: Jaroslaw Stelter <Jaroslaw.Stelter@intel.com>
This commit is contained in:
Jaroslaw Stelter 2022-07-12 12:09:29 +02:00 committed by Carles Cufí
commit cf24124efa
4 changed files with 126 additions and 0 deletions

View file

@ -434,3 +434,38 @@ out:
__weak FUNC_ALIAS(sys_mm_drv_simple_move_array,
sys_mm_drv_move_array, int);
int sys_mm_drv_simple_update_region_flags(void *virt, size_t size, uint32_t flags)
{
k_spinlock_key_t key;
int ret = 0;
size_t offset;
CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt) ||
!sys_mm_drv_is_size_aligned(size)) {
ret = -EINVAL;
goto out;
}
key = k_spin_lock(&sys_mm_drv_common_lock);
for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
uint8_t *va = (uint8_t *)virt + offset;
int ret2 = sys_mm_drv_update_page_flags(va, flags);
if (ret2 != 0) {
__ASSERT(false, "cannot update flags %p\n", va);
ret = ret2;
}
}
k_spin_unlock(&sys_mm_drv_common_lock, key);
out:
return ret;
}
__weak FUNC_ALIAS(sys_mm_drv_simple_update_region_flags,
sys_mm_drv_update_region_flags, int);

View file

@ -270,4 +270,27 @@ int sys_mm_drv_simple_move_array(void *virt_old, size_t size,
void *virt_new,
uintptr_t *phys_new, size_t phys_cnt);
/**
* @brief Update memory region flags
*
* This changes the attributes of physical memory which is already
* mapped to a virtual address. This is useful when use case of
* specific memory region changes.
* E.g. when the library/module code is copied to the memory then
* it needs to be read-write and after it has already
* been copied and library/module code is ready to be executed then
* attributes need to be changed to read-only/executable.
* Calling this API must not cause losing memory contents.
*
* @param virt Page-aligned virtual address to be updated
* @param size Page-aligned size of the mapped memory region in bytes
* @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
*
* @retval 0 if successful
* @retval -EINVAL if invalid arguments are provided
* @retval -EFAULT if virtual addresses is not mapped
*/
int sys_mm_drv_simple_update_region_flags(void *virt, size_t size, uint32_t flags);
#endif /* ZEPHYR_DRIVERS_SYSTEM_MM_DRV_COMMON_H_ */

View file

@ -261,6 +261,28 @@ int sys_mm_drv_page_flag_get(void *virt, uint32_t *flags)
return 0;
}
int sys_mm_drv_update_page_flags(void *virt, uint32_t flags)
{
ARG_UNUSED(virt);
ARG_UNUSED(flags);
/*
* There are no caching mode, or R/W, or eXecution (etc.) bits.
* So just return 0.
*/
return 0;
}
int sys_mm_drv_update_region_flags(void *virt, size_t size,
uint32_t flags)
{
void *va = z_soc_cached_ptr(virt);
return sys_mm_drv_simple_update_region_flags(va, size, flags);
}
int sys_mm_drv_remap_region(void *virt_old, size_t size,
void *virt_new)
{