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
3 changes: 3 additions & 0 deletions src/include/sof/llext_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct comp_dev;
struct comp_driver;
struct comp_ipc_config;
struct k_mem_domain;
struct lib_manager_mod_ctx;

static inline bool module_is_llext(const struct sof_man_module *mod)
{
Expand All @@ -33,13 +34,15 @@ int llext_manager_add_library(uint32_t module_id);
int llext_manager_add_domain(const uint32_t component_id, struct k_mem_domain *domain);
int llext_manager_rm_domain(const uint32_t component_id, struct k_mem_domain *domain);

int llext_manager_mod_find(const struct lib_manager_mod_ctx *ctx, unsigned int idx);
bool comp_is_llext(struct comp_dev *comp);
#else
#define module_is_llext(mod) false
#define llext_manager_allocate_module(ipc_config, ipc_specific_config) 0
#define llext_manager_free_module(component_id) 0
#define llext_manager_add_library(module_id) 0
#define llext_manager_add_domain(component_id, domain) 0
#define llext_manager_mod_find(ctx, idx) -ENOENT
#define comp_is_llext(comp) false
#endif

Expand Down
9 changes: 6 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 uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
const struct lib_manager_mod_ctx *const ctx = lib_manager_get_mod_ctx(module_id);

if (llext_manager_mod_find(ctx, entry_index) >= 0)
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
87 changes: 50 additions & 37 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 @@ -540,7 +589,7 @@ static int llext_manager_mod_init(struct lib_manager_mod_ctx *ctx,
}

/* Find a module context, containing the driver with the supplied index */
static int llext_manager_mod_find(const struct lib_manager_mod_ctx *ctx, unsigned int idx)
int llext_manager_mod_find(const struct lib_manager_mod_ctx *ctx, unsigned int idx)
{
unsigned int i;

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
Loading