@@ -276,6 +276,23 @@ static int userspace_proxy_memory_init(struct userspace_context *user_ctx,
276276 tr_dbg (& userspace_proxy_tr , "Heap partition %#lx + %zx, attr = %u" ,
277277 heap_part .start , heap_part .size , heap_part .attr );
278278
279+ /* When a new memory domain is created, only the "factory" entries from the L2 page
280+ * tables are copied. Memory that was dynamically mapped during firmware execution
281+ * will not be accessible from the new domain. The k_heap structure (drv->user_heap)
282+ * resides in such dynamically mapped memory, so we must explicitly add a partition
283+ * for it to ensure that syscalls can access this structure from the userspace domain.
284+ */
285+ struct k_mem_partition heap_struct_part ;
286+
287+ k_mem_region_align (& heap_struct_part .start , & heap_struct_part .size ,
288+ POINTER_TO_UINT (drv -> user_heap ),
289+ sizeof (* drv -> user_heap ), CONFIG_MM_DRV_PAGE_SIZE );
290+ heap_struct_part .attr = K_MEM_PARTITION_P_RW_U_NA |
291+ user_get_partition_attr (heap_struct_part .start ) | XTENSA_MMU_PERM_W ;
292+
293+ tr_err (& userspace_proxy_tr , "Heap struct partition %#lx + %zx, attr = %u" ,
294+ heap_struct_part .start , heap_struct_part .size , heap_struct_part .attr );
295+
279296#if defined(CONFIG_SOF_ZEPHYR_HEAP_CACHED )
280297 /* Add cached module private heap to memory partitions */
281298 struct k_mem_partition heap_cached_part = {
@@ -298,7 +315,8 @@ static int userspace_proxy_memory_init(struct userspace_context *user_ctx,
298315#ifdef CONFIG_SOF_ZEPHYR_HEAP_CACHED
299316 & heap_cached_part ,
300317#endif
301- & heap_part
318+ & heap_part ,
319+ & heap_struct_part
302320 };
303321
304322 tr_dbg (& userspace_proxy_tr , "Common partition %#lx + %zx, attr = %u" ,
0 commit comments