mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
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:
commit
fa899ba9b1
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user