@@ -423,6 +423,44 @@ __cold const struct ipc4_pipeline_set_state_data *ipc4_get_pipeline_data_wrapper
423423 return ipc4_get_pipeline_data ();
424424}
425425
426+ static int ipc4_pipeline_id_get (struct ipc4_message_request * ipc4 ,
427+ struct ipc4_pipeline_set_state * state ,
428+ const uint32_t * * ppl_id , unsigned int * ppl_count )
429+ {
430+ if (!state -> extension .r .multi_ppl ) {
431+ if (ppl_count )
432+ * ppl_count = 1 ;
433+ if (ppl_id )
434+ * ppl_id = NULL ;
435+ return state -> primary .r .ppl_id ;
436+ }
437+
438+ const struct ipc4_pipeline_set_state_data * ppl_data = ipc4_get_pipeline_data ();
439+ unsigned int cnt = ppl_data -> pipelines_count ;
440+
441+ /*
442+ * pipelines_count is read straight from the host-provided
443+ * mailbox payload, so cap it at what the mailbox can
444+ * physically hold. Anything larger means the host promised
445+ * more ppl_id[] entries than fit in MAILBOX_HOSTBOX, and
446+ * dereferencing the flex array would read out of bounds.
447+ */
448+ if (cnt > (MAILBOX_HOSTBOX_SIZE - sizeof (struct ipc4_pipeline_set_state_data )) /
449+ sizeof (uint32_t )) {
450+ ipc_cmd_err (& ipc_tr , "ipc: pipelines_count %u exceeds mailbox bound" ,
451+ cnt );
452+ return - EINVAL ;
453+ }
454+ dcache_invalidate_region ((__sparse_force void __sparse_cache * )ppl_data -> ppl_id ,
455+ sizeof (int ) * cnt );
456+ if (ppl_count )
457+ * ppl_count = cnt ;
458+ if (ppl_id )
459+ * ppl_id = ppl_data -> ppl_id ;
460+
461+ return ppl_data -> ppl_id [0 ];
462+ }
463+
426464/**
427465 * \brief Process SET_PIPELINE_STATE IPC4 message (prepare + trigger phases).
428466 * @param[in] ipc4 IPC4 message request.
@@ -435,7 +473,7 @@ int ipc4_set_pipeline_state(struct ipc4_message_request *ipc4)
435473 struct ipc_comp_dev * ppl_icd ;
436474 struct ipc * ipc = ipc_get ();
437475 uint32_t cmd , ppl_count ;
438- uint32_t id = 0 ;
476+ int id ;
439477 const uint32_t * ppl_id ;
440478 bool use_idc = false;
441479 uint32_t idx ;
@@ -447,31 +485,12 @@ int ipc4_set_pipeline_state(struct ipc4_message_request *ipc4)
447485 cmd = state .primary .r .ppl_state ;
448486 ppl_data = ipc4_get_pipeline_data ();
449487
450- if (state .extension .r .multi_ppl ) {
451- ppl_count = ppl_data -> pipelines_count ;
452- /*
453- * pipelines_count is read straight from the host-provided
454- * mailbox payload, so cap it at what the mailbox can
455- * physically hold. Anything larger means the host promised
456- * more ppl_id[] entries than fit in MAILBOX_HOSTBOX, and
457- * dereferencing the flex array would read out of bounds.
458- */
459- if (ppl_count > (MAILBOX_HOSTBOX_SIZE -
460- sizeof (struct ipc4_pipeline_set_state_data )) /
461- sizeof (uint32_t )) {
462- ipc_cmd_err (& ipc_tr ,
463- "ipc: pipelines_count %u exceeds mailbox bound" ,
464- ppl_count );
465- return IPC4_ERROR_INVALID_PARAM ;
466- }
467- ppl_id = ppl_data -> ppl_id ;
468- dcache_invalidate_region ((__sparse_force void __sparse_cache * )ppl_id ,
469- sizeof (int ) * ppl_count );
470- } else {
471- ppl_count = 1 ;
472- id = state .primary .r .ppl_id ;
488+ id = ipc4_pipeline_id_get (ipc4 , & state , & ppl_id , & ppl_count );
489+ if (id < 0 )
490+ return IPC4_ERROR_INVALID_PARAM ;
491+
492+ if (ppl_count == 1 )
473493 ppl_id = & id ;
474- }
475494
476495 for (i = 0 ; i < ppl_count ; i ++ ) {
477496 ppl_icd = ipc_get_comp_by_ppl_id (ipc , COMP_TYPE_PIPELINE ,
0 commit comments