Skip to content

Commit aec0d55

Browse files
committed
llext_manager: map detached sections for mmu
This patch will set permissions for detached sections if MMU is enabled Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
1 parent 1ef4e60 commit aec0d55

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

src/library_manager/llext_manager.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <zephyr/llext/llext.h>
3131
#include <zephyr/logging/log_ctrl.h>
3232
#include <zephyr/llext/inspect.h>
33+
#include <kernel_arch_interface.h>
3334

3435
#include <rimage/sof/user/manifest.h>
3536
#include <module/module/api_ver.h>
@@ -71,6 +72,32 @@ static int llext_manager_align_unmap(void __sparse_cache *vma, size_t size)
7172
return sys_mm_drv_unmap_region(aligned_vma, ALIGN_UP(pre_pad_size + size, PAGE_SZ));
7273
}
7374

75+
static void llext_manager_detached_map(void __sparse_cache *vma, size_t size, uint32_t flags)
76+
{
77+
#ifdef CONFIG_MMU
78+
size_t pre_pad_size = (uintptr_t)vma & (PAGE_SZ - 1);
79+
void *aligned_vma = (__sparse_force uint8_t *)vma - pre_pad_size;
80+
81+
/* Use cached virtual address */
82+
uintptr_t va = POINTER_TO_UINT(sys_cache_cached_ptr_get(aligned_vma));
83+
84+
arch_mem_map(aligned_vma, va, ALIGN_UP(pre_pad_size + size, PAGE_SZ), flags);
85+
#endif
86+
}
87+
88+
static void llext_manager_detached_unmap(void __sparse_cache *vma, size_t size)
89+
{
90+
#ifdef CONFIG_MMU
91+
size_t pre_pad_size = (uintptr_t)vma & (PAGE_SZ - 1);
92+
void *aligned_vma = (__sparse_force uint8_t *)vma - pre_pad_size;
93+
94+
/* Use cached virtual address */
95+
void *va = sys_cache_cached_ptr_get(aligned_vma);
96+
97+
arch_mem_unmap(va, ALIGN_UP(pre_pad_size + size, PAGE_SZ));
98+
#endif
99+
}
100+
74101
/*
75102
* Map the memory range covered by 'vma' and 'size' as writable, copy all
76103
* sections that belong to the specified 'region' and are contained in the
@@ -107,8 +134,16 @@ static int llext_manager_load_data_from_storage(const struct llext_loader *ldr,
107134

108135
/* skip detached sections (will be outside requested VMA area) */
109136
if ((uintptr_t)shdr->sh_addr < (uintptr_t)vma ||
110-
(uintptr_t)shdr->sh_addr >= (uintptr_t)vma + size)
137+
(uintptr_t)shdr->sh_addr >= (uintptr_t)vma + size) {
138+
llext_manager_detached_map((__sparse_force void *)
139+
((uint8_t *)region_addr + s_offset),
140+
shdr->sh_size, flags);
141+
if (flags & SYS_MM_MEM_PERM_EXEC)
142+
icache_invalidate_region((__sparse_force void *)
143+
((uint8_t *)region_addr + s_offset),
144+
shdr->sh_size);
111145
continue;
146+
}
112147

113148
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - s_offset,
114149
(const uint8_t *)region_addr + s_offset, shdr->sh_size);
@@ -129,6 +164,39 @@ static int llext_manager_load_data_from_storage(const struct llext_loader *ldr,
129164
return ret;
130165
}
131166

167+
static void llext_manager_unmap_detached_sections(const struct llext_loader *ldr,
168+
const struct llext *ext,
169+
enum llext_mem region,
170+
void __sparse_cache *vma,
171+
size_t size)
172+
{
173+
#ifdef CONFIG_MMU
174+
unsigned int i;
175+
const void *region_addr;
176+
177+
llext_get_region_info(ldr, ext, region, NULL, &region_addr, NULL);
178+
179+
for (i = 0; i < llext_section_count(ext); i++) {
180+
const elf_shdr_t *shdr;
181+
enum llext_mem s_region = LLEXT_MEM_COUNT;
182+
size_t s_offset = 0;
183+
184+
llext_get_section_info(ldr, ext, i, &shdr, &s_region, &s_offset);
185+
186+
/* skip sections not in the requested region */
187+
if (s_region != region)
188+
continue;
189+
190+
/* unmap detached sections (will be outside requested VMA area) */
191+
if ((uintptr_t)shdr->sh_addr < (uintptr_t)vma ||
192+
(uintptr_t)shdr->sh_addr >= (uintptr_t)vma + size)
193+
llext_manager_detached_unmap((__sparse_force void *)
194+
((uint8_t *)region_addr + s_offset),
195+
shdr->sh_size);
196+
}
197+
#endif
198+
}
199+
132200
static int llext_manager_load_module(struct lib_manager_module *mctx)
133201
{
134202
/* Executable code (.text) */
@@ -216,6 +284,9 @@ static int llext_manager_load_module(struct lib_manager_module *mctx)
216284

217285
static int llext_manager_unload_module(struct lib_manager_module *mctx)
218286
{
287+
const struct llext_loader *ldr = &mctx->ebl->loader;
288+
const struct llext *ext = mctx->llext;
289+
219290
/* Executable code (.text) */
220291
void __sparse_cache *va_base_text = (void __sparse_cache *)
221292
mctx->segment[LIB_MANAGER_TEXT].addr;
@@ -232,14 +303,20 @@ static int llext_manager_unload_module(struct lib_manager_module *mctx)
232303
size_t data_size = mctx->segment[LIB_MANAGER_DATA].size;
233304
int err = 0, ret;
234305

306+
llext_manager_unmap_detached_sections(ldr, ext, LLEXT_MEM_TEXT,
307+
va_base_text, text_size);
235308
ret = llext_manager_align_unmap(va_base_text, text_size);
236309
if (ret < 0)
237310
err = ret;
238311

312+
llext_manager_unmap_detached_sections(ldr, ext, LLEXT_MEM_DATA,
313+
va_base_data, data_size);
239314
ret = llext_manager_align_unmap(va_base_data, data_size);
240315
if (ret < 0 && !err)
241316
err = ret;
242317

318+
llext_manager_unmap_detached_sections(ldr, ext, LLEXT_MEM_RODATA,
319+
va_base_rodata, rodata_size);
243320
ret = llext_manager_align_unmap(va_base_rodata, rodata_size);
244321
if (ret < 0 && !err)
245322
err = ret;

zephyr/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ zephyr_library_named(modules_sof)
163163
# Zephyr C++ code requires 14 or newer standard
164164
set_property(TARGET modules_sof PROPERTY CXX_STANDARD 17)
165165

166-
zephyr_include_directories(
167-
include
168-
)
166+
zephyr_include_directories(include)
167+
zephyr_include_directories(${ZEPHYR_BASE}/kernel/include)
168+
zephyr_include_directories(${ZEPHYR_BASE}/arch/${ARCH}/include)
169169

170170
# SOC level sources
171171
# Files that are commented may not be needed.

0 commit comments

Comments
 (0)