Skip to content
Open
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
1 change: 1 addition & 0 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ struct lib_manager_module {
struct lib_manager_mod_ctx {
void *base_addr; /* library cold storage address (e.g. DRAM) */
unsigned int n_mod;
unsigned int load_type;
struct lib_manager_module *mod;
};

Expand Down
10 changes: 7 additions & 3 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,18 @@ static int lib_manager_free_module(const uint32_t component_id)

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

const struct lib_manager_mod_ctx *const ctx = lib_manager_get_mod_ctx(module_id);

if (ctx->load_type == SOF_MAN_MOD_TYPE_LLEXT ||
ctx->load_type == SOF_MAN_MOD_TYPE_LLEXT_AUX)
return llext_manager_free_module(component_id);

mod = lib_manager_get_module_manifest(module_id);
if (!mod) {
tr_err(&lib_manager_tr, "failed to get module descriptor");
return -EINVAL;
}

if (module_is_llext(mod))
return llext_manager_free_module(component_id);

ret = lib_manager_unload_module(mod);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -500,6 +503,7 @@ static void lib_manager_update_sof_ctx(void *base_addr, uint32_t lib_id)
}

ctx->base_addr = base_addr;
ctx->load_type = SOF_MAN_MOD_TYPE_MODULE;

_ext_lib->desc[lib_id] = ctx;
/* TODO: maybe need to call dcache_writeback here? */
Expand Down
86 changes: 50 additions & 36 deletions src/library_manager/llext_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,38 @@ static int llext_manager_load_data_from_storage(const struct sys_mm_drv_region *
return ret;
}

#ifdef CONFIG_USERSPACE
static int llext_manager_add_partition(struct k_mem_domain *domain,
uintptr_t addr, size_t size,
k_mem_partition_attr_t attr)
{
size_t pre_pad_size = addr & (PAGE_SZ - 1);
struct k_mem_partition part = {
.start = addr - pre_pad_size,
.size = ALIGN_UP(pre_pad_size + size, PAGE_SZ),
.attr = attr,
};

tr_dbg(&lib_manager_tr, "add %#zx @ %lx partition", part.size, part.start);
return k_mem_domain_add_partition(domain, &part);
}

static int llext_manager_rm_partition(struct k_mem_domain *domain,
uintptr_t addr, size_t size,
k_mem_partition_attr_t attr)
{
size_t pre_pad_size = addr & (PAGE_SZ - 1);
struct k_mem_partition part = {
.start = addr - pre_pad_size,
.size = ALIGN_UP(pre_pad_size + size, PAGE_SZ),
.attr = attr,
};

tr_dbg(&lib_manager_tr, "remove %#zx @ %lx partition", part.size, part.start);
return k_mem_domain_remove_partition(domain, &part);
}
#endif

static void llext_manager_unmap_detached_sections(const struct llext_loader *ldr,
const struct llext *ext,
enum llext_mem region,
Expand Down Expand Up @@ -350,6 +382,19 @@ static int llext_manager_unload_module(struct lib_manager_module *mctx)
mctx->segment[LIB_MANAGER_BSS].size;
int err = 0, ret;

#ifdef CONFIG_SOF_USERSPACE_LL
unsigned int sect_cnt = llext_section_count(ext);
size_t total = sect_cnt * sizeof(elf_shdr_t);
const elf_shdr_t *shdr;

ret = llext_get_section_info(ldr, ext, 0, &shdr, NULL, NULL);
if (ret < 0)
return ret;

/* Temporarily map ELF section headers */
llext_manager_add_partition(zephyr_ll_mem_domain(), (uintptr_t)shdr, total,
K_MEM_PARTITION_P_RW_U_NA | XTENSA_MMU_CACHED_WB);
#endif
llext_manager_unmap_detached_sections(ldr, ext, LLEXT_MEM_TEXT,
va_base_text, text_size);
ret = llext_manager_align_unmap(va_base_text, text_size);
Expand All @@ -374,6 +419,10 @@ static int llext_manager_unload_module(struct lib_manager_module *mctx)
if (ret < 0 && !err)
err = ret;

#ifdef CONFIG_SOF_USERSPACE_LL
llext_manager_rm_partition(zephyr_ll_mem_domain(), (uintptr_t)shdr, total,
K_MEM_PARTITION_P_RW_U_NA | XTENSA_MMU_CACHED_WB);
#endif
mctx->mapped = false;

#ifdef CONFIG_SOF_USERSPACE_LL
Expand Down Expand Up @@ -794,35 +843,6 @@ uintptr_t llext_manager_allocate_module(const struct comp_ipc_config *ipc_config
}

#ifdef CONFIG_USERSPACE
static int llext_manager_add_partition(struct k_mem_domain *domain,
uintptr_t addr, size_t size,
k_mem_partition_attr_t attr)
{
size_t pre_pad_size = addr & (PAGE_SZ - 1);
struct k_mem_partition part = {
.start = addr - pre_pad_size,
.size = ALIGN_UP(pre_pad_size + size, PAGE_SZ),
.attr = attr,
};

tr_dbg(&lib_manager_tr, "add %#zx @ %lx partition", part.size, part.start);
return k_mem_domain_add_partition(domain, &part);
}

static int llext_manager_rm_partition(struct k_mem_domain *domain,
uintptr_t addr, size_t size,
k_mem_partition_attr_t attr)
{
size_t pre_pad_size = addr & (PAGE_SZ - 1);
struct k_mem_partition part = {
.start = addr - pre_pad_size,
.size = ALIGN_UP(pre_pad_size + size, PAGE_SZ),
.attr = attr,
};

tr_dbg(&lib_manager_tr, "remove %#zx @ %lx partition", part.size, part.start);
return k_mem_domain_remove_partition(domain, &part);
}

static int llext_manager_add_mod_domain(struct lib_manager_module *mctx, struct k_mem_domain *domain)
{
Expand Down Expand Up @@ -1066,16 +1086,9 @@ int llext_manager_rm_domain(const uint32_t component_id, struct k_mem_domain *do
int llext_manager_free_module(const uint32_t component_id)
{
const uint32_t module_id = IPC4_MOD_ID(component_id);
struct sof_man_fw_desc *desc = (struct sof_man_fw_desc *)lib_manager_get_library_manifest(module_id);
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);

if (entry_index >= desc->header.num_module_entries) {
tr_err(&lib_manager_tr, "Invalid driver index %u exceeds %d",
entry_index, desc->header.num_module_entries - 1);
return -ENOENT;
}

if (!ctx->mod) {
tr_err(&lib_manager_tr, "NULL module array: ID %#x ctx %p", component_id, ctx);
Comment on lines 1089 to 1093
return -ENOENT;
Expand Down Expand Up @@ -1167,6 +1180,7 @@ int llext_manager_add_library(uint32_t module_id)
return ret;
}
}
ctx->load_type = SOF_MAN_MOD_TYPE_LLEXT;

return 0;
}
Expand Down
Loading