ASoC: amd: acp: SoundWire machine driver fixes

Vijendar Mukunda <Vijendar.Mukunda@amd.com> says:

This series fixes four defects in the AMD ACP SoundWire machine drivers
(acp-sdw-legacy-mach.c and acp-sdw-sof-mach.c).

A bounds check is added to validate the SoundWire link ID before it is
used as an array index in create_sdw_dailink(), preventing out-of-bounds
access when an unexpected link_mask value is encountered. The codec
config count in the SOF machine driver is refactored to use a dedicated
variable rather than reusing the endpoint-count variable for two
purposes, making the intent clearer and avoiding a stale value being
passed to the codec config array. An operator-precedence bug in the
ffs(link_mask - 1) expression is corrected to ffs(link_mask) - 1,
ensuring the link ID is derived from the correct bit position. Finally,
the SOF machine driver card name is shortened to fit within the 16-byte
snd_card driver[] field and eliminate a compile-time warning.

Link: https://patch.msgid.link/20260910161728.1452808-1-Vijendar.Mukunda@amd.com
This commit is contained in:
Mark Brown 2026-09-16 20:08:20 +01:00
commit fa899ba9b1
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 29 additions and 8 deletions

View File

@ -205,9 +205,19 @@ static int create_sdw_dailink(struct snd_soc_card *card,
return -EINVAL;
}
if (!soc_end->link_mask) {
dev_err(dev, "invalid zero link_mask\n");
return -EINVAL;
}
if ((ffs(soc_end->link_mask) - 1) >= amd_ctx->max_sdw_links) {
dev_err(dev, "link_id %d exceeds max_sdw_links %d\n",
ffs(soc_end->link_mask) - 1, amd_ctx->max_sdw_links);
return -EINVAL;
}
switch (amd_ctx->acp_rev) {
case ACP63_PCI_REV:
ret = get_acp63_cpu_pin_id(ffs(soc_end->link_mask - 1),
ret = get_acp63_cpu_pin_id(ffs(soc_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;
@ -215,7 +225,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
case ACP70_PCI_REV:
case ACP71_PCI_REV:
case ACP72_PCI_REV:
ret = get_acp70_cpu_pin_id(ffs(soc_end->link_mask - 1),
ret = get_acp70_cpu_pin_id(ffs(soc_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;

View File

@ -121,9 +121,18 @@ static int create_sdw_dailink(struct snd_soc_card *card,
return -EINVAL;
}
if (!sof_end->link_mask) {
dev_err(dev, "invalid zero link_mask\n");
return -EINVAL;
}
if ((ffs(sof_end->link_mask) - 1) >= amd_ctx->max_sdw_links) {
dev_err(dev, "link_id %d exceeds max_sdw_links %d\n",
ffs(sof_end->link_mask) - 1, amd_ctx->max_sdw_links);
return -EINVAL;
}
switch (amd_ctx->acp_rev) {
case ACP63_PCI_REV:
ret = get_acp63_cpu_pin_id(ffs(sof_end->link_mask - 1),
ret = get_acp63_cpu_pin_id(ffs(sof_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;
@ -131,7 +140,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
case ACP70_PCI_REV:
case ACP71_PCI_REV:
case ACP72_PCI_REV:
ret = get_acp70_cpu_pin_id(ffs(sof_end->link_mask - 1),
ret = get_acp70_cpu_pin_id(ffs(sof_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;
@ -277,6 +286,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
int num_devs = 0;
int num_ends = 0;
int num_aux = 0;
int num_confs;
int num_links;
int be_id = 0;
int ret;
@ -287,6 +297,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
return ret;
}
num_confs = num_ends;
/* One per DAI link, worst case is a DAI link for every endpoint */
struct asoc_sdw_dailink *sof_dais __free(kfree) =
kzalloc_objs(*sof_dais, num_ends);
@ -303,7 +314,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
if (!sof_aux)
return -ENOMEM;
ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_devs);
ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_confs);
if (ret < 0)
return ret;
@ -315,7 +326,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num);
codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL);
if (!codec_conf)
return -ENOMEM;
@ -326,7 +337,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
return -ENOMEM;
card->codec_conf = codec_conf;
card->num_configs = num_devs;
card->num_configs = num_confs;
card->dai_link = dai_links;
card->num_links = num_links;
card->aux_dev = sof_aux;
@ -379,7 +390,7 @@ static int mc_probe(struct platform_device *pdev)
ctx->private = amd_ctx;
card = &ctx->card;
card->dev = &pdev->dev;
card->name = "amd-soundwire";
card->name = "amd-sdw";
card->owner = THIS_MODULE;
card->late_probe = asoc_sdw_card_late_probe;