diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 04b8a27e0c50..0671b4603d81 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -294,7 +294,6 @@ static int modules_free(struct processing_module *mod) { struct comp_dev *dev = mod->dev; struct module_data *md = &mod->priv; - struct comp_ipc_config *config = &(mod->dev->ipc_config); int ret; comp_info(dev, "modules_free()"); @@ -314,7 +313,7 @@ static int modules_free(struct processing_module *mod) if (!md->llext || !llext_unload(&md->llext)) { /* Free module resources allocated in L2 memory. */ - ret = lib_manager_free_module(mod, config); + ret = lib_manager_free_module(dev->ipc_config.id); if (ret < 0) comp_err(dev, "modules_free(), lib_manager_free_module() failed!"); } diff --git a/src/include/sof/ipc/topology.h b/src/include/sof/ipc/topology.h index 86a6bebdb6f2..825898a09811 100644 --- a/src/include/sof/ipc/topology.h +++ b/src/include/sof/ipc/topology.h @@ -50,7 +50,7 @@ struct ipc_comp_dev; const struct comp_driver *ipc4_get_comp_drv(int module_id); struct comp_dev *ipc4_get_comp_dev(uint32_t comp_id); int ipc4_add_comp_dev(struct comp_dev *dev); -const struct comp_driver *ipc4_get_drv(uint8_t *uuid); +const struct comp_driver *ipc4_get_drv(const uint8_t *uuid); int ipc4_chain_manager_create(struct ipc4_chain_dma *cdma); int ipc4_chain_dma_state(struct comp_dev *dev, struct ipc4_chain_dma *cdma); int ipc4_create_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma); diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index f918602dc02d..a396c1daf282 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -127,13 +127,13 @@ void lib_manager_init(void); /* * \brief Register module on driver list * - * param[in] desc - library manifest descriptor - * param[in] module_id - used to get manifest offset for module + * param[in] component_id - component id coming from ipc config. This function reguires valid + * lib_id and module_id fields of component id. * * Creates new comp_driver_info and initialize it for module from library * Adds new module to sof_get()->comp_drivers list */ -int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id); +int lib_manager_register_module(const uint32_t component_id); /* * \brief Get library module manifest descriptor @@ -156,20 +156,18 @@ struct processing_module; * (WIP) These feature will contain module validation and proper memory management. */ uintptr_t lib_manager_allocate_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config, + const struct comp_ipc_config *ipc_config, const void *ipc_specific_config, const void **buildinfo); /* * \brief Free module * - * param[in] drv - component driver - * param[in] ipc_config - audio component base configuration from IPC at creation - * param[in] ipc_specific_config - ipc4 base configuration + * param[in] component_id - component id coming from ipc config. This function reguires valid + * lib_id and module_id fields of component id. * * Function is responsible to free module resources in HP memory. */ -int lib_manager_free_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config); +int lib_manager_free_module(const uint32_t component_id); /* * \brief Load library * diff --git a/src/include/sof/llext_manager.h b/src/include/sof/llext_manager.h index 3f87a43ff9bd..9730fea4c377 100644 --- a/src/include/sof/llext_manager.h +++ b/src/include/sof/llext_manager.h @@ -12,9 +12,9 @@ struct comp_driver; struct comp_ipc_config; uintptr_t llext_manager_allocate_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config, + const struct comp_ipc_config *ipc_config, const void *ipc_specific_config, const void **buildinfo); -int llext_manager_free_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config); + +int llext_manager_free_module(const uint32_t component_id); #endif diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index c038af6a1097..ad14bac53685 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -728,7 +728,7 @@ int ipc4_chain_manager_create(struct ipc4_chain_dma *cdma) const struct comp_driver *drv; struct comp_dev *dev; - drv = ipc4_get_drv((uint8_t *)&uuid); + drv = ipc4_get_drv((const uint8_t *)&uuid); if (!drv) return -EINVAL; @@ -864,7 +864,7 @@ int ipc4_process_on_core(uint32_t core, bool blocking) return IPC4_SUCCESS; } -const struct comp_driver *ipc4_get_drv(uint8_t *uuid) +const struct comp_driver *ipc4_get_drv(const uint8_t *uuid) { struct comp_driver_list *drivers = comp_drivers_get(); struct list_item *clist; @@ -934,7 +934,7 @@ static const struct comp_driver *ipc4_library_get_drv(int module_id) mod_uuid = &uuid_map[i]; if (mod_uuid->module_id == module_id) - return ipc4_get_drv((uint8_t *)&mod_uuid->uuid); + return ipc4_get_drv((const uint8_t *)&mod_uuid->uuid); } tr_err(&comp_tr, "ipc4_library_get_drv(): Unsupported module ID %#x\n", module_id); @@ -990,7 +990,7 @@ const struct comp_driver *ipc4_get_comp_drv(int module_id) #if CONFIG_LIBRARY_MANAGER if (!drv) { /* New module not registered yet. */ - lib_manager_register_module(desc, module_id); + lib_manager_register_module(module_id); drv = ipc4_get_drv(mod->uuid); } #endif diff --git a/src/library_manager/lib_manager.c b/src/library_manager/lib_manager.c index d30253554482..9c9474ed577d 100644 --- a/src/library_manager/lib_manager.c +++ b/src/library_manager/lib_manager.c @@ -279,7 +279,7 @@ static int lib_manager_unload_libcode_modules(const uint32_t module_id, static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module_id, uint32_t instance_id, - struct sof_man_module *mod) + const struct sof_man_module *mod) { uint32_t instance_bss_size = mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count; @@ -296,7 +296,7 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module } static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t instance_id, - uint32_t is_pages, struct sof_man_module *mod) + uint32_t is_pages, const struct sof_man_module *mod) { uint32_t bss_size = (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count) @@ -324,7 +324,7 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins } static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instance_id, - struct sof_man_module *mod) + const struct sof_man_module *mod) { uint32_t bss_size = (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count) @@ -337,17 +337,17 @@ static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instanc return sys_mm_drv_unmap_region((__sparse_force void *)va_base, bss_size); } -static bool module_is_llext(struct sof_man_module *mod) +static inline bool module_is_llext(const struct sof_man_module *mod) { return mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT; } uintptr_t lib_manager_allocate_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config, + const struct comp_ipc_config *ipc_config, const void *ipc_specific_config, const void **buildinfo) { struct sof_man_fw_desc *desc; - struct sof_man_module *mod; + const struct sof_man_module *mod; const struct ipc4_base_module_cfg *base_cfg = ipc_specific_config; int ret; uint32_t module_id = IPC4_MOD_ID(ipc_config->id); @@ -396,22 +396,21 @@ uintptr_t lib_manager_allocate_module(struct processing_module *proc, return 0; } -int lib_manager_free_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config) +int lib_manager_free_module(const uint32_t component_id) { struct sof_man_fw_desc *desc; - struct sof_man_module *mod; - uint32_t module_id = IPC4_MOD_ID(ipc_config->id); + const struct sof_man_module *mod; + const uint32_t module_id = IPC4_MOD_ID(component_id); uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); int ret; - tr_dbg(&lib_manager_tr, "lib_manager_free_module(): mod_id: %#x", ipc_config->id); + tr_dbg(&lib_manager_tr, "lib_manager_free_module(): mod_id: %#x", component_id); desc = lib_manager_get_library_module_desc(module_id); mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index)); if (module_is_llext(mod)) - return llext_manager_free_module(proc, ipc_config); + return llext_manager_free_module(component_id); ret = lib_manager_unload_module(mod); if (ret < 0) @@ -423,7 +422,7 @@ int lib_manager_free_module(struct processing_module *proc, return ret; #endif /* CONFIG_LIBCODE_MODULE_SUPPORT */ - ret = lib_manager_free_module_instance(module_id, IPC4_INST_ID(ipc_config->id), mod); + ret = lib_manager_free_module_instance(module_id, IPC4_INST_ID(component_id), mod); if (ret < 0) { tr_err(&lib_manager_tr, "lib_manager_free_module(): free module instance failed: %d", ret); @@ -437,7 +436,7 @@ int lib_manager_free_module(struct processing_module *proc, #define PAGE_SZ 4096 /* equals to MAN_PAGE_SIZE used by rimage */ uintptr_t lib_manager_allocate_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config, + const struct comp_ipc_config *ipc_config, const void *ipc_specific_config, const void **buildinfo) { tr_err(&lib_manager_tr, @@ -445,8 +444,7 @@ uintptr_t lib_manager_allocate_module(struct processing_module *proc, return 0; } -int lib_manager_free_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config) +int lib_manager_free_module(const uint32_t component_id) { /* Since we cannot allocate the freeing is not considered to be an error */ tr_warn(&lib_manager_tr, @@ -487,15 +485,28 @@ static void lib_manager_update_sof_ctx(void *base_addr, uint32_t lib_id) } #if CONFIG_INTEL_MODULES -int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id) +int lib_manager_register_module(const uint32_t component_id) { - uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); - /* allocate new comp_driver_info */ + const struct lib_manager_mod_ctx *const ctx = lib_manager_get_mod_ctx(component_id); + const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(component_id); + const struct sof_man_fw_desc *desc; struct comp_driver_info *new_drv_info; struct comp_driver *drv = NULL; struct sof_man_module *mod; int ret; + /* Get library manifest based on component_id */ + if (!ctx || !ctx->base_addr) + return -ENOENT; + + desc = (const struct sof_man_fw_desc *)((const char *)ctx->base_addr + + SOF_MAN_ELF_TEXT_OFFSET); + if (entry_index >= desc->header.num_module_entries) { + tr_err(&lib_manager_tr, "Entry index %d out of bounds.", entry_index); + return -ENOENT; + } + + /* allocate new comp_driver_info */ new_drv_info = rmalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM | SOF_MEM_FLAG_COHERENT, sizeof(struct comp_driver_info)); @@ -520,7 +531,7 @@ int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id) /* Fill the new_drv_info structure with already known parameters */ /* Check already registered components */ mod = (struct sof_man_module *)((uint8_t *)desc + SOF_MAN_MODULE_OFFSET(entry_index)); - struct sof_uuid *uid = (struct sof_uuid *)&mod->uuid[0]; + const struct sof_uuid *uid = (struct sof_uuid *)&mod->uuid[0]; declare_dynamic_module_adapter(drv, SOF_COMP_MODULE_ADAPTER, uid, &lib_manager_tr); @@ -539,7 +550,7 @@ int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id) } #else /* CONFIG_INTEL_MODULES */ -int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id) +int lib_manager_register_module(const uint32_t component_id) { tr_err(&lib_manager_tr, "lib_manager_register_module(): Dynamic module loading is not supported"); @@ -689,15 +700,25 @@ static void __sparse_cache *lib_manager_allocate_store_mem(uint32_t size, } static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, - void __sparse_cache *man_buffer, + const void __sparse_cache *man_buffer, uint32_t lib_id) { void __sparse_cache *library_base_address; - struct sof_man_fw_desc *man_desc = (struct sof_man_fw_desc *) + const struct sof_man_fw_desc *man_desc = (struct sof_man_fw_desc *) ((__sparse_force uint8_t *)man_buffer + SOF_MAN_ELF_TEXT_OFFSET); uint32_t preload_size = man_desc->header.preload_page_count * PAGE_SZ; int ret; + /* + * The module manifest structure always has its maximum size regardless of + * the actual size of the manifest. + */ + if (preload_size < MAN_MAX_SIZE_V1_8) { + tr_err(&lib_manager_tr, "Invalid preload_size value %x.", preload_size); + return -EINVAL; + } + + /* Prepare storage memory, note: it is never freed, library unloading is unsupported */ /* * Prepare storage memory, note: it is never freed, it is assumed, that this * memory is abundant, so we store all loaded modules there permanently @@ -711,7 +732,7 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, #if CONFIG_LIBRARY_AUTH_SUPPORT /* AUTH_PHASE_FIRST - checks library manifest only. */ - ret = lib_manager_auth_proc((__sparse_force void *)man_buffer, + ret = lib_manager_auth_proc((__sparse_force const void *)man_buffer, MAN_MAX_SIZE_V1_8, AUTH_PHASE_FIRST); if (ret < 0) { rfree((__sparse_force void *)library_base_address); @@ -721,7 +742,7 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, /* Copy data from temp_mft_buf to destination memory (pointed by library_base_address) */ memcpy_s((__sparse_force void *)library_base_address, MAN_MAX_SIZE_V1_8, - (__sparse_force void *)man_buffer, MAN_MAX_SIZE_V1_8); + (__sparse_force const void *)man_buffer, MAN_MAX_SIZE_V1_8); /* Copy remaining library part into storage buffer */ ret = lib_manager_store_data(dma_ext, (uint8_t __sparse_cache *)library_base_address + diff --git a/src/library_manager/llext_manager.c b/src/library_manager/llext_manager.c index 23ded81f9a10..2f0afb6ddbe5 100644 --- a/src/library_manager/llext_manager.c +++ b/src/library_manager/llext_manager.c @@ -73,8 +73,7 @@ static int llext_manager_load_data_from_storage(void __sparse_cache *vma, void * return memcpy_s((__sparse_force void *)vma, size, s_addr, size); } -static int llext_manager_load_module(uint32_t module_id, struct sof_man_module *mod, - struct sof_man_fw_desc *desc) +static int llext_manager_load_module(uint32_t module_id, const struct sof_man_module *mod) { struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); uint8_t *load_base = (uint8_t *)ctx->base_addr; @@ -116,8 +115,7 @@ static int llext_manager_load_module(uint32_t module_id, struct sof_man_module * return ret; } -static int llext_manager_unload_module(uint32_t module_id, struct sof_man_module *mod, - struct sof_man_fw_desc *desc) +static int llext_manager_unload_module(uint32_t module_id, const struct sof_man_module *mod) { struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); void __sparse_cache *va_base_text = (void __sparse_cache *) @@ -136,13 +134,13 @@ static int llext_manager_unload_module(uint32_t module_id, struct sof_man_module } static void __sparse_cache *llext_manager_get_bss_address(uint32_t module_id, - struct sof_man_module *mod) + const struct sof_man_module *mod) { return (void __sparse_cache *)mod->segment[SOF_MAN_SEGMENT_BSS].v_base_addr; } static int llext_manager_allocate_module_bss(uint32_t module_id, - struct sof_man_module *mod) + const struct sof_man_module *mod) { struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS]; @@ -158,7 +156,7 @@ static int llext_manager_allocate_module_bss(uint32_t module_id, } static int llext_manager_free_module_bss(uint32_t module_id, - struct sof_man_module *mod) + const struct sof_man_module *mod) { struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS]; @@ -230,7 +228,7 @@ static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_modul } uintptr_t llext_manager_allocate_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config, + const struct comp_ipc_config *ipc_config, const void *ipc_specific_config, const void **buildinfo) { struct sof_man_fw_desc *desc; @@ -258,7 +256,7 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc, return 0; /* Map .text and the rest as .data */ - ret = llext_manager_load_module(module_id, mod, desc); + ret = llext_manager_load_module(module_id, mod); if (ret < 0) return 0; @@ -272,21 +270,20 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc, return mod_manifest->module.entry_point; } -int llext_manager_free_module(struct processing_module *proc, - struct comp_ipc_config *ipc_config) +int llext_manager_free_module(const uint32_t component_id) { struct sof_man_fw_desc *desc; - struct sof_man_module *mod; - uint32_t module_id = IPC4_MOD_ID(ipc_config->id); + const struct sof_man_module *mod; + const uint32_t module_id = IPC4_MOD_ID(component_id); uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); int ret; - tr_dbg(&lib_manager_tr, "llext_manager_free_module(): mod_id: %#x", ipc_config->id); + tr_dbg(&lib_manager_tr, "llext_manager_free_module(): mod_id: %#x", component_id); desc = lib_manager_get_library_module_desc(module_id); mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index)); - ret = llext_manager_unload_module(module_id, mod, desc); + ret = llext_manager_unload_module(module_id, mod); if (ret < 0) return ret;