Skip to content

Commit e89c0e2

Browse files
lyakhlgirdwood
authored andcommitted
llext: add a function to remove a memory domain
When a LLEXT module is freed, its partitions should be removed from any memory domains. Add a function for that. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 9567234 commit e89c0e2

2 files changed

Lines changed: 78 additions & 6 deletions

File tree

src/include/sof/llext_manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ int llext_manager_free_module(const uint32_t component_id);
3131
int llext_manager_add_library(uint32_t module_id);
3232

3333
int llext_manager_add_domain(const uint32_t component_id, struct k_mem_domain *domain);
34+
int llext_manager_rm_domain(const uint32_t component_id, struct k_mem_domain *domain);
3435

3536
bool comp_is_llext(struct comp_dev *comp);
3637
#else

src/library_manager/llext_manager.c

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ static int llext_manager_load_module(struct lib_manager_module *mctx)
287287
return 0;
288288

289289
e_rodata:
290-
llext_manager_align_unmap(va_base_rodata, rodata_size);
290+
if (rodata_size)
291+
llext_manager_align_unmap(va_base_rodata, rodata_size);
291292
e_text:
292293
llext_manager_align_unmap(va_base_text, text_size);
293294

@@ -733,14 +734,28 @@ static int llext_manager_add_partition(struct k_mem_domain *domain,
733734
return k_mem_domain_add_partition(domain, &part);
734735
}
735736

737+
static int llext_manager_rm_partition(struct k_mem_domain *domain,
738+
uintptr_t addr, size_t size,
739+
k_mem_partition_attr_t attr)
740+
{
741+
size_t pre_pad_size = addr & (PAGE_SZ - 1);
742+
struct k_mem_partition part = {
743+
.start = addr - pre_pad_size,
744+
.size = ALIGN_UP(pre_pad_size + size, PAGE_SZ),
745+
.attr = attr,
746+
};
747+
748+
tr_dbg(&lib_manager_tr, "remove %#zx @ %lx partition", part.size, part.start);
749+
return k_mem_domain_remove_partition(domain, &part);
750+
}
751+
736752
int llext_manager_add_domain(const uint32_t component_id, struct k_mem_domain *domain)
737753
{
738754
const uint32_t module_id = IPC4_MOD_ID(component_id);
739755
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
740756
const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
741757
const unsigned int mod_idx = llext_manager_mod_find(ctx, entry_index);
742758
struct lib_manager_module *mctx = ctx->mod + mod_idx;
743-
int ret;
744759

745760
/* Executable code (.text) */
746761
uintptr_t va_base_text = mctx->segment[LIB_MANAGER_TEXT].addr;
@@ -754,26 +769,82 @@ int llext_manager_add_domain(const uint32_t component_id, struct k_mem_domain *d
754769
uintptr_t va_base_data = mctx->segment[LIB_MANAGER_DATA].addr;
755770
size_t data_size = mctx->segment[LIB_MANAGER_DATA].size;
756771

757-
ret = llext_manager_add_partition(domain, va_base_text, text_size,
758-
K_MEM_PARTITION_P_RX_U_RX);
772+
int ret = llext_manager_add_partition(domain, va_base_text, text_size,
773+
K_MEM_PARTITION_P_RX_U_RX);
774+
759775
if (ret < 0)
760776
return ret;
761777

762778
if (rodata_size) {
763779
ret = llext_manager_add_partition(domain, va_base_rodata, rodata_size,
764780
K_MEM_PARTITION_P_RO_U_RO);
765781
if (ret < 0)
766-
return ret;
782+
goto e_text;
767783
}
768784

769785
if (data_size) {
770786
ret = llext_manager_add_partition(domain, va_base_data, data_size,
771787
K_MEM_PARTITION_P_RW_U_RW);
772788
if (ret < 0)
773-
return ret;
789+
goto e_rodata;
774790
}
775791

776792
return 0;
793+
e_rodata:
794+
llext_manager_rm_partition(domain, va_base_rodata, rodata_size, K_MEM_PARTITION_P_RO_U_RO);
795+
e_text:
796+
llext_manager_rm_partition(domain, va_base_text, text_size, K_MEM_PARTITION_P_RX_U_RX);
797+
return ret;
798+
}
799+
800+
int llext_manager_rm_domain(const uint32_t component_id, struct k_mem_domain *domain)
801+
{
802+
const uint32_t module_id = IPC4_MOD_ID(component_id);
803+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
804+
const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
805+
const unsigned int mod_idx = llext_manager_mod_find(ctx, entry_index);
806+
struct lib_manager_module *mctx = ctx->mod + mod_idx;
807+
808+
/* Executable code (.text) */
809+
uintptr_t va_base_text = mctx->segment[LIB_MANAGER_TEXT].addr;
810+
size_t text_size = mctx->segment[LIB_MANAGER_TEXT].size;
811+
812+
/* Read-only data (.rodata and others) */
813+
uintptr_t va_base_rodata = mctx->segment[LIB_MANAGER_RODATA].addr;
814+
size_t rodata_size = mctx->segment[LIB_MANAGER_RODATA].size;
815+
816+
/* Writable data (.data, .bss and others) */
817+
uintptr_t va_base_data = mctx->segment[LIB_MANAGER_DATA].addr;
818+
size_t data_size = mctx->segment[LIB_MANAGER_DATA].size;
819+
820+
int err, ret = llext_manager_rm_partition(domain, va_base_text, text_size,
821+
K_MEM_PARTITION_P_RX_U_RX);
822+
823+
if (ret < 0)
824+
tr_err(&lib_manager_tr, "failed to remove .text memory partition: %d", ret);
825+
826+
if (rodata_size) {
827+
err = llext_manager_rm_partition(domain, va_base_rodata, rodata_size,
828+
K_MEM_PARTITION_P_RO_U_RO);
829+
if (err < 0) {
830+
tr_err(&lib_manager_tr, "failed to remove .rodata memory partition: %d",
831+
err);
832+
if (!ret)
833+
ret = err;
834+
}
835+
}
836+
837+
if (data_size) {
838+
err = llext_manager_rm_partition(domain, va_base_data, data_size,
839+
K_MEM_PARTITION_P_RW_U_RW);
840+
if (err < 0) {
841+
tr_err(&lib_manager_tr, "failed to remove .data memory partition: %d", err);
842+
if (!ret)
843+
ret = err;
844+
}
845+
}
846+
847+
return ret;
777848
}
778849
#endif
779850

0 commit comments

Comments
 (0)