]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
ALSA: hda: hdmi - fix kernel oops caused by invalid PCM idx
authorKai Vehmanen <kai.vehmanen@linux.intel.com>
Wed, 12 Aug 2020 05:58:19 +0000 (13:58 +0800)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Fri, 4 Sep 2020 19:30:12 +0000 (16:30 -0300)
BugLink: https://bugs.launchpad.net/bugs/1867704
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: https://github.com/thesofproject/linux/issues/1536
Fixes: 5398e94fb753 ALSA: hda - Add DP-MST support for NVIDIA codecs
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20191129143756.23941-1-kai.vehmanen@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
(cherry picked from commit 0c0fe9e6b95ce2e9e2c83bef5563cf223e849eda)
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-By: AceLan Kao <acelan.kao@canonical.com>
Signed-off-by: Kelsey Skunberg <kelsey.skunberg@canonical.com>
sound/pci/hda/patch_hdmi.c

index 30ede7e7011dacfde22c4f8a04428d78359a8b40..2051bfaa19bbf03fdcabaef7cc94d545d42b0992 100644 (file)
@@ -1363,24 +1363,24 @@ static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
        int i;
 
        /*
-        * generic_hdmi_build_pcms() allocates (num_nids + dev_num - 1)
-        * number of pcms.
+        * generic_hdmi_build_pcms() may allocate extra PCMs on some
+        * platforms (with maximum of 'num_nids + dev_num - 1')
         *
         * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n
         * if m==0. This guarantees that dynamic pcm assignments are compatible
-        * with the legacy static per_pin-pmc assignment that existed in the
+        * with the legacy static per_pin-pcm assignment that existed in the
         * days before DP-MST.
         *
         * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)).
         */
-       if (per_pin->dev_id == 0 &&
-           !test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
-               return per_pin->pin_nid_idx;
-
-       if (per_pin->dev_id != 0 &&
-           !(test_bit(spec->num_nids + (per_pin->dev_id - 1),
-               &spec->pcm_bitmap))) {
-               return spec->num_nids + (per_pin->dev_id - 1);
+
+       if (per_pin->dev_id == 0) {
+               if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
+                       return per_pin->pin_nid_idx;
+       } else {
+               i = spec->num_nids + (per_pin->dev_id - 1);
+               if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap)))
+                       return i;
        }
 
        /* have a second try; check the area over num_nids */