From: Greg Kroah-Hartman Date: Sun, 14 Feb 2016 20:50:04 +0000 (-0800) Subject: 4.4-stable patches X-Git-Tag: v4.4.2~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e4bb493d2888a39d25a69b489f487c48c8712590;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: alsa-timer-code-cleanup.patch alsa-timer-fix-race-between-stop-and-interrupt.patch --- diff --git a/queue-4.4/alsa-timer-code-cleanup.patch b/queue-4.4/alsa-timer-code-cleanup.patch new file mode 100644 index 00000000000..7d98317e459 --- /dev/null +++ b/queue-4.4/alsa-timer-code-cleanup.patch @@ -0,0 +1,100 @@ +From c3b1681375dc6e71d89a3ae00cc3ce9e775a8917 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 14 Jan 2016 17:01:46 +0100 +Subject: ALSA: timer: Code cleanup + +From: Takashi Iwai + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + + /* diff --git a/queue-4.4/alsa-timer-fix-leftover-link-at-closing.patch b/queue-4.4/alsa-timer-fix-leftover-link-at-closing.patch index 832847d1e79..c465eaf846c 100644 --- a/queue-4.4/alsa-timer-fix-leftover-link-at-closing.patch +++ b/queue-4.4/alsa-timer-fix-leftover-link-at-closing.patch @@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman --- 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; diff --git a/queue-4.4/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch b/queue-4.4/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch index 93352de895e..5d35ee116c4 100644 --- a/queue-4.4/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch +++ b/queue-4.4/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch @@ -30,7 +30,7 @@ Signed-off-by: Greg Kroah-Hartman --- 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); @@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman 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); @@ -51,7 +51,7 @@ Signed-off-by: Greg Kroah-Hartman 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); @@ -71,18 +71,18 @@ Signed-off-by: Greg Kroah-Hartman 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); @@ -94,7 +94,7 @@ Signed-off-by: Greg Kroah-Hartman 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); diff --git a/queue-4.4/alsa-timer-fix-race-at-concurrent-reads.patch b/queue-4.4/alsa-timer-fix-race-at-concurrent-reads.patch index b6085d3ab44..0e9f1b83e4b 100644 --- a/queue-4.4/alsa-timer-fix-race-at-concurrent-reads.patch +++ b/queue-4.4/alsa-timer-fix-race-at-concurrent-reads.patch @@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman --- 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; @@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman 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; @@ -38,7 +38,7 @@ Signed-off-by: Greg Kroah-Hartman } 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; diff --git a/queue-4.4/alsa-timer-fix-race-between-stop-and-interrupt.patch b/queue-4.4/alsa-timer-fix-race-between-stop-and-interrupt.patch new file mode 100644 index 00000000000..29f0fbd241f --- /dev/null +++ b/queue-4.4/alsa-timer-fix-race-between-stop-and-interrupt.patch @@ -0,0 +1,43 @@ +From ed8b1d6d2c741ab26d60d499d7fbb7ac801f0f51 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 9 Feb 2016 12:02:32 +0100 +Subject: ALSA: timer: Fix race between stop and interrupt + +From: Takashi Iwai + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.4/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch b/queue-4.4/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch index 3321fcacf04..49053021346 100644 --- a/queue-4.4/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch +++ b/queue-4.4/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch @@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman --- 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) diff --git a/queue-4.4/series b/queue-4.4/series index ad33079d939..329b8d1e4f1 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -20,6 +20,7 @@ parisc-protect-huge-page-pte-changes-with-spinlocks.patch 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 @@ -43,11 +44,12 @@ asoc-dpcm-fix-the-be-state-on-hw_free.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