ASoC: Intel: Fix audio crash due to negative address offset

There were occasional ADSP crash during reboot testing:

[   11.883364] BUG: unable to handle kernel paging request at ffffc90121700000
[   11.883380] IP: [<ffffffffc024d8bc>] sst_module_insert_fixed_block+0x24f/0x26d [snd_soc_sst_dsp]
[   11.883397] PGD 7800b067 PUD 0
[   11.883405] Oops: 0002 [#1] SMP
[   11.886418] gsmi: Log Shutdown Reason 0x03

The virtual address, ffffc90121700000, was out of range. The virtual
address is calculated by adding LPE base address with an offset:

sst_memcpy32(dsp->addr.lpe + data->offset, data->data, data->size);

The offset is calculated in sst_byt_parse_module, by subtraction of
two virtual addresses dsp->addr.fw_ext and dsp->addr.lpe:

block_data.offset = block->ram_offset + (dsp->addr.fw_ext - dsp->addr.lpe);

These virtual addresses are assigned by kernel from ioremap:

sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
sst->addr.fw_ext = ioremap(pdata->fw_base, pdata->fw_size);

In current driver code, offset is defined as unsigned int32:

struct sst_module_data {
...
	u32 offset;		/* offset in FW file */
};

Most of the time kernel assigned virtual addresses with addr.fw_ext
greater than addr.lpe. But sometimes it was the other way round.

Fix the problem by declaring offset as signed int32_t.

Signed-off-by: Wenkai Du <wenkai.du@intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
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;
}

It looks like the stream is invalid.

<5>[  170.576597] RDX: dead000000100100 RSI: 0000000000000040 RDI: ffffc90021940000

Note the RDX is LIST_POISON1, which means the list item has been deleted.

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.

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

Change-Id: Idcbca8b57c271d2d5878538a12c2708a5bf84021
Signed-off-by: Wenkai Du <wenkai.du@intel.com>