Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLEXT: Minor improvements #9703

Merged
merged 7 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,12 @@ enum {
LIB_MANAGER_TEXT,
LIB_MANAGER_DATA,
LIB_MANAGER_RODATA,
LIB_MANAGER_BSS,
LIB_MANAGER_N_SEGMENTS,
};

struct lib_manager_segment_desc {
uintptr_t addr;
size_t size;
size_t file_offset;
};

struct lib_manager_mod_ctx {
Expand Down
81 changes: 29 additions & 52 deletions src/library_manager/llext_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,8 @@ static int llext_manager_align_unmap(void __sparse_cache *vma, size_t size)
static int llext_manager_load_data_from_storage(const struct llext *ext,
void __sparse_cache *vma,
const uint8_t *load_base,
size_t region_offset,
size_t size, uint32_t flags)
{
const uint8_t *s_addr = load_base + region_offset;
unsigned int i;
int ret = llext_manager_align_map(vma, size, SYS_MM_MEM_PERM_RW);
const elf_shdr_t *shdr;
Expand All @@ -93,17 +91,22 @@ static int llext_manager_load_data_from_storage(const struct llext *ext,
return ret;
}

size_t init_offset = 0;

/* Need to copy sections within regions individually, offsets may differ */
for (i = 0, shdr = llext_section_headers(ext); i < llext_section_count(ext); i++, shdr++) {
if ((uintptr_t)shdr->sh_addr < (uintptr_t)vma ||
(uintptr_t)shdr->sh_addr >= (uintptr_t)vma + size)
continue;

size_t offset = shdr->sh_offset + FILE_TEXT_OFFSET_V1_8 - region_offset;
if (!init_offset)
init_offset = shdr->sh_offset;

/* found a section within the region */
size_t offset = shdr->sh_offset - init_offset;

ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - offset,
s_addr + offset, shdr->sh_size);
load_base + offset, shdr->sh_size);
if (ret < 0)
return ret;
}
Expand All @@ -122,10 +125,9 @@ static int llext_manager_load_data_from_storage(const struct llext *ext,
}

static int llext_manager_load_module(const struct llext *ext, const struct llext_buf_loader *ebl,
uint32_t module_id, const struct sof_man_module *mod)
uint32_t module_id)
{
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
const uint8_t *load_base = (const uint8_t *)ctx->base_addr;

/* Executable code (.text) */
void __sparse_cache *va_base_text = (void __sparse_cache *)
Expand All @@ -144,8 +146,8 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext

/* .bss, should be within writable data above */
void __sparse_cache *bss_addr = (void __sparse_cache *)
ctx->segment[LIB_MANAGER_BSS].addr;
size_t bss_size = ctx->segment[LIB_MANAGER_BSS].size;
ebl->loader.sects[LLEXT_MEM_BSS].sh_addr;
size_t bss_size = ebl->loader.sects[LLEXT_MEM_BSS].sh_size;
int ret;

/* Check, that .bss is within .data */
Expand All @@ -170,22 +172,19 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
}

/* Copy Code */
ret = llext_manager_load_data_from_storage(ext, va_base_text, load_base,
ctx->segment[LIB_MANAGER_TEXT].file_offset,
ret = llext_manager_load_data_from_storage(ext, va_base_text, ext->mem[LLEXT_MEM_TEXT],
text_size, SYS_MM_MEM_PERM_EXEC);
if (ret < 0)
return ret;

/* Copy read-only data */
ret = llext_manager_load_data_from_storage(ext, va_base_rodata, load_base,
ctx->segment[LIB_MANAGER_RODATA].file_offset,
ret = llext_manager_load_data_from_storage(ext, va_base_rodata, ext->mem[LLEXT_MEM_RODATA],
rodata_size, 0);
if (ret < 0)
goto e_text;

/* Copy writable data */
ret = llext_manager_load_data_from_storage(ext, va_base_data, load_base,
ctx->segment[LIB_MANAGER_DATA].file_offset,
ret = llext_manager_load_data_from_storage(ext, va_base_data, ext->mem[LLEXT_MEM_DATA],
data_size, SYS_MM_MEM_PERM_RW);
if (ret < 0)
goto e_rodata;
Expand All @@ -202,7 +201,7 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
return ret;
}

static int llext_manager_unload_module(uint32_t module_id, const struct sof_man_module *mod)
static int llext_manager_unload_module(uint32_t module_id)
{
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
/* Executable code (.text) */
Expand Down Expand Up @@ -241,7 +240,7 @@ static bool llext_manager_section_detached(const elf_shdr_t *shdr)
return shdr->sh_addr < SOF_MODULE_DRAM_LINK_END;
}

static int llext_manager_link(struct llext_buf_loader *ebl, uintptr_t dram_base,
static int llext_manager_link(struct llext_buf_loader *ebl,
const char *name, uint32_t module_id, struct module_data *md,
const void **buildinfo,
const struct sof_man_module_manifest **mod_manifest)
Expand All @@ -259,45 +258,29 @@ static int llext_manager_link(struct llext_buf_loader *ebl, uintptr_t dram_base,
return ret;

ctx->segment[LIB_MANAGER_TEXT].addr = ebl->loader.sects[LLEXT_MEM_TEXT].sh_addr;
ctx->segment[LIB_MANAGER_TEXT].file_offset =
(uintptr_t)md->llext->mem[LLEXT_MEM_TEXT] - dram_base;
ctx->segment[LIB_MANAGER_TEXT].size = ebl->loader.sects[LLEXT_MEM_TEXT].sh_size;

tr_dbg(&lib_manager_tr, ".text: start: %#lx size %#x offset %#x",
tr_dbg(&lib_manager_tr, ".text: start: %#lx size %#x",
ctx->segment[LIB_MANAGER_TEXT].addr,
ctx->segment[LIB_MANAGER_TEXT].size,
ctx->segment[LIB_MANAGER_TEXT].file_offset);
ctx->segment[LIB_MANAGER_TEXT].size);

/* All read-only data sections */
ctx->segment[LIB_MANAGER_RODATA].addr =
ebl->loader.sects[LLEXT_MEM_RODATA].sh_addr;
ctx->segment[LIB_MANAGER_RODATA].file_offset =
(uintptr_t)md->llext->mem[LLEXT_MEM_RODATA] - dram_base;
ctx->segment[LIB_MANAGER_RODATA].size = ebl->loader.sects[LLEXT_MEM_RODATA].sh_size;

tr_dbg(&lib_manager_tr, ".rodata: start: %#lx size %#x offset %#x",
tr_dbg(&lib_manager_tr, ".rodata: start: %#lx size %#x",
ctx->segment[LIB_MANAGER_RODATA].addr,
ctx->segment[LIB_MANAGER_RODATA].size,
ctx->segment[LIB_MANAGER_RODATA].file_offset);
ctx->segment[LIB_MANAGER_RODATA].size);

/* All writable data sections */
ctx->segment[LIB_MANAGER_DATA].addr =
ebl->loader.sects[LLEXT_MEM_DATA].sh_addr;
ctx->segment[LIB_MANAGER_DATA].file_offset =
(uintptr_t)md->llext->mem[LLEXT_MEM_DATA] - dram_base;
ctx->segment[LIB_MANAGER_DATA].size = ebl->loader.sects[LLEXT_MEM_DATA].sh_size;

tr_dbg(&lib_manager_tr, ".data: start: %#lx size %#x offset %#x",
tr_dbg(&lib_manager_tr, ".data: start: %#lx size %#x",
ctx->segment[LIB_MANAGER_DATA].addr,
ctx->segment[LIB_MANAGER_DATA].size,
ctx->segment[LIB_MANAGER_DATA].file_offset);

ctx->segment[LIB_MANAGER_BSS].addr = ebl->loader.sects[LLEXT_MEM_BSS].sh_addr;
ctx->segment[LIB_MANAGER_BSS].size = ebl->loader.sects[LLEXT_MEM_BSS].sh_size;

tr_dbg(&lib_manager_tr, ".bss: start: %#lx size %#x",
ctx->segment[LIB_MANAGER_BSS].addr,
ctx->segment[LIB_MANAGER_BSS].size);
ctx->segment[LIB_MANAGER_DATA].size);

ssize_t binfo_o = llext_find_section(&ebl->loader, ".mod_buildinfo");

Expand Down Expand Up @@ -330,19 +313,17 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
mod_size);
struct module_data *md = &proc->priv;

tr_dbg(&lib_manager_tr, "llext_manager_allocate_module(): mod_id: %#x",
ipc_config->id);
tr_dbg(&lib_manager_tr, "mod_id: %#x", ipc_config->id);

if (!ctx || !desc) {
tr_err(&lib_manager_tr,
"llext_manager_allocate_module(): failed to get module descriptor");
tr_err(&lib_manager_tr, "failed to get module descriptor");
return 0;
}

mod_array = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(0));

/* LLEXT linking is only needed once for all the modules in the library */
ret = llext_manager_link(&ebl, dram_base, mod_array[0].name, module_id, md,
ret = llext_manager_link(&ebl, mod_array[0].name, module_id, md,
(const void **)&buildinfo, &mod_manifest);
if (ret < 0) {
tr_err(&lib_manager_tr, "linking failed: %d", ret);
Expand All @@ -353,13 +334,12 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
/* First instance: check that the module is native */
if (buildinfo->format != SOF_MODULE_API_BUILD_INFO_FORMAT ||
buildinfo->api_version_number.full != SOF_MODULE_API_CURRENT_VERSION) {
tr_err(&lib_manager_tr,
"llext_manager_allocate_module(): Unsupported module API version");
return -ENOEXEC;
tr_err(&lib_manager_tr, "Unsupported module API version");
return 0;
}

/* Map executable code and data */
ret = llext_manager_load_module(md->llext, &ebl, module_id, mod_array);
ret = llext_manager_load_module(md->llext, &ebl, module_id);
if (ret < 0)
return 0;

Expand All @@ -372,16 +352,13 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,

int llext_manager_free_module(const uint32_t component_id)
{
const struct sof_man_module *mod;
const uint32_t module_id = IPC4_MOD_ID(component_id);
const unsigned int base_module_id = LIB_MANAGER_GET_LIB_ID(module_id) <<
LIB_MANAGER_LIB_ID_SHIFT;

tr_dbg(&lib_manager_tr, "llext_manager_free_module(): mod_id: %#x", component_id);

mod = lib_manager_get_module_manifest(base_module_id);
tr_dbg(&lib_manager_tr, "mod_id: %#x", component_id);

return llext_manager_unload_module(base_module_id, mod);
return llext_manager_unload_module(base_module_id);
}

bool comp_is_llext(struct comp_dev *comp)
Expand Down
23 changes: 6 additions & 17 deletions tools/rimage/src/adsp_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -2359,23 +2359,12 @@ void adsp_free(struct adsp *adsp)
if (!adsp)
return;

if (adsp->man_v1_5)
free(adsp->man_v1_5);

if (adsp->man_v1_5_sue)
free(adsp->man_v1_5_sue);

if (adsp->man_v1_8)
free(adsp->man_v1_8);

if (adsp->man_v2_5)
free(adsp->man_v2_5);

if (adsp->modules)
free(adsp->modules);

if (adsp->name)
free((char *)adsp->name);
free(adsp->man_v1_5);
free(adsp->man_v1_5_sue);
free(adsp->man_v1_8);
free(adsp->man_v2_5);
free(adsp->modules);
free((void *)adsp->name);

free(adsp);
}
Loading