From c7f80847e76cc153d4f3b32244ed4888f67bca48 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 6 Aug 2026 20:31:13 +0300 Subject: [PATCH 1/2] vregion: allocate metadata with coherent memory for cross-core access The vregion metadata struct (containing the interim k_heap) is allocated from cached memory with rmalloc(0, ...). When a DP module on core 1 has its interim heap initialized during pipeline_complete, the k_heap data (including the sys_heap.heap pointer) is written to core 1's cache. If the IPC handler on core 0 later reads this data during a cross-core buffer bind, it gets stale/garbage values from main memory, causing a crash (EXCCAUSE 13: LoadStorePIFDataError) when the garbage pointer is dereferenced. Fix by allocating vregion metadata with SOF_MEM_FLAG_COHERENT so writes are immediately visible to all cores. Signed-off-by: Jyri Sarha --- zephyr/lib/vregion.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/zephyr/lib/vregion.c b/zephyr/lib/vregion.c index 9c8c94c23f97..210f2940a2cb 100644 --- a/zephyr/lib/vregion.c +++ b/zephyr/lib/vregion.c @@ -127,8 +127,11 @@ struct vregion *vregion_create(size_t memsize) */ total_size = ALIGN_UP(memsize, CONFIG_MM_DRV_PAGE_SIZE); - /* allocate vregion metadata separately to keep it inaccessible to the user */ - vr = rmalloc(0, sizeof(*vr)); + /* allocate vregion metadata separately to keep it inaccessible to the user. + * Use coherent memory so interim heap state written on one core is + * visible to other cores during cross-core buffer allocation. + */ + vr = rmalloc(SOF_MEM_FLAG_COHERENT, sizeof(*vr)); if (!vr) return NULL; From 8e90e0e606b61a102be22e8288b7679f03a31b36 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 6 Aug 2026 23:00:48 +0300 Subject: [PATCH 2/2] vregion: flush interim heap buffer after init for cross-core access interim_heap_init() runs on one core (e.g. core 2 during pipeline_complete) and writes the k_heap/sys_heap/z_heap metadata to the vregion's page-allocated buffer. This buffer is in cached memory. When a different core (e.g. core 1) later tries to allocate from the interim heap, it reads stale data from its own cache, causing the allocation to fail despite sufficient space being available. Add sys_cache_data_flush_range() after k_heap_init() to flush the heap metadata to main memory so all cores see the initialized state. Signed-off-by: Jyri Sarha --- zephyr/lib/vregion.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zephyr/lib/vregion.c b/zephyr/lib/vregion.c index 210f2940a2cb..4cc2437fcec4 100644 --- a/zephyr/lib/vregion.c +++ b/zephyr/lib/vregion.c @@ -257,6 +257,11 @@ static void interim_heap_init(struct vregion *vr) k_heap_init(&vr->interim.heap, interim_base, interim_size); vr->type = VREGION_MEM_TYPE_INTERIM; + /* Flush the heap metadata written by k_heap_init to main memory + * so other cores can access the interim heap without stale cache. + */ + sys_cache_data_flush_range(interim_base, interim_size); + /* Update lifetime heap with the interim heap usage. */ vr->lifetime.ptr = (void *)(interim_base + interim_size); vr->lifetime.used = (uint8_t *)vr->lifetime.ptr - (uint8_t *)vr->lifetime.base;