--- /dev/null
+From b088b53e20c7d09b5ab84c5688e609f478e5c417 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 5 Jan 2018 16:15:33 +0100
+Subject: ALSA: aloop: Fix inconsistent format due to incomplete rule
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit b088b53e20c7d09b5ab84c5688e609f478e5c417 upstream.
+
+The extra hw constraint rule for the formats the aloop driver
+introduced has a slight flaw, where it doesn't return a positive value
+when the mask got changed. It came from the fact that it's basically
+a copy&paste from snd_hw_constraint_mask64(). The original code is
+supposed to be a single-shot and it modifies the mask bits only once
+and never after, while what we need for aloop is the dynamic hw rule
+that limits the mask bits.
+
+This difference results in the inconsistent state, as the hw_refine
+doesn't apply the dependencies fully. The worse and surprisingly
+result is that it causes a crash in OSS emulation when multiple
+full-duplex reads/writes are performed concurrently (I leave why it
+triggers Oops to readers as a homework).
+
+For fixing this, replace a few open-codes with the standard
+snd_mask_*() macros.
+
+Reported-by: syzbot+3902b5220e8ca27889ca@syzkaller.appspotmail.com
+Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/drivers/aloop.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -39,6 +39,7 @@
+ #include <sound/core.h>
+ #include <sound/control.h>
+ #include <sound/pcm.h>
++#include <sound/pcm_params.h>
+ #include <sound/info.h>
+ #include <sound/initval.h>
+
+@@ -622,14 +623,12 @@ static int rule_format(struct snd_pcm_hw
+ {
+
+ struct snd_pcm_hardware *hw = rule->private;
+- struct snd_mask *maskp = hw_param_mask(params, rule->var);
++ struct snd_mask m;
+
+- maskp->bits[0] &= (u_int32_t)hw->formats;
+- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
+- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
+- if (! maskp->bits[0] && ! maskp->bits[1])
+- return -EINVAL;
+- return 0;
++ snd_mask_none(&m);
++ m.bits[0] = (u_int32_t)hw->formats;
++ m.bits[1] = (u_int32_t)(hw->formats >> 32);
++ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
+ }
+
+ static int rule_rate(struct snd_pcm_hw_params *params,
--- /dev/null
+From 898dfe4687f460ba337a01c11549f87269a13fa2 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 4 Jan 2018 17:38:54 +0100
+Subject: ALSA: aloop: Fix racy hw constraints adjustment
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 898dfe4687f460ba337a01c11549f87269a13fa2 upstream.
+
+The aloop driver tries to update the hw constraints of the connected
+target on the cable of the opened PCM substream. This is done by
+adding the extra hw constraints rules referring to the substream
+runtime->hw fields, while the other substream may update the runtime
+hw of another side on the fly.
+
+This is, however, racy and may result in the inconsistent values when
+both PCM streams perform the prepare concurrently. One of the reason
+is that it overwrites the other's runtime->hw field; which is not only
+racy but also broken when it's called before the open of another side
+finishes. And, since the reference to runtime->hw isn't protected,
+the concurrent write may give the partial value update and become
+inconsistent.
+
+This patch is an attempt to fix and clean up:
+- The prepare doesn't change the runtime->hw of other side any longer,
+ but only update the cable->hw that is referred commonly.
+- The extra rules refer to the loopback_pcm object instead of the
+ runtime->hw. The actual hw is deduced from cable->hw.
+- The extra rules take the cable_lock to protect against the race.
+
+Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/drivers/aloop.c | 51 ++++++++++++++++++++------------------------------
+ 1 file changed, 21 insertions(+), 30 deletions(-)
+
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -306,19 +306,6 @@ static int loopback_trigger(struct snd_p
+ return 0;
+ }
+
+-static void params_change_substream(struct loopback_pcm *dpcm,
+- struct snd_pcm_runtime *runtime)
+-{
+- struct snd_pcm_runtime *dst_runtime;
+-
+- if (dpcm == NULL || dpcm->substream == NULL)
+- return;
+- dst_runtime = dpcm->substream->runtime;
+- if (dst_runtime == NULL)
+- return;
+- dst_runtime->hw = dpcm->cable->hw;
+-}
+-
+ static void params_change(struct snd_pcm_substream *substream)
+ {
+ struct snd_pcm_runtime *runtime = substream->runtime;
+@@ -330,10 +317,6 @@ static void params_change(struct snd_pcm
+ cable->hw.rate_max = runtime->rate;
+ cable->hw.channels_min = runtime->channels;
+ cable->hw.channels_max = runtime->channels;
+- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
+- runtime);
+- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
+- runtime);
+ }
+
+ static int loopback_prepare(struct snd_pcm_substream *substream)
+@@ -621,24 +604,29 @@ static unsigned int get_cable_index(stru
+ static int rule_format(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+ {
+-
+- struct snd_pcm_hardware *hw = rule->private;
++ struct loopback_pcm *dpcm = rule->private;
++ struct loopback_cable *cable = dpcm->cable;
+ struct snd_mask m;
+
+ snd_mask_none(&m);
+- m.bits[0] = (u_int32_t)hw->formats;
+- m.bits[1] = (u_int32_t)(hw->formats >> 32);
++ mutex_lock(&dpcm->loopback->cable_lock);
++ m.bits[0] = (u_int32_t)cable->hw.formats;
++ m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
++ mutex_unlock(&dpcm->loopback->cable_lock);
+ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
+ }
+
+ static int rule_rate(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+ {
+- struct snd_pcm_hardware *hw = rule->private;
++ struct loopback_pcm *dpcm = rule->private;
++ struct loopback_cable *cable = dpcm->cable;
+ struct snd_interval t;
+
+- t.min = hw->rate_min;
+- t.max = hw->rate_max;
++ mutex_lock(&dpcm->loopback->cable_lock);
++ t.min = cable->hw.rate_min;
++ t.max = cable->hw.rate_max;
++ mutex_unlock(&dpcm->loopback->cable_lock);
+ t.openmin = t.openmax = 0;
+ t.integer = 0;
+ return snd_interval_refine(hw_param_interval(params, rule->var), &t);
+@@ -647,11 +635,14 @@ static int rule_rate(struct snd_pcm_hw_p
+ static int rule_channels(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+ {
+- struct snd_pcm_hardware *hw = rule->private;
++ struct loopback_pcm *dpcm = rule->private;
++ struct loopback_cable *cable = dpcm->cable;
+ struct snd_interval t;
+
+- t.min = hw->channels_min;
+- t.max = hw->channels_max;
++ mutex_lock(&dpcm->loopback->cable_lock);
++ t.min = cable->hw.channels_min;
++ t.max = cable->hw.channels_max;
++ mutex_unlock(&dpcm->loopback->cable_lock);
+ t.openmin = t.openmax = 0;
+ t.integer = 0;
+ return snd_interval_refine(hw_param_interval(params, rule->var), &t);
+@@ -717,19 +708,19 @@ static int loopback_open(struct snd_pcm_
+ /* are cached -> they do not reflect the actual state */
+ err = snd_pcm_hw_rule_add(runtime, 0,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+- rule_format, &runtime->hw,
++ rule_format, dpcm,
+ SNDRV_PCM_HW_PARAM_FORMAT, -1);
+ if (err < 0)
+ goto unlock;
+ err = snd_pcm_hw_rule_add(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+- rule_rate, &runtime->hw,
++ rule_rate, dpcm,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ goto unlock;
+ err = snd_pcm_hw_rule_add(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+- rule_channels, &runtime->hw,
++ rule_channels, dpcm,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ if (err < 0)
+ goto unlock;
--- /dev/null
+From 9685347aa0a5c2869058ca6ab79fd8e93084a67f Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 5 Jan 2018 16:09:47 +0100
+Subject: ALSA: aloop: Release cable upon open error path
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 9685347aa0a5c2869058ca6ab79fd8e93084a67f upstream.
+
+The aloop runtime object and its assignment in the cable are left even
+when opening a substream fails. This doesn't mean any memory leak,
+but it still keeps the invalid pointer that may be referred by the
+another side of the cable spontaneously, which is a potential Oops
+cause.
+
+Clean up the cable assignment and the empty cable upon the error path
+properly.
+
+Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/drivers/aloop.c | 38 +++++++++++++++++++++++++-------------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -658,12 +658,31 @@ static int rule_channels(struct snd_pcm_
+ return snd_interval_refine(hw_param_interval(params, rule->var), &t);
+ }
+
++static void free_cable(struct snd_pcm_substream *substream)
++{
++ struct loopback *loopback = substream->private_data;
++ int dev = get_cable_index(substream);
++ struct loopback_cable *cable;
++
++ cable = loopback->cables[substream->number][dev];
++ if (!cable)
++ return;
++ if (cable->streams[!substream->stream]) {
++ /* other stream is still alive */
++ cable->streams[substream->stream] = NULL;
++ } else {
++ /* free the cable */
++ loopback->cables[substream->number][dev] = NULL;
++ kfree(cable);
++ }
++}
++
+ static int loopback_open(struct snd_pcm_substream *substream)
+ {
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct loopback *loopback = substream->private_data;
+ struct loopback_pcm *dpcm;
+- struct loopback_cable *cable;
++ struct loopback_cable *cable = NULL;
+ int err = 0;
+ int dev = get_cable_index(substream);
+
+@@ -682,7 +701,6 @@ static int loopback_open(struct snd_pcm_
+ if (!cable) {
+ cable = kzalloc(sizeof(*cable), GFP_KERNEL);
+ if (!cable) {
+- kfree(dpcm);
+ err = -ENOMEM;
+ goto unlock;
+ }
+@@ -724,6 +742,10 @@ static int loopback_open(struct snd_pcm_
+ else
+ runtime->hw = cable->hw;
+ unlock:
++ if (err < 0) {
++ free_cable(substream);
++ kfree(dpcm);
++ }
+ mutex_unlock(&loopback->cable_lock);
+ return err;
+ }
+@@ -732,20 +754,10 @@ static int loopback_close(struct snd_pcm
+ {
+ struct loopback *loopback = substream->private_data;
+ struct loopback_pcm *dpcm = substream->runtime->private_data;
+- struct loopback_cable *cable;
+- int dev = get_cable_index(substream);
+
+ loopback_timer_stop(dpcm);
+ mutex_lock(&loopback->cable_lock);
+- cable = loopback->cables[substream->number][dev];
+- if (cable->streams[!substream->stream]) {
+- /* other stream is still alive */
+- cable->streams[substream->stream] = NULL;
+- } else {
+- /* free the cable */
+- loopback->cables[substream->number][dev] = NULL;
+- kfree(cable);
+- }
++ free_cable(substream);
+ mutex_unlock(&loopback->cable_lock);
+ return 0;
+ }
--- /dev/null
+From 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 8 Jan 2018 13:58:31 +0100
+Subject: ALSA: pcm: Abort properly at pending signal in OSS read/write loops
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b upstream.
+
+The loops for read and write in PCM OSS emulation have no proper check
+of pending signals, and they keep processing even after user tries to
+break. This results in a very long delay, often seen as RCU stall
+when a huge unprocessed bytes remain queued. The bug could be easily
+triggered by syzkaller.
+
+As a simple workaround, this patch adds the proper check of pending
+signals and aborts the loop appropriately.
+
+Reported-by: syzbot+993cb4cfcbbff3947c21@syzkaller.appspotmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/oss/pcm_oss.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -1416,6 +1416,10 @@ static ssize_t snd_pcm_oss_write1(struct
+ tmp != runtime->oss.period_bytes)
+ break;
+ }
++ if (signal_pending(current)) {
++ tmp = -ERESTARTSYS;
++ goto err;
++ }
+ }
+ mutex_unlock(&runtime->oss.params_lock);
+ return xfer;
+@@ -1501,6 +1505,10 @@ static ssize_t snd_pcm_oss_read1(struct
+ bytes -= tmp;
+ xfer += tmp;
+ }
++ if (signal_pending(current)) {
++ tmp = -ERESTARTSYS;
++ goto err;
++ }
+ }
+ mutex_unlock(&runtime->oss.params_lock);
+ return xfer;
--- /dev/null
+From 6708913750344a900f2e73bfe4a4d6dbbce4fe8d Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 4 Jan 2018 16:39:27 +0100
+Subject: ALSA: pcm: Add missing error checks in OSS emulation plugin builder
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 6708913750344a900f2e73bfe4a4d6dbbce4fe8d upstream.
+
+In the OSS emulation plugin builder where the frame size is parsed in
+the plugin chain, some places miss the possible errors returned from
+the plugin src_ or dst_frames callback.
+
+This patch papers over such places.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/oss/pcm_plugin.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/sound/core/oss/pcm_plugin.c
++++ b/sound/core/oss/pcm_plugin.c
+@@ -591,18 +591,26 @@ snd_pcm_sframes_t snd_pcm_plug_write_tra
+ snd_pcm_sframes_t frames = size;
+
+ plugin = snd_pcm_plug_first(plug);
+- while (plugin && frames > 0) {
++ while (plugin) {
++ if (frames <= 0)
++ return frames;
+ if ((next = plugin->next) != NULL) {
+ snd_pcm_sframes_t frames1 = frames;
+- if (plugin->dst_frames)
++ if (plugin->dst_frames) {
+ frames1 = plugin->dst_frames(plugin, frames);
++ if (frames1 <= 0)
++ return frames1;
++ }
+ if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
+ return err;
+ }
+ if (err != frames1) {
+ frames = err;
+- if (plugin->src_frames)
++ if (plugin->src_frames) {
+ frames = plugin->src_frames(plugin, frames1);
++ if (frames <= 0)
++ return frames;
++ }
+ }
+ } else
+ dst_channels = NULL;
--- /dev/null
+From 900498a34a3ac9c611e9b425094c8106bdd7dc1c Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 8 Jan 2018 14:03:53 +0100
+Subject: ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream.
+
+PCM OSS read/write loops keep taking the mutex lock for the whole
+read/write, and this might take very long when the exceptionally high
+amount of data is given. Also, since it invokes with mutex_lock(),
+the concurrent read/write becomes unbreakable.
+
+This patch tries to address these issues by replacing mutex_lock()
+with mutex_lock_interruptible(), and also splits / re-takes the lock
+at each read/write period chunk, so that it can switch the context
+more finely if requested.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++---------------
+ 1 file changed, 21 insertions(+), 15 deletions(-)
+
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -1369,8 +1369,11 @@ static ssize_t snd_pcm_oss_write1(struct
+
+ if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
+ return tmp;
+- mutex_lock(&runtime->oss.params_lock);
+ while (bytes > 0) {
++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
++ tmp = -ERESTARTSYS;
++ break;
++ }
+ if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
+ tmp = bytes;
+ if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
+@@ -1414,18 +1417,18 @@ static ssize_t snd_pcm_oss_write1(struct
+ xfer += tmp;
+ if ((substream->f_flags & O_NONBLOCK) != 0 &&
+ tmp != runtime->oss.period_bytes)
+- break;
++ tmp = -EAGAIN;
+ }
++ err:
++ mutex_unlock(&runtime->oss.params_lock);
++ if (tmp < 0)
++ break;
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+- goto err;
++ break;
+ }
++ tmp = 0;
+ }
+- mutex_unlock(&runtime->oss.params_lock);
+- return xfer;
+-
+- err:
+- mutex_unlock(&runtime->oss.params_lock);
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+ }
+
+@@ -1473,8 +1476,11 @@ static ssize_t snd_pcm_oss_read1(struct
+
+ if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
+ return tmp;
+- mutex_lock(&runtime->oss.params_lock);
+ while (bytes > 0) {
++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
++ tmp = -ERESTARTSYS;
++ break;
++ }
+ if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
+ if (runtime->oss.buffer_used == 0) {
+ tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
+@@ -1505,16 +1511,16 @@ static ssize_t snd_pcm_oss_read1(struct
+ bytes -= tmp;
+ xfer += tmp;
+ }
++ err:
++ mutex_unlock(&runtime->oss.params_lock);
++ if (tmp < 0)
++ break;
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+- goto err;
++ break;
+ }
++ tmp = 0;
+ }
+- mutex_unlock(&runtime->oss.params_lock);
+- return xfer;
+-
+- err:
+- mutex_unlock(&runtime->oss.params_lock);
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+ }
+
--- /dev/null
+From fe08f34d066f4404934a509b6806db1a4f700c86 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 1 Jan 2018 09:50:50 +0100
+Subject: ALSA: pcm: Remove incorrect snd_BUG_ON() usages
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit fe08f34d066f4404934a509b6806db1a4f700c86 upstream.
+
+syzkaller triggered kernel warnings through PCM OSS emulation at
+closing a stream:
+ WARNING: CPU: 0 PID: 3502 at sound/core/pcm_lib.c:1635
+ snd_pcm_hw_param_first+0x289/0x690 sound/core/pcm_lib.c:1635
+ Call Trace:
+ ....
+ snd_pcm_hw_param_near.constprop.27+0x78d/0x9a0 sound/core/oss/pcm_oss.c:457
+ snd_pcm_oss_change_params+0x17d3/0x3720 sound/core/oss/pcm_oss.c:969
+ snd_pcm_oss_make_ready+0xaa/0x130 sound/core/oss/pcm_oss.c:1128
+ snd_pcm_oss_sync+0x257/0x830 sound/core/oss/pcm_oss.c:1638
+ snd_pcm_oss_release+0x20b/0x280 sound/core/oss/pcm_oss.c:2431
+ __fput+0x327/0x7e0 fs/file_table.c:210
+ ....
+
+This happens while it tries to open and set up the aloop device
+concurrently. The warning above (invoked from snd_BUG_ON() macro) is
+to detect the unexpected logical error where snd_pcm_hw_refine() call
+shouldn't fail. The theory is true for the case where the hw_params
+config rules are static. But for an aloop device, the hw_params rule
+condition does vary dynamically depending on the connected target;
+when another device is opened and changes the parameters, the device
+connected in another side is also affected, and it caused the error
+from snd_pcm_hw_refine().
+
+That is, the simplest "solution" for this is to remove the incorrect
+assumption of static rules, and treat such an error as a normal error
+path. As there are a couple of other places using snd_BUG_ON()
+incorrectly, this patch removes these spurious snd_BUG_ON() calls.
+
+Reported-by: syzbot+6f11c7e2a1b91d466432@syzkaller.appspotmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/oss/pcm_oss.c | 1 -
+ sound/core/pcm_lib.c | 4 ++--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -465,7 +465,6 @@ static int snd_pcm_hw_param_near(struct
+ v = snd_pcm_hw_param_last(pcm, params, var, dir);
+ else
+ v = snd_pcm_hw_param_first(pcm, params, var, dir);
+- snd_BUG_ON(v < 0);
+ return v;
+ }
+
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -1664,7 +1664,7 @@ int snd_pcm_hw_param_first(struct snd_pc
+ return changed;
+ if (params->rmask) {
+ int err = snd_pcm_hw_refine(pcm, params);
+- if (snd_BUG_ON(err < 0))
++ if (err < 0)
+ return err;
+ }
+ return snd_pcm_hw_param_value(params, var, dir);
+@@ -1711,7 +1711,7 @@ int snd_pcm_hw_param_last(struct snd_pcm
+ return changed;
+ if (params->rmask) {
+ int err = snd_pcm_hw_refine(pcm, params);
+- if (snd_BUG_ON(err < 0))
++ if (err < 0)
+ return err;
+ }
+ return snd_pcm_hw_param_value(params, var, dir);
--- /dev/null
+From yurovsky@gmail.com Thu Jan 11 07:36:10 2018
+From: Andrey Yurovsky <yurovsky@gmail.com>
+Date: Wed, 10 Jan 2018 15:47:34 -0800
+Subject: [PATCH] nvmem: add i.MX7 support to snvs-lpgpr
+To: srinivas.kandagatla@linaro.org
+Cc: Andrey Yurovsky <yurovsky@gmail.com>, o.rempel@pengutronix.de, gregkh@linuxfoundation.org
+Message-ID: <20180110234734.26213-1-yurovsky@gmail.com>
+
+
+The i.MX7 family has similar SNVS hardware so make the snvs-lpgpr
+support it along with the i.MX6 family. The register interface is the
+same except for the number and offset of the general purpose registers.
+
+Signed-off-by: Andrey Yurovsky <yurovsky@gmail.com>
+---
+ .../devicetree/bindings/nvmem/snvs-lpgpr.txt | 3 ++-
+ drivers/nvmem/Kconfig | 4 ++--
+ drivers/nvmem/snvs_lpgpr.c | 27 +++++++++++++++++-----
+ 3 files changed, 25 insertions(+), 9 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt b/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
+index 20bc49b49799..3cb170896658 100644
+--- a/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
++++ b/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
+@@ -1,5 +1,5 @@
+ Device tree bindings for Low Power General Purpose Register found in i.MX6Q/D
+-Secure Non-Volatile Storage.
++and i.MX7 Secure Non-Volatile Storage.
+
+ This DT node should be represented as a sub-node of a "syscon",
+ "simple-mfd" node.
+@@ -8,6 +8,7 @@ Required properties:
+ - compatible: should be one of the fallowing variants:
+ "fsl,imx6q-snvs-lpgpr" for Freescale i.MX6Q/D/DL/S
+ "fsl,imx6ul-snvs-lpgpr" for Freescale i.MX6UL
++ "fsl,imx7d-snvs-lpgpr" for Freescale i.MX7D/S
+
+ Example:
+ snvs: snvs@020cc000 {
+diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
+index ff505af064ba..5f9bc787d634 100644
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -167,10 +167,10 @@ config MESON_MX_EFUSE
+
+ config NVMEM_SNVS_LPGPR
+ tristate "Support for Low Power General Purpose Register"
+- depends on SOC_IMX6 || COMPILE_TEST
++ depends on SOC_IMX6 || SOC_IMX7D || COMPILE_TEST
+ help
+ This is a driver for Low Power General Purpose Register (LPGPR) available on
+- i.MX6 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
++ i.MX6 and i.MX7 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called nvmem-snvs-lpgpr.
+diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
+index e5c2a4a17f03..3ed617a16db0 100644
+--- a/drivers/nvmem/snvs_lpgpr.c
++++ b/drivers/nvmem/snvs_lpgpr.c
+@@ -14,15 +14,21 @@
+ #include <linux/regmap.h>
+
+ #define IMX6Q_SNVS_HPLR 0x00
+-#define IMX6Q_GPR_SL BIT(5)
+ #define IMX6Q_SNVS_LPLR 0x34
+-#define IMX6Q_GPR_HL BIT(5)
+ #define IMX6Q_SNVS_LPGPR 0x68
+
++#define IMX7D_SNVS_HPLR 0x00
++#define IMX7D_SNVS_LPLR 0x34
++#define IMX7D_SNVS_LPGPR 0x90
++
++#define IMX_GPR_SL BIT(5)
++#define IMX_GPR_HL BIT(5)
++
+ struct snvs_lpgpr_cfg {
+ int offset;
+ int offset_hplr;
+ int offset_lplr;
++ int size;
+ };
+
+ struct snvs_lpgpr_priv {
+@@ -36,6 +42,14 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx6q = {
+ .offset = IMX6Q_SNVS_LPGPR,
+ .offset_hplr = IMX6Q_SNVS_HPLR,
+ .offset_lplr = IMX6Q_SNVS_LPLR,
++ .size = 4,
++};
++
++static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
++ .offset = IMX7D_SNVS_LPGPR,
++ .offset_hplr = IMX7D_SNVS_HPLR,
++ .offset_lplr = IMX7D_SNVS_LPLR,
++ .size = 16,
+ };
+
+ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
+@@ -50,14 +64,14 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
+ if (ret < 0)
+ return ret;
+
+- if (lock_reg & IMX6Q_GPR_SL)
++ if (lock_reg & IMX_GPR_SL)
+ return -EPERM;
+
+ ret = regmap_read(priv->regmap, dcfg->offset_lplr, &lock_reg);
+ if (ret < 0)
+ return ret;
+
+- if (lock_reg & IMX6Q_GPR_HL)
++ if (lock_reg & IMX_GPR_HL)
+ return -EPERM;
+
+ return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
+@@ -112,7 +126,7 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
+ cfg->dev = dev;
+ cfg->stride = 4,
+ cfg->word_size = 4,
+- cfg->size = 4,
++ cfg->size = dcfg->size,
+ cfg->owner = THIS_MODULE,
+ cfg->reg_read = snvs_lpgpr_read,
+ cfg->reg_write = snvs_lpgpr_write,
+@@ -137,6 +151,7 @@ static const struct of_device_id snvs_lpgpr_dt_ids[] = {
+ { .compatible = "fsl,imx6q-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx6q },
+ { .compatible = "fsl,imx6ul-snvs-lpgpr",
+ .data = &snvs_lpgpr_cfg_imx6q },
++ { .compatible = "fsl,imx7d-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx7d },
+ { },
+ };
+ MODULE_DEVICE_TABLE(of, snvs_lpgpr_dt_ids);
+@@ -152,5 +167,5 @@ static struct platform_driver snvs_lpgpr_driver = {
+ module_platform_driver(snvs_lpgpr_driver);
+
+ MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
+-MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 Secure Non-Volatile Storage");
++MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 and i.MX7 Secure Non-Volatile Storage");
+ MODULE_LICENSE("GPL v2");
+--
+2.14.3
+
x86-vsdo-fix-build-on-paravirt_clock-y-kvm_guest-n.patch
x86-acpi-handle-sci-interrupts-above-legacy-space-gracefully.patch
iommu-arm-smmu-v3-don-t-free-page-table-ops-twice.patch
+alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
+alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
+alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
+alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
+alsa-aloop-release-cable-upon-open-error-path.patch
+alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
+alsa-aloop-fix-racy-hw-constraints-adjustment.patch
+nvmem-add-i.mx7-support-to-snvs-lpgpr.patch