@@ -238,11 +238,12 @@ static bool llext_manager_section_detached(const elf_shdr_t *shdr)
238238 return shdr -> sh_addr < SOF_MODULE_DRAM_LINK_END ;
239239}
240240
241- static int llext_manager_link (struct llext_loader * ldr , const char * name ,
241+ static int llext_manager_link (const char * name ,
242242 struct lib_manager_module * mctx , const void * * buildinfo ,
243243 const struct sof_man_module_manifest * * mod_manifest )
244244{
245245 struct llext * * llext = & mctx -> llext ;
246+ struct llext_loader * ldr = & mctx -> ebl -> loader ;
246247 int ret ;
247248
248249 if (* llext && !mctx -> mapped ) {
@@ -352,6 +353,7 @@ static int llext_manager_mod_init(struct lib_manager_mod_ctx *ctx,
352353 offs = mod_array [i ].segment [LIB_MANAGER_TEXT ].file_offset ;
353354 ctx -> mod [n_mod ].mapped = false;
354355 ctx -> mod [n_mod ].llext = NULL ;
356+ ctx -> mod [n_mod ].ebl = NULL ;
355357 ctx -> mod [n_mod ++ ].start_idx = i ;
356358 }
357359
@@ -429,16 +431,28 @@ static int llext_manager_link_single(uint32_t module_id, const struct sof_man_fw
429431 mod_size = ALIGN_UP (mod_array [i ].segment [LIB_MANAGER_TEXT ].file_offset - mod_offset ,
430432 PAGE_SZ );
431433
432- uint8_t * dram_base = (uint8_t * )desc - SOF_MAN_ELF_TEXT_OFFSET ;
433- struct llext_buf_loader ebl = LLEXT_BUF_LOADER (dram_base + mod_offset , mod_size );
434+ if (!mctx -> ebl ) {
435+ /* allocate once, never freed */
436+ mctx -> ebl = rmalloc (SOF_MEM_ZONE_RUNTIME_SHARED , 0 , SOF_MEM_CAPS_RAM ,
437+ sizeof (struct llext_buf_loader ));
438+ if (!mctx -> ebl ) {
439+ tr_err (& lib_manager_tr , "loader alloc failed" );
440+ return 0 ;
441+ }
442+
443+ uint8_t * dram_base = (uint8_t * )desc - SOF_MAN_ELF_TEXT_OFFSET ;
444+
445+ * mctx -> ebl = (struct llext_buf_loader )LLEXT_BUF_LOADER (dram_base + mod_offset ,
446+ mod_size );
447+ }
434448
435449 /*
436450 * LLEXT linking is only needed once for all the "drivers" in the
437451 * module. This calls llext_load(), which also takes references to any
438452 * dependencies, sets up sections and retrieves buildinfo and
439453 * mod_manifest
440454 */
441- ret = llext_manager_link (& ebl . loader , mod_array [entry_index - inst_idx ].name , mctx ,
455+ ret = llext_manager_link (mod_array [entry_index - inst_idx ].name , mctx ,
442456 buildinfo , mod_manifest );
443457 if (ret < 0 ) {
444458 tr_err (& lib_manager_tr , "linking failed: %d" , ret );
0 commit comments