diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index c64a650e0b38..fdcc5d3c3af9 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -70,6 +70,8 @@ static struct k_heap *module_adapter_dp_heap_new(const struct comp_ipc_config *c void *mod_heap_buf = mod_heap_mem + heap_prefix_size; k_heap_init(mod_heap, mod_heap_buf, heap_size - heap_prefix_size); + mod_heap->heap.init_mem = mod_heap_buf; + mod_heap->heap.init_bytes = heap_size - heap_prefix_size; return mod_heap; } diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index 0fac007cfe36..55b8dc9e4f40 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -152,6 +152,8 @@ static inline int comp_trigger_local(struct comp_dev *dev, int cmd) int ret; ret = dev->drv->ops.trigger(dev, cmd); + if (ret) + return ret; /* start a thread in case of shared component or DP scheduling */ if (dev->task) { @@ -159,7 +161,7 @@ static inline int comp_trigger_local(struct comp_dev *dev, int cmd) switch (cmd) { case COMP_TRIGGER_START: case COMP_TRIGGER_RELEASE: - schedule_task(dev->task, 0, dev->period); + ret = schedule_task(dev->task, 0, dev->period); break; case COMP_TRIGGER_XRUN: case COMP_TRIGGER_PAUSE: diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 3aee3b69313f..700aa96944f6 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -613,7 +613,7 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) audio_buffer_is_shared(&buffer->audio_buffer), buf_get_id(buffer)); if (!ring_buffer) - goto free; + goto free_unlocked; /* data destination module needs to use ring_buffer */ audio_buffer_attach_secondary_buffer(&buffer->audio_buffer, dp_on_source, @@ -698,6 +698,7 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) pipeline_disconnect(source, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); free: ll_unblock(cross_core_bind, flags); +free_unlocked: buffer_free(buffer); return IPC4_INVALID_RESOURCE_STATE; } diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index c93ffcd80dab..55be90d8208c 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -155,6 +155,25 @@ extern char _end[], _heap_sentry[]; static struct k_heap sof_heap; +/** + * Checks whether pointer is from a given heap memory. + * @param heap Pointer to a heap. + * @param ptr Pointer to memory being checked. + * @return True if pointer falls into heap memory region, false otherwise. + */ +static bool is_heap_pointer(const struct k_heap *heap, void *ptr) +{ + uintptr_t heap_start = + POINTER_TO_UINT(sys_cache_cached_ptr_get(heap->heap.init_mem)); + uintptr_t heap_end = heap_start + heap->heap.init_bytes; + + if (!is_cached(ptr)) + ptr = (__sparse_force void *)sys_cache_cached_ptr_get(ptr); + + return ((POINTER_TO_UINT(ptr) >= heap_start) && + (POINTER_TO_UINT(ptr) < heap_end)); +} + #if CONFIG_SOF_USERSPACE_USE_SHARED_HEAP static struct k_heap shared_buffer_heap; @@ -628,7 +647,7 @@ EXPORT_SYMBOL(rfree); void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, size_t alignment) { - if (flags & SOF_MEM_FLAG_LARGE_BUFFER) + if (flags & (SOF_MEM_FLAG_LARGE_BUFFER | SOF_MEM_FLAG_USER_SHARED_BUFFER)) return rballoc_align(flags, bytes, alignment); if (!heap) @@ -642,7 +661,7 @@ void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, void sof_heap_free(struct k_heap *heap, void *addr) { - if (heap && addr) + if (heap && addr && is_heap_pointer(heap, addr)) heap_free(heap, addr); else rfree(addr);