Skip to content

Commit 69626d6

Browse files
lyakhlgirdwood
authored andcommitted
llext: update memory access flags when mapping
When dynamically mapping memory, we need to update access flags according to the type of the mapping. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 7658b48 commit 69626d6

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

src/library_manager/llext_manager.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ extern struct tr_ctx lib_manager_tr;
5151

5252
#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
5353

54+
static int llext_manager_update_flags(void __sparse_cache *vma, size_t size, uint32_t flags)
55+
{
56+
size_t pre_pad_size = (uintptr_t)vma & (PAGE_SZ - 1);
57+
void *aligned_vma = (__sparse_force uint8_t *)vma - pre_pad_size;
58+
59+
return sys_mm_drv_update_region_flags(aligned_vma,
60+
ALIGN_UP(pre_pad_size + size, PAGE_SZ), flags);
61+
}
62+
5463
static int llext_manager_align_map(void __sparse_cache *vma, size_t size, uint32_t flags)
5564
{
5665
size_t pre_pad_size = (uintptr_t)vma & (PAGE_SZ - 1);
@@ -71,15 +80,28 @@ static int llext_manager_align_unmap(void __sparse_cache *vma, size_t size)
7180
static int llext_manager_load_data_from_storage(void __sparse_cache *vma, void *s_addr,
7281
size_t size, uint32_t flags)
7382
{
74-
int ret = llext_manager_align_map(vma, size, flags);
83+
int ret = llext_manager_align_map(vma, size, SYS_MM_MEM_PERM_RW);
7584

7685
if (ret < 0) {
7786
tr_err(&lib_manager_tr, "cannot map %u of %p", size, (__sparse_force void *)vma);
7887
return ret;
7988
}
8089

81-
/* TODO: Change attributes for memory to FLAGS */
82-
return memcpy_s((__sparse_force void *)vma, size, s_addr, size);
90+
ret = memcpy_s((__sparse_force void *)vma, size, s_addr, size);
91+
if (ret < 0)
92+
return ret;
93+
94+
/*
95+
* We don't know what flags we're changing to, maybe the buffer will be
96+
* executable or read-only. Need to write back caches now
97+
*/
98+
dcache_writeback_region(vma, size);
99+
100+
ret = llext_manager_update_flags(vma, size, flags);
101+
if (!ret && (flags & SYS_MM_MEM_PERM_EXEC))
102+
icache_invalidate_region(vma, size);
103+
104+
return ret;
83105
}
84106

85107
static int llext_manager_load_module(uint32_t module_id, const struct sof_man_module *mod)
@@ -103,23 +125,11 @@ static int llext_manager_load_module(uint32_t module_id, const struct sof_man_mo
103125
if (ret < 0)
104126
return ret;
105127

106-
/* .text contains instructions and it also often contains local data */
107-
dcache_writeback_region(va_base_text, st_text_size);
108-
icache_invalidate_region(va_base_text, st_text_size);
109-
110128
/* Copy RODATA */
111129
ret = llext_manager_load_data_from_storage(va_base_rodata, src_rodata,
112130
st_rodata_size, SYS_MM_MEM_PERM_RW);
113131
if (ret < 0)
114-
goto e_text;
115-
116-
/* Some data can be accessed as uncached, in fact that's the default */
117-
dcache_writeback_region(va_base_rodata, st_rodata_size);
118-
119-
return 0;
120-
121-
e_text:
122-
llext_manager_align_unmap(va_base_text, st_text_size);
132+
llext_manager_align_unmap(va_base_text, st_text_size);
123133

124134
return ret;
125135
}

0 commit comments

Comments
 (0)