From a787330e23645703079e8a73d83f3675b11e481c Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Wed, 18 Feb 2026 15:13:07 +0100 Subject: [PATCH 1/2] dai-zephyr: zero unused dai_config members This prevents initializing unused members of struct dai_config with random garbage from the stack. In case some Zephyr DAI driver uses such an uninitialized member, it's better to have a bug with stable reproduction than a random one. Signed-off-by: Serhiy Katsyuba --- src/audio/dai-zephyr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index e653e93ae082..a082e8c40650 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -145,7 +145,7 @@ __cold int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, { const struct device *dev = dai->dev; const struct sof_ipc_dai_config *sof_cfg = spec_config; - struct dai_config cfg; + struct dai_config cfg = {0}; const void *cfg_params; bool is_blob; From 6ac499786bf47eba6c53f027a080a5208251d9bd Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Wed, 18 Feb 2026 17:59:33 +0100 Subject: [PATCH 2/2] ipc4: dai: fix DMIC DMA link setup There are two problems with out_fmt: (1) Audio format for gateway DMA data is sent either in copier's base.audio_fmt or out_fmt depending on gateway direction. DMIC is a capture gateway and its input pin format should be used to set up DMA link. UAOL gateway (coming soon) can be either capture or playback, hence the direction check is used. (2) The copier pointer in copier_dai_create() points to IPC memory window contents. However, out_fmt (now gtw_fmt) is also used when DAIs are resumed after exiting D3 state. So cd->config (a copy of ipc4_copier_module_cfg that is kept allocated throughout the copier module lifetime) is used to get the address of the audio format struct. Signed-off-by: Serhiy Katsyuba --- src/audio/copier/copier_dai.c | 4 ++-- src/include/sof/audio/ipc-config.h | 2 +- src/ipc/ipc4/dai.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/audio/copier/copier_dai.c b/src/audio/copier/copier_dai.c index 821aa59d7640..ceb93b2a22bf 100644 --- a/src/audio/copier/copier_dai.c +++ b/src/audio/copier/copier_dai.c @@ -285,6 +285,8 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, dai.is_config_blob = true; dai.sampling_frequency = copier->out_fmt.sampling_frequency; dai.feature_mask = copier->copier_feature_mask; + dai.gtw_fmt = (dai.direction == SOF_IPC_STREAM_PLAYBACK) ? + &cd->config.out_fmt : &cd->config.base.audio_fmt; switch (node_id.f.dma_type) { case ipc4_hda_link_output_class: @@ -303,7 +305,6 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, comp_err(dev, "No ssp dma_config found in blob!"); return -EINVAL; } - dai.out_fmt = &copier->out_fmt; break; case ipc4_alh_link_output_class: case ipc4_alh_link_input_class: @@ -330,7 +331,6 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, comp_err(dev, "No dmic dma_config found in blob!"); return -EINVAL; } - dai.out_fmt = &copier->out_fmt; #if CONFIG_COPIER_GAIN dai.apply_gain = true; #endif diff --git a/src/include/sof/audio/ipc-config.h b/src/include/sof/audio/ipc-config.h index 49dbb9eac217..1eb6b9cca555 100644 --- a/src/include/sof/audio/ipc-config.h +++ b/src/include/sof/audio/ipc-config.h @@ -77,7 +77,7 @@ struct ipc_config_dai { */ /**< DMA configs - required for ACE 2.0 and newer */ struct ipc_dma_config *host_dma_config[GTW_DMA_DEVICE_MAX_COUNT]; - const struct ipc4_audio_format *out_fmt;/**< audio format for output pin 0 - required + const struct ipc4_audio_format *gtw_fmt;/**< audio format for gateway DMA data - required * for ACE 2.0 and newer */ /* Gain feature flag */ diff --git a/src/ipc/ipc4/dai.c b/src/ipc/ipc4/dai.c index dd55236f0917..9f63fd4196f7 100644 --- a/src/ipc/ipc4/dai.c +++ b/src/ipc/ipc4/dai.c @@ -38,7 +38,7 @@ void dai_set_link_hda_config(uint16_t *link_config, const void *spec_config) { #if ACE_VERSION > ACE_VERSION_1_5 - const struct ipc4_audio_format *out_fmt = common_config->out_fmt; + const struct ipc4_audio_format *gtw_fmt = common_config->gtw_fmt; union hdalink_cfg link_cfg; switch (common_config->type) { @@ -49,14 +49,14 @@ void dai_set_link_hda_config(uint16_t *link_config, break; case SOF_DAI_INTEL_DMIC: link_cfg.full = 0; - if (out_fmt->depth == IPC4_DEPTH_16BIT) { + if (gtw_fmt->depth == IPC4_DEPTH_16BIT) { /* 16bit dmic packs two 16bit samples into single 32bit word * fw needs to adjust channel count to match final sample * group size */ - link_cfg.part.hchan = (out_fmt->channels_count - 1) / 2; + link_cfg.part.hchan = (gtw_fmt->channels_count - 1) / 2; } else { - link_cfg.part.hchan = out_fmt->channels_count - 1; + link_cfg.part.hchan = gtw_fmt->channels_count - 1; } link_cfg.part.stream = common_config->host_dma_config[0]->stream_id; break;