CHROMIUM: ASoC: Intel: Fix audio crash due to race condition
 in stream deletion

Panic log:

<5>[  170.571367] general protection fault: 0000 [#1] SMP
<0>[  170.574565] gsmi: Log Shutdown Reason 0x03
<5>[  170.574610] Modules linked in: i2c_dev snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_soc_sst_byt_max98090_mach dptf_acpi esif_lf_driver snd_soc_sst_baytrail_pcm snd_soc_sst_dsp memconsole snd_soc_max98090 snd_hwdep snd_soc_sst_acpi zram(C) fuse nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables iwlmvm iwl7000_mac80211 iwlwifi cfg80211 btusb bluetooth uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev joydev
<5>[  170.576243] CPU: 1 PID: 1689 Comm: irq/29-AudioDSP Tainted: G         C   3.10.18 #1
<5>[  170.576293] Hardware name: GOOGLE Clapper, BIOS Google_Clapper.5216.171.0 04/14/2014
<5>[  170.576346] task: ffff8800714142f0 ti: ffff88005a0da000 task.ti: ffff88005a0da000
<5>[  170.576395] RIP: 0010:[<ffffffffc01cbb62>]  [<ffffffffc01cbb62>] sst_byt_dsp_suspend_noirq+0x13b/0x378 [snd_soc_sst_baytrail_pcm]
<5>[  170.576500] RSP: 0018:ffff88005a0dbdc8  EFLAGS: 00010093
<5>[  170.576546] RAX: 0000000000000001 RBX: ffff880065d8b628 RCX: ffff88005ab36638
<5>[  170.576597] RDX: dead000000100100 RSI: 0000000000000040 RDI: ffffc90021940000
<5>[  170.576646] RBP: ffff88005a0dbdf8 R08: ffff88005a0da000 R09: 0000000000000000
<5>[  170.576695] R10: 0000000006db4000 R11: ffff88007ac92d88 R12: ffff88005ab36628
<5>[  170.576744] R13: ffff880065d8b628 R14: 0000000000000246 R15: ffff880065d8b630
<5>[  170.576796] FS:  0000000000000000(0000) GS:ffff88007ac80000(0000) knlGS:0000000000000000
<5>[  170.576845] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
<5>[  170.576890] CR2: 00003a50450da000 CR3: 0000000072138000 CR4: 00000000001007e0
<5>[  170.576941] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
<5>[  170.576990] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
<5>[  170.577036] Stack:
<5>[  170.577080]  ffff880071414758 ffff88005b912600 ffff88007839a000 ffff8800714142f0
<5>[  170.577324]  ffffffff96887a41 ffff8800714142f0 ffff88005a0dbe20 ffffffff96887a5e
<5>[  170.577569]  ffff88005b912600 ffff88005b912600 ffff88007839a000 ffff88005a0dbe98
<5>[  170.577816] Call Trace:
<5>[  170.577888]  [<ffffffff96887a41>] ? free_irq+0x8a/0x8a
<5>[  170.577945]  [<ffffffff96887a5e>] irq_thread_fn+0x1d/0x3d
<5>[  170.578000]  [<ffffffff96887614>] irq_thread+0xfd/0x1f7
<5>[  170.578058]  [<ffffffff96d0a942>] ? __schedule+0x4b0/0x592
<5>[  170.578114]  [<ffffffff96887074>] ? kzalloc.constprop.37+0x1c/0x1c
<5>[  170.578171]  [<ffffffff96887517>] ? irq_thread_check_affinity+0x8a/0x8a
<5>[  170.578228]  [<ffffffff96850b26>] kthread+0xae/0xb6
<5>[  170.578285]  [<ffffffff96850a78>] ? __kthread_parkme+0x65/0x65
<5>[  170.578341]  [<ffffffff96d0c41c>] ret_from_fork+0x7c/0xb0
<5>[  170.578395]  [<ffffffff96850a78>] ? __kthread_parkme+0x65/0x65
<5>[  170.578440] Code: fa 81 0f 84 8b 00 00 00 80 fa 97 0f 85 f1 01 00 00 49 8b 54 24 10 48 c1 e8 08 49 8d 4c 24 10 83 e0 1f 48 39 ca 0f 84 d7 01 00 00 <39> 82 f8 00 00 00 74 05 48 8b 12 eb ea 48 85 d2 0f 84 c1 01 00
<1>[  170.581678] RIP  [<ffffffffc01cbb62>] sst_byt_dsp_suspend_noirq+0x13b/0x378 [snd_soc_sst_baytrail_pcm]
<5>[  170.581787]  RSP <ffff88005a0dbdc8>
<4>[  170.581837] ---[ end trace 9ae02a41a93d9247 ]---

sound/soc/intel/sst-baytrail-ipc.c:229

static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
						 int stream_id)
{
	struct sst_byt_stream *stream;

	list_for_each_entry(stream, &byt->stream_list, node) {
		if (stream->str_id == stream_id)  // <- line 229
			return stream;
	}

	return NULL;
}

There is a race between sst_byt_stream_free() and sst_byt_get_stream()
if sst_byt_get_stream() called from sst_byt_irq_thread() context is
accessing the byt->stream_list while a stream is deleted from the list.

A stream is added to byt->stream_list in sst_byt_stream_new() and deleted in
sst_byt_stream_free(). sst_byt_get_stream() is always protected by
sst->spinlock, but the stream addition and deletion are not protected.

The patch adds spinlock to both stream addition and deletion.

[Jarkko: Same fix added to sst-haswell-ipc.c too]

BUG=chrome-os-partner:27511
TEST=Test suspend/resume manually to confirm operation

Change-Id: Id33f739fb2dfc941c2adf185ad467eee5e4ee22e
Signed-off-by: Wenkai Du <wenkai.du@intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-on: https://chromium-review.googlesource.com/196515
Reviewed-by: Kevin Strasser <kevin.strasser@intel.com>
Reviewed-by: Derek Basehore <dbasehore@chromium.org>
(cherry picked from commit 561b0233525bc1a6d6645c467febff7deda439ef)
Reviewed-on: https://chromium-review.googlesource.com/197059
Reviewed-by: Bernie Thompson <bhthompson@chromium.org>
Commit-Queue: Bernie Thompson <bhthompson@chromium.org>
Tested-by: Bernie Thompson <bhthompson@chromium.org>