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
2 changes: 1 addition & 1 deletion src/audio/copier/copier.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ __cold static int copier_init(struct processing_module *mod)
if (node_id.dw != IPC4_INVALID_NODE_ID) {
/* A gateway copier wires itself into the pipeline graph, so it needs a
* valid parent pipeline (base FW modules using IPC4_INVALID_PIPELINE_ID
* are exempt in comp_new_ipc4()). Reject here to avoid a NULL deref.
* are exempt in ipc4_comp_new_config()). Reject here to avoid a NULL deref.
*/
if (!dev->pipeline) {
comp_err(dev, "gateway copier requires a valid parent pipeline");
Expand Down
60 changes: 41 additions & 19 deletions src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,36 @@ __cold static int ipc4_comp_new_config(struct comp_ipc_config *ipc_config,
return -EINVAL;
}

/* Reject a module naming a non-existent parent pipeline: otherwise
* dev->pipeline stays NULL and a later init path (e.g. the copier)
* dereferences it. IPC4_INVALID_PIPELINE_ID is exempt - it marks base FW
* modules with no parent pipeline. IPC_COMP_ALL: the pipeline may run on a
* different core than this module.
*/
if (ipc_config->pipeline_id != IPC4_INVALID_PIPELINE_ID) {
struct ipc_comp_dev *ppl = ipc_get_comp_by_ppl_id(ipc_get(), COMP_TYPE_PIPELINE,
ipc_config->pipeline_id,
IPC_COMP_ALL);

if (!ppl) {
tr_err(&ipc_tr, "comp 0x%x: parent pipeline %u does not exist", comp_id,
(uint32_t)ipc_config->pipeline_id);
return -EINVAL;
}

/* Without cross-core streams a stream is processed entirely on a
* single core, so a module cannot live on another core than its
* pipeline.
*/
if (!IS_ENABLED(CONFIG_CROSS_CORE_STREAM) && ppl->core != ipc_config->core) {
tr_err(&ipc_tr,
"comp 0x%x: core %u != pipeline %u core %u, cross-core disabled",
comp_id, (uint32_t)ipc_config->core,
(uint32_t)ipc_config->pipeline_id, (uint32_t)ppl->core);
return -EINVAL;
}
}

return 0;
}

Expand All @@ -170,20 +200,6 @@ __cold struct comp_dev *comp_new_ipc4(const struct ipc4_module_init_instance *mo
if (ret < 0)
return NULL;

/* Reject a module naming a non-existent parent pipeline: otherwise
* dev->pipeline stays NULL and a later init path (e.g. the copier)
* dereferences it. IPC4_INVALID_PIPELINE_ID is exempt - it marks base FW
* modules with no parent pipeline. IPC_COMP_ALL: the pipeline may run on a
* different core than this module.
*/
if (ipc_config.pipeline_id != IPC4_INVALID_PIPELINE_ID &&
!ipc_get_comp_by_ppl_id(ipc_get(), COMP_TYPE_PIPELINE, ipc_config.pipeline_id,
IPC_COMP_ALL)) {
tr_err(&ipc_tr, "comp 0x%x: parent pipeline %u does not exist", comp_id,
(uint32_t)ipc_config.pipeline_id);
return NULL;
}

#ifdef CONFIG_DCACHE_LINE_SIZE
if (!IS_ENABLED(CONFIG_LIBRARY))
sys_cache_data_invd_range((__sparse_force void __sparse_cache *)
Expand Down Expand Up @@ -846,6 +862,15 @@ __cold int ipc4_comp_connect(struct ipc *ipc, const struct ipc4_module_bind_unbi
#endif
bool cross_core_bind = source->ipc_config.core != sink->ipc_config.core;

#if !CONFIG_CROSS_CORE_STREAM
/* reject early: the remote attribute/bind calls below are privileged */
if (cross_core_bind) {
tr_err(&ipc_tr, "Cross-core binding is disabled: can't bind %x to %x",
src_id, sink_id);
return IPC4_INVALID_REQUEST;
}
#endif

/* If both components are on same core -- process IPC on that core,
* otherwise stay on core 0
*/
Expand Down Expand Up @@ -976,20 +1001,17 @@ __cold int ipc4_comp_connect(struct ipc *ipc, const struct ipc4_module_bind_unbi
*/
ll_block(source->ipc_config.core, sink->ipc_config.core, flags);

if (cross_core_bind) {
#if CONFIG_CROSS_CORE_STREAM
if (cross_core_bind) {
/* Make sure LL has finished on both cores */
if (!cpu_is_me(source->ipc_config.core))
if (ll_wait_finished_on_core(source) < 0)
goto free;
if (!cpu_is_me(sink->ipc_config.core))
if (ll_wait_finished_on_core(sink) < 0)
goto free;
#else
tr_err(&ipc_tr, "Cross-core binding is disabled");
goto free;
#endif
}
#endif

ret = comp_buffer_connect(source, source->ipc_config.core, buffer,
PPL_CONN_DIR_COMP_TO_BUFFER);
Expand Down
Loading