--- /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
+@@ -305,8 +305,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
+@@ -348,7 +347,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 */
+@@ -493,8 +492,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;
+@@ -503,13 +501,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;
+@@ -534,9 +530,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)
+@@ -555,7 +549,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;
+@@ -601,7 +595,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
-@@ -724,8 +724,8 @@ void snd_timer_interrupt(struct snd_time
+@@ -718,8 +718,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
-@@ -452,6 +452,10 @@ static int snd_timer_start_slave(struct
+@@ -451,6 +451,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);
-@@ -476,7 +480,8 @@ int snd_timer_start(struct snd_timer_ins
+@@ -475,7 +479,8 @@ 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;
}
timer = timeri->timer;
-@@ -485,11 +490,18 @@ int snd_timer_start(struct snd_timer_ins
+@@ -484,11 +489,18 @@ int snd_timer_start(struct snd_timer_ins
if (timer->card && timer->card->shutdown)
return -ENODEV;
spin_lock_irqsave(&timer->lock, flags);
return result;
}
-@@ -505,6 +517,10 @@ static int _snd_timer_stop(struct snd_ti
+@@ -502,6 +514,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);
-@@ -516,6 +532,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);
+@@ -512,6 +528,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 (timer->card && timer->card->shutdown) {
-@@ -587,10 +608,15 @@ int snd_timer_continue(struct snd_timer_
+@@ -581,10 +602,15 @@ int snd_timer_continue(struct snd_timer_
if (timer->card && timer->card->shutdown)
return -ENODEV;
spin_lock_irqsave(&timer->lock, flags);
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
-@@ -1926,6 +1926,7 @@ static ssize_t snd_timer_user_read(struc
+@@ -1920,6 +1920,7 @@ static ssize_t snd_timer_user_read(struc
{
struct snd_timer_user *tu;
long result = 0, unit;
int err = 0;
tu = file->private_data;
-@@ -1937,7 +1938,7 @@ static ssize_t snd_timer_user_read(struc
+@@ -1931,7 +1932,7 @@ static ssize_t snd_timer_user_read(struc
if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
err = -EAGAIN;
}
set_current_state(TASK_INTERRUPTIBLE);
-@@ -1952,42 +1953,37 @@ static ssize_t snd_timer_user_read(struc
+@@ -1946,42 +1947,37 @@ static ssize_t snd_timer_user_read(struc
if (tu->disconnected) {
err = -ENODEV;
--- /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
+@@ -518,9 +518,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
-@@ -423,7 +423,7 @@ static void snd_timer_notify1(struct snd
+@@ -422,7 +422,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)
parisc-fix-__arch_si_preamble_size.patch
media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch
md-raid-only-permit-hot-add-of-compatible-integrity-profiles.patch
+hrtimer-handle-remaining-time-proper-for-time_low_res.patch
alsa-usb-audio-fix-teac-ud-501-ud-503-nt-503-usb-delay.patch
alsa-usb-audio-add-quirk-for-microsoft-lifecam-hd-6000.patch
alsa-usb-audio-fix-oppo-ha-1-vendor-id.patch
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-race-at-concurrent-reads.patch
alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch
-hrtimer-handle-remaining-time-proper-for-time_low_res.patch
+alsa-timer-fix-race-between-stop-and-interrupt.patch
alsa-hda-add-fixup-for-mac-mini-7-1-model.patch
alsa-hda-fix-static-checker-warning-in-patch_hdmi.c.patch
revert-alsa-hda-fix-noise-on-gigabyte-z170x-mobo.patch