--- /dev/null
+From c3b1681375dc6e71d89a3ae00cc3ce9e775a8917 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 14 Jan 2016 17:01:46 +0100
+Subject: ALSA: timer: Code cleanup
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit c3b1681375dc6e71d89a3ae00cc3ce9e775a8917 upstream.
+
+This is a minor code cleanup without any functional changes:
+- Kill keep_flag argument from _snd_timer_stop(), as all callers pass
+ only it false.
+- Remove redundant NULL check in _snd_timer_stop().
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer.c | 28 +++++++++++-----------------
+ 1 file changed, 11 insertions(+), 17 deletions(-)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -300,8 +300,7 @@ int snd_timer_open(struct snd_timer_inst
+ return 0;
+ }
+
+-static int _snd_timer_stop(struct snd_timer_instance *timeri,
+- int keep_flag, int event);
++static int _snd_timer_stop(struct snd_timer_instance *timeri, int event);
+
+ /*
+ * close a timer instance
+@@ -343,7 +342,7 @@ int snd_timer_close(struct snd_timer_ins
+ spin_unlock_irq(&timer->lock);
+ mutex_lock(®ister_mutex);
+ list_del(&timeri->open_list);
+- if (timer && list_empty(&timer->open_list_head) &&
++ if (list_empty(&timer->open_list_head) &&
+ timer->hw.close)
+ timer->hw.close(timer);
+ /* remove slave links */
+@@ -483,8 +482,7 @@ int snd_timer_start(struct snd_timer_ins
+ return result;
+ }
+
+-static int _snd_timer_stop(struct snd_timer_instance * timeri,
+- int keep_flag, int event)
++static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
+ {
+ struct snd_timer *timer;
+ unsigned long flags;
+@@ -493,13 +491,11 @@ static int _snd_timer_stop(struct snd_ti
+ return -ENXIO;
+
+ if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
+- if (!keep_flag) {
+- spin_lock_irqsave(&slave_active_lock, flags);
+- timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+- list_del_init(&timeri->ack_list);
+- list_del_init(&timeri->active_list);
+- spin_unlock_irqrestore(&slave_active_lock, flags);
+- }
++ spin_lock_irqsave(&slave_active_lock, flags);
++ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
++ list_del_init(&timeri->ack_list);
++ list_del_init(&timeri->active_list);
++ spin_unlock_irqrestore(&slave_active_lock, flags);
+ goto __end;
+ }
+ timer = timeri->timer;
+@@ -520,9 +516,7 @@ static int _snd_timer_stop(struct snd_ti
+ }
+ }
+ }
+- if (!keep_flag)
+- timeri->flags &=
+- ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
++ timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
+ spin_unlock_irqrestore(&timer->lock, flags);
+ __end:
+ if (event != SNDRV_TIMER_EVENT_RESOLUTION)
+@@ -541,7 +535,7 @@ int snd_timer_stop(struct snd_timer_inst
+ unsigned long flags;
+ int err;
+
+- err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
++ err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP);
+ if (err < 0)
+ return err;
+ timer = timeri->timer;
+@@ -585,7 +579,7 @@ int snd_timer_continue(struct snd_timer_
+ */
+ int snd_timer_pause(struct snd_timer_instance * timeri)
+ {
+- return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
++ return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE);
+ }
+
+ /*
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
-@@ -702,8 +702,8 @@ void snd_timer_interrupt(struct snd_time
+@@ -696,8 +696,8 @@ void snd_timer_interrupt(struct snd_time
ti->cticks = ti->ticks;
} else {
ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
-@@ -444,6 +444,10 @@ static int snd_timer_start_slave(struct
+@@ -443,6 +443,10 @@ static int snd_timer_start_slave(struct
unsigned long flags;
spin_lock_irqsave(&slave_active_lock, flags);
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
if (timeri->master && timeri->timer) {
spin_lock(&timeri->timer->lock);
-@@ -468,18 +472,26 @@ int snd_timer_start(struct snd_timer_ins
+@@ -467,18 +471,26 @@ int snd_timer_start(struct snd_timer_ins
return -EINVAL;
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
result = snd_timer_start_slave(timeri);
return result;
}
-@@ -495,6 +507,10 @@ static int _snd_timer_stop(struct snd_ti
+@@ -492,6 +504,10 @@ static int _snd_timer_stop(struct snd_ti
+
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
- if (!keep_flag) {
- spin_lock_irqsave(&slave_active_lock, flags);
-+ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
-+ spin_unlock_irqrestore(&slave_active_lock, flags);
-+ return -EBUSY;
-+ }
- timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
- list_del_init(&timeri->ack_list);
- list_del_init(&timeri->active_list);
-@@ -506,6 +522,11 @@ static int _snd_timer_stop(struct snd_ti
+ spin_lock_irqsave(&slave_active_lock, flags);
++ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
++ spin_unlock_irqrestore(&slave_active_lock, flags);
++ return -EBUSY;
++ }
+ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+ list_del_init(&timeri->ack_list);
+ list_del_init(&timeri->active_list);
+@@ -502,6 +518,11 @@ static int _snd_timer_stop(struct snd_ti
if (!timer)
return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
list_del_init(&timeri->ack_list);
list_del_init(&timeri->active_list);
if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
-@@ -571,10 +592,15 @@ int snd_timer_continue(struct snd_timer_
+@@ -565,10 +586,15 @@ int snd_timer_continue(struct snd_timer_
if (! timer)
return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
--- /dev/null
+From ed8b1d6d2c741ab26d60d499d7fbb7ac801f0f51 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 9 Feb 2016 12:02:32 +0100
+Subject: ALSA: timer: Fix race between stop and interrupt
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit ed8b1d6d2c741ab26d60d499d7fbb7ac801f0f51 upstream.
+
+A slave timer element also unlinks at snd_timer_stop() but it takes
+only slave_active_lock. When a slave is assigned to a master,
+however, this may become a race against the master's interrupt
+handling, eventually resulting in a list corruption. The actual bug
+could be seen with a syzkaller fuzzer test case in BugLink below.
+
+As a fix, we need to take timeri->timer->lock when timer isn't NULL,
+i.e. assigned to a master, while the assignment to a master itself is
+protected by slave_active_lock.
+
+BugLink: http://lkml.kernel.org/r/CACT4Y+Y_Bm+7epAb=8Wi=AaWd+DYS7qawX52qxdCfOfY49vozQ@mail.gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -508,9 +508,13 @@ static int _snd_timer_stop(struct snd_ti
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ return -EBUSY;
+ }
++ if (timeri->timer)
++ spin_lock(&timeri->timer->lock);
+ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+ list_del_init(&timeri->ack_list);
+ list_del_init(&timeri->active_list);
++ if (timeri->timer)
++ spin_unlock(&timeri->timer->lock);
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ goto __end;
+ }
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
-@@ -415,7 +415,7 @@ static void snd_timer_notify1(struct snd
+@@ -414,7 +414,7 @@ static void snd_timer_notify1(struct snd
spin_lock_irqsave(&timer->lock, flags);
list_for_each_entry(ts, &ti->slave_active_head, active_list)
if (ts->ccallback)
alsa-seq-fix-yet-another-races-among-alsa-timer-accesses.patch
alsa-seq-fix-race-at-closing-in-virmidi-driver.patch
alsa-seq-fix-lockdep-warnings-due-to-double-mutex-locks.patch
+alsa-timer-code-cleanup.patch
alsa-timer-fix-leftover-link-at-closing.patch
alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch
alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch
alsa-hda-fix-speaker-output-from-vaio-aio-machines.patch
alsa-dummy-implement-timer-backend-switching-more-safely.patch
+alsa-timer-fix-race-between-stop-and-interrupt.patch
saa7134-alsa-only-frees-registered-sound-cards.patch
usb-ti_usb_3410_502-fix-id-table-size.patch
usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.patch