Skip to content
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
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace15_mtpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why call it experimental? Perhaps LLEXT_SAVE_RESTORE makes better sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranj063 we don't, Zephyr does. This option has recently been added to Zephyr to support our partial LLEXT restore, but the way how we added it there isn't perfectly clean. It's hardly usable by other LLEXT users, it's almost SOF-specific, therefore it's been decided to mark it "experimental" until a proper universal solution replaces it.

CONFIG_MODULES=y
CONFIG_TIMING_FUNCTIONS=y
CONFIG_WATCHDOG=y
Expand Down
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace20_lnl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ CONFIG_COUNTER=y
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
CONFIG_MODULES=y
CONFIG_TIMING_FUNCTIONS=y

Expand Down
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace30_ptl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_L3_HEAP=y
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
CONFIG_MODULES=y

# Zephyr / device drivers
Expand Down
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace30_wcl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_L3_HEAP=y
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
CONFIG_MODULES=y

# Zephyr / device drivers
Expand Down
2 changes: 2 additions & 0 deletions posix/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ int rstrlen(const char *s);
*/
int rstrcmp(const char *s1, const char *s2);

static inline void l3_heap_save(void) {}

/** @}*/

#endif /* __SOF_LIB_ALLOC_H__ */
2 changes: 2 additions & 0 deletions src/include/ipc4/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ enum sof_ipc4_resource_type {
(((SOF_IPC4_NOTIFY_FW_READY) << (SOF_IPC4_GLB_NOTIFY_TYPE_SHIFT)) |\
((SOF_IPC4_GLB_NOTIFICATION) << (SOF_IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT)))

#define SOF_IPC4_FW_READY_LIB_RESTORED BIT(15)

#define SOF_IPC4_NOTIF_HEADER(notif_type) \
((notif_type) << (SOF_IPC4_GLB_NOTIFY_TYPE_SHIFT) | \
((SOF_IPC4_GLB_NOTIFICATION) << (SOF_IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT)))
Expand Down
7 changes: 3 additions & 4 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#if CONFIG_LIBRARY_AUTH_SUPPORT
#include <sof/auth_api_iface.h>
#endif
#include <sof/list.h>

#define LIB_MANAGER_MAX_LIBS 16
#define LIB_MANAGER_LIB_ID_SHIFT 12
Expand Down Expand Up @@ -125,11 +126,8 @@ struct ext_library {
struct ipc_lib_msg *lib_notif_pool;
uint32_t lib_notif_count;

/* Only needed from SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE to SOF_IPC4_GLB_LOAD_LIBRARY */
void *runtime_data;
#if CONFIG_LIBRARY_AUTH_SUPPORT
struct auth_api_ctx auth_ctx;
void *auth_buffer;
#endif
};

/* lib manager context, used by lib_notification */
Expand Down Expand Up @@ -187,6 +185,7 @@ int lib_manager_register_module(const uint32_t component_id);
const struct sof_man_fw_desc *lib_manager_get_library_manifest(int module_id);

struct processing_module;
struct comp_ipc_config;
/*
* \brief Allocate module
*
Expand Down
8 changes: 8 additions & 0 deletions src/include/sof/llext_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,12 @@ bool comp_is_llext(struct comp_dev *comp);
#define comp_is_llext(comp) false
#endif

#if CONFIG_LLEXT_EXPERIMENTAL && !CONFIG_ADSP_IMR_CONTEXT_SAVE
int llext_manager_store_to_dram(void);
int llext_manager_restore_from_dram(void);
#else
#define llext_manager_store_to_dram() 0
#define llext_manager_restore_from_dram() -ENOSYS
#endif

#endif
12 changes: 12 additions & 0 deletions src/ipc/ipc4/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <sof/lib/mailbox.h>
#include <sof/lib/memory.h>
#include <sof/lib/pm_runtime.h>
#include <sof/llext_manager.h>
#include <sof/math/numbers.h>
#include <sof/tlv.h>
#include <sof/trace/trace.h>
Expand Down Expand Up @@ -1485,6 +1486,17 @@ __cold static int ipc4_module_process_dx(struct ipc4_message_request *ipc4)
return IPC4_BUSY;
}

#if !CONFIG_ADSP_IMR_CONTEXT_SAVE
ret = llext_manager_store_to_dram();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this play with full CONTEXT_SAVE feature? If full SRAM is saved, then this is redundant, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, need to add that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any update here ?

if (ret < 0)
ipc_cmd_err(&ipc_tr, "Error %d saving LLEXT context. Resume might fail.",
ret);

#if CONFIG_L3_HEAP
l3_heap_save();
#endif
#endif

#if defined(CONFIG_PM)
ipc_get()->task_mask |= IPC_TASK_POWERDOWN;
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/library_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ if(CONFIG_LIBRARY_MANAGER)

if (CONFIG_MM_DRV AND CONFIG_LLEXT)
add_local_sources(sof llext_manager.c)
if(CONFIG_LLEXT_EXPERIMENTAL AND NOT CONFIG_ADSP_IMR_CONTEXT_SAVE)
add_local_sources_ifdef(CONFIG_L3_HEAP sof llext_manager_dram.c)
endif()
endif()
endif()
68 changes: 32 additions & 36 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

#if CONFIG_LIBRARY_AUTH_SUPPORT
#include <auth/intel_auth_api.h>
#else
struct auth_api_ctx;
#endif

#include <errno.h>
Expand All @@ -60,68 +62,59 @@ struct lib_manager_dma_ext {
static struct ext_library loader_ext_lib;

#if CONFIG_LIBRARY_AUTH_SUPPORT
static int lib_manager_auth_init(void)
static int lib_manager_auth_init(struct auth_api_ctx *auth_ctx, void **auth_buffer)
{
struct ext_library *ext_lib = ext_lib_get();
int ret;

if (auth_api_version().major != AUTH_API_VERSION_MAJOR)
return -EINVAL;

ext_lib->auth_buffer = rballoc_align(0, SOF_MEM_CAPS_RAM,
AUTH_SCRATCH_BUFF_SZ, CONFIG_MM_DRV_PAGE_SIZE);
if (!ext_lib->auth_buffer)
*auth_buffer = rballoc_align(0, SOF_MEM_CAPS_RAM,
AUTH_SCRATCH_BUFF_SZ, CONFIG_MM_DRV_PAGE_SIZE);
if (!*auth_buffer)
return -ENOMEM;

ret = auth_api_init(&ext_lib->auth_ctx, ext_lib->auth_buffer,
AUTH_SCRATCH_BUFF_SZ, IMG_TYPE_LIB);
ret = auth_api_init(auth_ctx, *auth_buffer, AUTH_SCRATCH_BUFF_SZ, IMG_TYPE_LIB);
if (ret != 0) {
tr_err(&lib_manager_tr, "auth_api_init() failed with error: %d", ret);
rfree(ext_lib->auth_buffer);
ret = -EACCES;
rfree(*auth_buffer);
return -EACCES;
}

return ret;
return 0;
}

static void lib_manager_auth_deinit(void)
static void lib_manager_auth_deinit(struct auth_api_ctx *auth_ctx, void *auth_buffer)
{
struct ext_library *ext_lib = ext_lib_get();

if (ext_lib->auth_buffer)
memset(ext_lib->auth_buffer, 0, AUTH_SCRATCH_BUFF_SZ);

rfree(ext_lib->auth_buffer);
ext_lib->auth_buffer = NULL;
memset(&ext_lib->auth_ctx, 0, sizeof(struct auth_api_ctx));
ARG_UNUSED(auth_ctx);
rfree(auth_buffer);
}

static int lib_manager_auth_proc(const void *buffer_data,
size_t buffer_size, enum auth_phase phase)
static int lib_manager_auth_proc(const void *buffer_data, size_t buffer_size,
enum auth_phase phase, struct auth_api_ctx *auth_ctx)
{
struct ext_library *ext_lib = ext_lib_get();
int ret;

ret = auth_api_init_auth_proc(&ext_lib->auth_ctx, buffer_data, buffer_size, phase);
ret = auth_api_init_auth_proc(auth_ctx, buffer_data, buffer_size, phase);

if (ret != 0) {
tr_err(&lib_manager_tr, "auth_api_init_auth_proc() failed with error: %d", ret);
return -ENOTSUP;
}

/* The auth_api_busy() will timeouts internally in case of failure */
while (auth_api_busy(&ext_lib->auth_ctx))
while (auth_api_busy(auth_ctx))
;

ret = auth_api_result(&ext_lib->auth_ctx);
ret = auth_api_result(auth_ctx);

if (ret != AUTH_IMAGE_TRUSTED) {
tr_err(&lib_manager_tr, "Untrusted library!");
return -EACCES;
}

if (phase == AUTH_PHASE_LAST)
auth_api_cleanup(&ext_lib->auth_ctx);
auth_api_cleanup(auth_ctx);

return 0;
}
Expand Down Expand Up @@ -819,7 +812,7 @@ 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,
const void __sparse_cache *man_buffer,
uint32_t lib_id)
uint32_t lib_id, struct auth_api_ctx *auth_ctx)
{
void __sparse_cache *library_base_address;
const struct sof_man_fw_desc *man_desc = (struct sof_man_fw_desc *)
Expand Down Expand Up @@ -850,7 +843,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 const void *)man_buffer,
MAN_MAX_SIZE_V1_8, AUTH_PHASE_FIRST);
MAN_MAX_SIZE_V1_8, AUTH_PHASE_FIRST, auth_ctx);
if (ret < 0) {
rfree((__sparse_force void *)library_base_address);
return ret;
Expand All @@ -872,7 +865,7 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext,
#if CONFIG_LIBRARY_AUTH_SUPPORT
/* AUTH_PHASE_LAST - do final library authentication checks */
ret = lib_manager_auth_proc((__sparse_force void *)library_base_address,
preload_size - MAN_MAX_SIZE_V1_8, AUTH_PHASE_LAST);
preload_size - MAN_MAX_SIZE_V1_8, AUTH_PHASE_LAST, auth_ctx);
if (ret < 0) {
rfree((__sparse_force void *)library_base_address);
return ret;
Expand Down Expand Up @@ -1003,16 +996,19 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type)
goto stop_dma;

#if CONFIG_LIBRARY_AUTH_SUPPORT
struct auth_api_ctx auth_ctx;
void *auth_buffer;

/* Initialize authentication support */
ret = lib_manager_auth_init();
ret = lib_manager_auth_init(&auth_ctx, &auth_buffer);
if (ret < 0)
goto stop_dma;
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */

ret = lib_manager_store_library(dma_ext, man_tmp_buffer, lib_id);
ret = lib_manager_store_library(dma_ext, man_tmp_buffer, lib_id, &auth_ctx);

#if CONFIG_LIBRARY_AUTH_SUPPORT
lib_manager_auth_deinit();
lib_manager_auth_deinit(&auth_ctx, auth_buffer);
#else
ret = lib_manager_store_library(dma_ext, man_tmp_buffer, lib_id, NULL);
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */

stop_dma:
Expand All @@ -1034,7 +1030,7 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type)
uint32_t module_id = lib_id << LIB_MANAGER_LIB_ID_SHIFT;
const struct sof_man_module *mod = lib_manager_get_module_manifest(module_id);

if (module_is_llext(mod) && !ret)
if (!ret && module_is_llext(mod))
/* Auxiliary LLEXT libraries need to be linked upon loading */
ret = llext_manager_add_library(module_id);

Expand All @@ -1043,7 +1039,7 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type)
#endif

if (!ret)
tr_info(&ipc_tr, "loaded library id: %u", lib_id);
tr_info(&lib_manager_tr, "loaded library id: %u", lib_id);

return ret;
}
8 changes: 6 additions & 2 deletions src/library_manager/llext_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,12 @@ static int llext_manager_load_data_from_storage(const struct llext_loader *ldr,
const elf_shdr_t *shdr;
enum llext_mem s_region = LLEXT_MEM_COUNT;
size_t s_offset = 0;
int ret = llext_get_section_info(ldr, ext, i, &shdr, &s_region, &s_offset);

llext_get_section_info(ldr, ext, i, &shdr, &s_region, &s_offset);
if (ret < 0) {
tr_err(lib_manager_tr, "no section info: %d", ret);
continue;
}

/* skip sections not in the requested region */
if (s_region != region)
Expand Down Expand Up @@ -528,7 +532,7 @@ static int llext_manager_link_single(uint32_t module_id, const struct sof_man_fw
sizeof(struct llext_buf_loader));
if (!mctx->ebl) {
tr_err(&lib_manager_tr, "loader alloc failed");
return 0;
return -ENOMEM;
}

uint8_t *dram_base = (uint8_t *)desc - SOF_MAN_ELF_TEXT_OFFSET;
Expand Down
Loading
Loading