ALSA: hda - Fix NULL dereference from CA0132 DSP loader

The CA0132 DSP loader leads to NULL deference since the recent
transition to HDA core code, as it unconditionally accesses
hdac_stream->substream->runtime.  For DSP loading, the substream
shouldn't be assigned.

This patch addresses the NULL dereference above in addition to assure
the substream is cleared while DSP loading.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=98151
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2015-05-19 11:35:13 +02:00
parent 1882b0577b
commit 4214c5349c
1 changed files with 9 additions and 3 deletions

View File

@ -139,9 +139,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_reset);
int snd_hdac_stream_setup(struct hdac_stream *azx_dev) int snd_hdac_stream_setup(struct hdac_stream *azx_dev)
{ {
struct hdac_bus *bus = azx_dev->bus; struct hdac_bus *bus = azx_dev->bus;
struct snd_pcm_runtime *runtime = azx_dev->substream->runtime; struct snd_pcm_runtime *runtime;
unsigned int val; unsigned int val;
if (azx_dev->substream)
runtime = azx_dev->substream->runtime;
else
runtime = NULL;
/* make sure the run bit is zero for SD */ /* make sure the run bit is zero for SD */
snd_hdac_stream_clear(azx_dev); snd_hdac_stream_clear(azx_dev);
/* program the stream_tag */ /* program the stream_tag */
@ -189,14 +193,15 @@ int snd_hdac_stream_setup(struct hdac_stream *azx_dev)
* we ignore it; currently set the threshold statically to * we ignore it; currently set the threshold statically to
* 64 frames * 64 frames
*/ */
if (runtime->period_size > 64) if (runtime && runtime->period_size > 64)
azx_dev->delay_negative_threshold = azx_dev->delay_negative_threshold =
-frames_to_bytes(runtime, 64); -frames_to_bytes(runtime, 64);
else else
azx_dev->delay_negative_threshold = 0; azx_dev->delay_negative_threshold = 0;
/* wallclk has 24Mhz clock source */ /* wallclk has 24Mhz clock source */
azx_dev->period_wallclk = (((runtime->period_size * 24000) / if (runtime)
azx_dev->period_wallclk = (((runtime->period_size * 24000) /
runtime->rate) * 1000); runtime->rate) * 1000);
return 0; return 0;
@ -611,6 +616,7 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
if (err < 0) if (err < 0)
goto err_alloc; goto err_alloc;
azx_dev->substream = NULL;
azx_dev->bufsize = byte_size; azx_dev->bufsize = byte_size;
azx_dev->period_bytes = byte_size; azx_dev->period_bytes = byte_size;
azx_dev->format_val = format; azx_dev->format_val = format;