Skip to content

Commit 0c0fe9e

Browse files
kv2019itiwai
authored andcommitted
ALSA: hda: hdmi - fix kernel oops caused by invalid PCM idx
Add additional check in hdmi_find_pcm_slot() to not return a pcm index that points to unallocated pcm. This could happen if codec driver is set up in codec->mst_no_extra_pcms mode. On some platforms, this leads to a kernel oops in snd_ctl_notify(), called via update_eld(). BugLink: thesofproject#1536 Fixes: 5398e94 ALSA: hda - Add DP-MST support for NVIDIA codecs Signed-off-by: Kai Vehmanen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 336820c commit 0c0fe9e

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

sound/pci/hda/patch_hdmi.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,24 +1335,24 @@ static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
13351335
int i;
13361336

13371337
/*
1338-
* generic_hdmi_build_pcms() allocates (num_nids + dev_num - 1)
1339-
* number of pcms.
1338+
* generic_hdmi_build_pcms() may allocate extra PCMs on some
1339+
* platforms (with maximum of 'num_nids + dev_num - 1')
13401340
*
13411341
* The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n
13421342
* if m==0. This guarantees that dynamic pcm assignments are compatible
1343-
* with the legacy static per_pin-pmc assignment that existed in the
1343+
* with the legacy static per_pin-pcm assignment that existed in the
13441344
* days before DP-MST.
13451345
*
13461346
* per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)).
13471347
*/
1348-
if (per_pin->dev_id == 0 &&
1349-
!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
1350-
return per_pin->pin_nid_idx;
1351-
1352-
if (per_pin->dev_id != 0 &&
1353-
!(test_bit(spec->num_nids + (per_pin->dev_id - 1),
1354-
&spec->pcm_bitmap))) {
1355-
return spec->num_nids + (per_pin->dev_id - 1);
1348+
1349+
if (per_pin->dev_id == 0) {
1350+
if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
1351+
return per_pin->pin_nid_idx;
1352+
} else {
1353+
i = spec->num_nids + (per_pin->dev_id - 1);
1354+
if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap)))
1355+
return i;
13561356
}
13571357

13581358
/* have a second try; check the area over num_nids */

0 commit comments

Comments
 (0)