--- /dev/null
+From 69cf3978f3ada4e54beae4ad44868b5627864884 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 24 Apr 2020 11:21:14 +0100
+Subject: afs: Fix to actually set AFS_SERVER_FL_HAVE_EPOCH
+
+From: David Howells <dhowells@redhat.com>
+
+commit 69cf3978f3ada4e54beae4ad44868b5627864884 upstream.
+
+AFS keeps track of the epoch value from the rxrpc protocol to note (a) when
+a fileserver appears to have restarted and (b) when different endpoints of
+a fileserver do not appear to be associated with the same fileserver
+(ie. all probes back from a fileserver from all of its interfaces should
+carry the same epoch).
+
+However, the AFS_SERVER_FL_HAVE_EPOCH flag that indicates that we've
+received the server's epoch is never set, though it is used.
+
+Fix this to set the flag when we first receive an epoch value from a probe
+sent to the filesystem client from the fileserver.
+
+Fixes: 3bf0fb6f33dd ("afs: Probe multiple fileservers simultaneously")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/afs/cmservice.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/afs/cmservice.c
++++ b/fs/afs/cmservice.c
+@@ -169,7 +169,7 @@ static int afs_record_cm_probe(struct af
+
+ spin_lock(&server->probe_lock);
+
+- if (!test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
++ if (!test_and_set_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
+ server->cm_epoch = call->epoch;
+ server->probe.cm_epoch = call->epoch;
+ goto out;
--- /dev/null
+From c4bfda16d1b40d1c5941c61b5aa336bdd2d9904a Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 16 Apr 2020 18:17:13 +0100
+Subject: afs: Make record checking use TASK_UNINTERRUPTIBLE when appropriate
+
+From: David Howells <dhowells@redhat.com>
+
+commit c4bfda16d1b40d1c5941c61b5aa336bdd2d9904a upstream.
+
+When an operation is meant to be done uninterruptibly (such as
+FS.StoreData), we should not be allowing volume and server record checking
+to be interrupted.
+
+Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/afs/internal.h | 2 +-
+ fs/afs/rotate.c | 6 +++---
+ fs/afs/server.c | 7 ++-----
+ fs/afs/volume.c | 8 +++++---
+ 4 files changed, 11 insertions(+), 12 deletions(-)
+
+--- a/fs/afs/internal.h
++++ b/fs/afs/internal.h
+@@ -1329,7 +1329,7 @@ extern struct afs_volume *afs_create_vol
+ extern void afs_activate_volume(struct afs_volume *);
+ extern void afs_deactivate_volume(struct afs_volume *);
+ extern void afs_put_volume(struct afs_cell *, struct afs_volume *);
+-extern int afs_check_volume_status(struct afs_volume *, struct key *);
++extern int afs_check_volume_status(struct afs_volume *, struct afs_fs_cursor *);
+
+ /*
+ * write.c
+--- a/fs/afs/rotate.c
++++ b/fs/afs/rotate.c
+@@ -192,7 +192,7 @@ bool afs_select_fileserver(struct afs_fs
+ write_unlock(&vnode->volume->servers_lock);
+
+ set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
+- error = afs_check_volume_status(vnode->volume, fc->key);
++ error = afs_check_volume_status(vnode->volume, fc);
+ if (error < 0)
+ goto failed_set_error;
+
+@@ -281,7 +281,7 @@ bool afs_select_fileserver(struct afs_fs
+
+ set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags);
+ set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
+- error = afs_check_volume_status(vnode->volume, fc->key);
++ error = afs_check_volume_status(vnode->volume, fc);
+ if (error < 0)
+ goto failed_set_error;
+
+@@ -341,7 +341,7 @@ start:
+ /* See if we need to do an update of the volume record. Note that the
+ * volume may have moved or even have been deleted.
+ */
+- error = afs_check_volume_status(vnode->volume, fc->key);
++ error = afs_check_volume_status(vnode->volume, fc);
+ if (error < 0)
+ goto failed_set_error;
+
+--- a/fs/afs/server.c
++++ b/fs/afs/server.c
+@@ -595,12 +595,9 @@ retry:
+ }
+
+ ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
+- TASK_INTERRUPTIBLE);
++ (fc->flags & AFS_FS_CURSOR_INTR) ?
++ TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+ if (ret == -ERESTARTSYS) {
+- if (!(fc->flags & AFS_FS_CURSOR_INTR) && server->addresses) {
+- _leave(" = t [intr]");
+- return true;
+- }
+ fc->error = ret;
+ _leave(" = f [intr]");
+ return false;
+--- a/fs/afs/volume.c
++++ b/fs/afs/volume.c
+@@ -281,7 +281,7 @@ error:
+ /*
+ * Make sure the volume record is up to date.
+ */
+-int afs_check_volume_status(struct afs_volume *volume, struct key *key)
++int afs_check_volume_status(struct afs_volume *volume, struct afs_fs_cursor *fc)
+ {
+ time64_t now = ktime_get_real_seconds();
+ int ret, retries = 0;
+@@ -299,7 +299,7 @@ retry:
+ }
+
+ if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) {
+- ret = afs_update_volume_status(volume, key);
++ ret = afs_update_volume_status(volume, fc->key);
+ clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags);
+ clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags);
+ wake_up_bit(&volume->flags, AFS_VOLUME_WAIT);
+@@ -312,7 +312,9 @@ retry:
+ return 0;
+ }
+
+- ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT, TASK_INTERRUPTIBLE);
++ ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT,
++ (fc->flags & AFS_FS_CURSOR_INTR) ?
++ TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+ if (ret == -ERESTARTSYS) {
+ _leave(" = %d", ret);
+ return ret;
--- /dev/null
+From 1164284270779e1865cc2046a2a01b58a1e858a9 Mon Sep 17 00:00:00 2001
+From: Jerome Brunet <jbrunet@baylibre.com>
+Date: Mon, 20 Apr 2020 13:45:10 +0200
+Subject: ASoC: meson: axg-card: fix codec-to-codec link setup
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+commit 1164284270779e1865cc2046a2a01b58a1e858a9 upstream.
+
+Since the addition of commit 9b5db059366a ("ASoC: soc-pcm: dpcm: Only allow
+playback/capture if supported"), meson-axg cards which have codec-to-codec
+links fail to init and Oops:
+
+ Unable to handle kernel NULL pointer dereference at virtual address 0000000000000128
+ Internal error: Oops: 96000044 [#1] PREEMPT SMP
+ CPU: 3 PID: 1582 Comm: arecord Not tainted 5.7.0-rc1
+ pc : invalidate_paths_ep+0x30/0xe0
+ lr : snd_soc_dapm_dai_get_connected_widgets+0x170/0x1a8
+ Call trace:
+ invalidate_paths_ep+0x30/0xe0
+ snd_soc_dapm_dai_get_connected_widgets+0x170/0x1a8
+ dpcm_path_get+0x38/0xd0
+ dpcm_fe_dai_open+0x70/0x920
+ snd_pcm_open_substream+0x564/0x840
+ snd_pcm_open+0xfc/0x228
+ snd_pcm_capture_open+0x4c/0x78
+ snd_open+0xac/0x1a8
+ ...
+
+While initiliazing the links, ASoC treats the codec-to-codec links of this
+card type as a DPCM backend. This error eventually leads to the Oops.
+
+Most of the card driver code is shared between DPCM backends and
+codec-to-codec links. The property "no_pcm" marking DCPM BE was left set on
+codec-to-codec links, leading to this problem. This commit fixes that.
+
+Fixes: 0a8f1117a680 ("ASoC: meson: axg-card: add basic codec-to-codec link support")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://lore.kernel.org/r/20200420114511.450560-2-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/meson/axg-card.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/meson/axg-card.c
++++ b/sound/soc/meson/axg-card.c
+@@ -586,8 +586,10 @@ static int axg_card_add_link(struct snd_
+
+ if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node))
+ ret = axg_card_parse_tdm(card, np, index);
+- else if (axg_card_cpu_is_codec(dai_link->cpus->of_node))
++ else if (axg_card_cpu_is_codec(dai_link->cpus->of_node)) {
+ dai_link->params = &codec_params;
++ dai_link->no_pcm = 0; /* link is not a DPCM BE */
++ }
+
+ return ret;
+ }
--- /dev/null
+From 0c824ec094b5cda766c80d88c2036e28c24a4cb1 Mon Sep 17 00:00:00 2001
+From: Stephan Gerhold <stephan@gerhold.net>
+Date: Wed, 15 Apr 2020 17:00:50 +0200
+Subject: ASoC: q6dsp6: q6afe-dai: add missing channels to MI2S DAIs
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+commit 0c824ec094b5cda766c80d88c2036e28c24a4cb1 upstream.
+
+For some reason, the MI2S DAIs do not have channels_min/max defined.
+This means that snd_soc_dai_stream_valid() returns false,
+i.e. the DAIs have neither valid playback nor capture stream.
+
+It's quite surprising that this ever worked correctly,
+but in 5.7-rc1 this is now failing badly: :)
+
+Commit 0e9cf4c452ad ("ASoC: pcm: check if cpu-dai supports a given stream")
+introduced a check for snd_soc_dai_stream_valid() before calling
+hw_params(), which means that the q6i2s_hw_params() function
+was never called, eventually resulting in:
+
+ qcom-q6afe aprsvc:q6afe:4:4: no line is assigned
+
+... even though "qcom,sd-lines" is set in the device tree.
+
+Commit 9b5db059366a ("ASoC: soc-pcm: dpcm: Only allow playback/capture if supported")
+now even avoids creating PCM devices if the stream is not supported,
+which means that it is failing even earlier with e.g.:
+
+ Primary MI2S: ASoC: no backend playback stream
+
+Avoid all that trouble by adding channels_min/max for the MI2S DAIs.
+
+Fixes: 24c4cbcfac09 ("ASoC: qdsp6: q6afe: Add q6afe dai driver")
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20200415150050.616392-1-stephan@gerhold.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/qcom/qdsp6/q6afe-dai.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/sound/soc/qcom/qdsp6/q6afe-dai.c
++++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
+@@ -902,6 +902,8 @@ static struct snd_soc_dai_driver q6afe_d
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -917,6 +919,8 @@ static struct snd_soc_dai_driver q6afe_d
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -931,6 +935,8 @@ static struct snd_soc_dai_driver q6afe_d
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -946,6 +952,8 @@ static struct snd_soc_dai_driver q6afe_d
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -960,6 +968,8 @@ static struct snd_soc_dai_driver q6afe_d
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -975,6 +985,8 @@ static struct snd_soc_dai_driver q6afe_d
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -989,6 +1001,8 @@ static struct snd_soc_dai_driver q6afe_d
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+@@ -1004,6 +1018,8 @@ static struct snd_soc_dai_driver q6afe_d
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE,
++ .channels_min = 1,
++ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
--- /dev/null
+From 9df8ba7c63073508e5aa677dade48fcab6a6773e Mon Sep 17 00:00:00 2001
+From: Philipp Puschmann <p.puschmann@pironex.de>
+Date: Tue, 14 Apr 2020 13:27:54 +0200
+Subject: ASoC: tas571x: disable regulators on failed probe
+
+From: Philipp Puschmann <p.puschmann@pironex.de>
+
+commit 9df8ba7c63073508e5aa677dade48fcab6a6773e upstream.
+
+If probe fails after enabling the regulators regulator_put is called for
+each supply without having them disabled before. This produces some
+warnings like
+
+WARNING: CPU: 0 PID: 90 at drivers/regulator/core.c:2044 _regulator_put.part.0+0x154/0x15c
+[<c010f7a8>] (unwind_backtrace) from [<c010c544>] (show_stack+0x10/0x14)
+[<c010c544>] (show_stack) from [<c012b640>] (__warn+0xd0/0xf4)
+[<c012b640>] (__warn) from [<c012b9b4>] (warn_slowpath_fmt+0x64/0xc4)
+[<c012b9b4>] (warn_slowpath_fmt) from [<c04c4064>] (_regulator_put.part.0+0x154/0x15c)
+[<c04c4064>] (_regulator_put.part.0) from [<c04c4094>] (regulator_put+0x28/0x38)
+[<c04c4094>] (regulator_put) from [<c04c40cc>] (regulator_bulk_free+0x28/0x38)
+[<c04c40cc>] (regulator_bulk_free) from [<c0579b2c>] (release_nodes+0x1d0/0x22c)
+[<c0579b2c>] (release_nodes) from [<c05756dc>] (really_probe+0x108/0x34c)
+[<c05756dc>] (really_probe) from [<c0575aec>] (driver_probe_device+0xb8/0x16c)
+[<c0575aec>] (driver_probe_device) from [<c0575d40>] (device_driver_attach+0x58/0x60)
+[<c0575d40>] (device_driver_attach) from [<c0575da0>] (__driver_attach+0x58/0xcc)
+[<c0575da0>] (__driver_attach) from [<c0573978>] (bus_for_each_dev+0x78/0xc0)
+[<c0573978>] (bus_for_each_dev) from [<c0574b5c>] (bus_add_driver+0x188/0x1e0)
+[<c0574b5c>] (bus_add_driver) from [<c05768b0>] (driver_register+0x74/0x108)
+[<c05768b0>] (driver_register) from [<c061ab7c>] (i2c_register_driver+0x3c/0x88)
+[<c061ab7c>] (i2c_register_driver) from [<c0102df8>] (do_one_initcall+0x58/0x250)
+[<c0102df8>] (do_one_initcall) from [<c01a91bc>] (do_init_module+0x60/0x244)
+[<c01a91bc>] (do_init_module) from [<c01ab5a4>] (load_module+0x2180/0x2540)
+[<c01ab5a4>] (load_module) from [<c01abbd4>] (sys_finit_module+0xd0/0xe8)
+[<c01abbd4>] (sys_finit_module) from [<c01011e0>] (__sys_trace_return+0x0/0x20)
+
+Fixes: 3fd6e7d9a146 (ASoC: tas571x: New driver for TI TAS571x power amplifiers)
+Signed-off-by: Philipp Puschmann <p.puschmann@pironex.de>
+Link: https://lore.kernel.org/r/20200414112754.3365406-1-p.puschmann@pironex.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/tas571x.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/sound/soc/codecs/tas571x.c
++++ b/sound/soc/codecs/tas571x.c
+@@ -820,8 +820,10 @@ static int tas571x_i2c_probe(struct i2c_
+
+ priv->regmap = devm_regmap_init(dev, NULL, client,
+ priv->chip->regmap_config);
+- if (IS_ERR(priv->regmap))
+- return PTR_ERR(priv->regmap);
++ if (IS_ERR(priv->regmap)) {
++ ret = PTR_ERR(priv->regmap);
++ goto disable_regs;
++ }
+
+ priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW);
+ if (IS_ERR(priv->pdn_gpio)) {
+@@ -845,7 +847,7 @@ static int tas571x_i2c_probe(struct i2c_
+
+ ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);
+ if (ret)
+- return ret;
++ goto disable_regs;
+
+ usleep_range(50000, 60000);
+
+@@ -861,12 +863,20 @@ static int tas571x_i2c_probe(struct i2c_
+ */
+ ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0);
+ if (ret)
+- return ret;
++ goto disable_regs;
+ }
+
+- return devm_snd_soc_register_component(&client->dev,
++ ret = devm_snd_soc_register_component(&client->dev,
+ &priv->component_driver,
+ &tas571x_dai, 1);
++ if (ret)
++ goto disable_regs;
++
++ return ret;
++
++disable_regs:
++ regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
++ return ret;
+ }
+
+ static int tas571x_i2c_remove(struct i2c_client *client)
--- /dev/null
+From 1e060a453c8604311fb45ae2f84f67ed673329b4 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Tue, 21 Apr 2020 19:28:45 +0800
+Subject: ASoC: wm8960: Fix wrong clock after suspend & resume
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 1e060a453c8604311fb45ae2f84f67ed673329b4 upstream.
+
+After suspend & resume, wm8960_hw_params may be called when
+bias_level is not SND_SOC_BIAS_ON, then wm8960_configure_clocking
+is not called. But if sample rate is changed at that time, then
+the output clock rate will be not correct.
+
+So judgement of bias_level is SND_SOC_BIAS_ON in wm8960_hw_params
+is not necessary and it causes above issue.
+
+Fixes: 3176bf2d7ccd ("ASoC: wm8960: update pll and clock setting function")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/1587468525-27514-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm8960.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/sound/soc/codecs/wm8960.c
++++ b/sound/soc/codecs/wm8960.c
+@@ -860,8 +860,7 @@ static int wm8960_hw_params(struct snd_p
+
+ wm8960->is_stream_in_use[tx] = true;
+
+- if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON &&
+- !wm8960->is_stream_in_use[!tx])
++ if (!wm8960->is_stream_in_use[!tx])
+ return wm8960_configure_clocking(component);
+
+ return 0;
--- /dev/null
+From 6e7e63cbb023976d828cdb22422606bf77baa8a9 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Fri, 17 Apr 2020 02:00:06 +0200
+Subject: bpf: Forbid XADD on spilled pointers for unprivileged users
+
+From: Jann Horn <jannh@google.com>
+
+commit 6e7e63cbb023976d828cdb22422606bf77baa8a9 upstream.
+
+When check_xadd() verifies an XADD operation on a pointer to a stack slot
+containing a spilled pointer, check_stack_read() verifies that the read,
+which is part of XADD, is valid. However, since the placeholder value -1 is
+passed as `value_regno`, check_stack_read() can only return a binary
+decision and can't return the type of the value that was read. The intent
+here is to verify whether the value read from the stack slot may be used as
+a SCALAR_VALUE; but since check_stack_read() doesn't check the type, and
+the type information is lost when check_stack_read() returns, this is not
+enforced, and a malicious user can abuse XADD to leak spilled kernel
+pointers.
+
+Fix it by letting check_stack_read() verify that the value is usable as a
+SCALAR_VALUE if no type information is passed to the caller.
+
+To be able to use __is_pointer_value() in check_stack_read(), move it up.
+
+Fix up the expected unprivileged error message for a BPF selftest that,
+until now, assumed that unprivileged users can use XADD on stack-spilled
+pointers. This also gives us a test for the behavior introduced in this
+patch for free.
+
+In theory, this could also be fixed by forbidding XADD on stack spills
+entirely, since XADD is a locked operation (for operations on memory with
+concurrency) and there can't be any concurrency on the BPF stack; but
+Alexei has said that he wants to keep XADD on stack slots working to avoid
+changes to the test suite [1].
+
+The following BPF program demonstrates how to leak a BPF map pointer as an
+unprivileged user using this bug:
+
+ // r7 = map_pointer
+ BPF_LD_MAP_FD(BPF_REG_7, small_map),
+ // r8 = launder(map_pointer)
+ BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_7, -8),
+ BPF_MOV64_IMM(BPF_REG_1, 0),
+ ((struct bpf_insn) {
+ .code = BPF_STX | BPF_DW | BPF_XADD,
+ .dst_reg = BPF_REG_FP,
+ .src_reg = BPF_REG_1,
+ .off = -8
+ }),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_FP, -8),
+
+ // store r8 into map
+ BPF_MOV64_REG(BPF_REG_ARG1, BPF_REG_7),
+ BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -4),
+ BPF_ST_MEM(BPF_W, BPF_REG_ARG2, 0, 0),
+ BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+ BPF_EXIT_INSN(),
+ BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0),
+
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN()
+
+[1] https://lore.kernel.org/bpf/20200416211116.qxqcza5vo2ddnkdq@ast-mbp.dhcp.thefacebook.com/
+
+Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20200417000007.10734-1-jannh@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/bpf/verifier.c | 28 ++++++++++-----
+ tools/testing/selftests/bpf/verifier/value_illegal_alu.c | 1
+ 2 files changed, 20 insertions(+), 9 deletions(-)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1866,6 +1866,15 @@ static bool register_is_const(struct bpf
+ return reg->type == SCALAR_VALUE && tnum_is_const(reg->var_off);
+ }
+
++static bool __is_pointer_value(bool allow_ptr_leaks,
++ const struct bpf_reg_state *reg)
++{
++ if (allow_ptr_leaks)
++ return false;
++
++ return reg->type != SCALAR_VALUE;
++}
++
+ static void save_register_state(struct bpf_func_state *state,
+ int spi, struct bpf_reg_state *reg)
+ {
+@@ -2056,6 +2065,16 @@ static int check_stack_read(struct bpf_v
+ * which resets stack/reg liveness for state transitions
+ */
+ state->regs[value_regno].live |= REG_LIVE_WRITTEN;
++ } else if (__is_pointer_value(env->allow_ptr_leaks, reg)) {
++ /* If value_regno==-1, the caller is asking us whether
++ * it is acceptable to use this value as a SCALAR_VALUE
++ * (e.g. for XADD).
++ * We must not allow unprivileged callers to do that
++ * with spilled pointers.
++ */
++ verbose(env, "leaking pointer from stack off %d\n",
++ off);
++ return -EACCES;
+ }
+ mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
+ } else {
+@@ -2416,15 +2435,6 @@ static int check_sock_access(struct bpf_
+ return -EACCES;
+ }
+
+-static bool __is_pointer_value(bool allow_ptr_leaks,
+- const struct bpf_reg_state *reg)
+-{
+- if (allow_ptr_leaks)
+- return false;
+-
+- return reg->type != SCALAR_VALUE;
+-}
+-
+ static struct bpf_reg_state *reg_state(struct bpf_verifier_env *env, int regno)
+ {
+ return cur_regs(env) + regno;
+--- a/tools/testing/selftests/bpf/verifier/value_illegal_alu.c
++++ b/tools/testing/selftests/bpf/verifier/value_illegal_alu.c
+@@ -88,6 +88,7 @@
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map_hash_48b = { 3 },
++ .errstr_unpriv = "leaking pointer from stack off -8",
+ .errstr = "R0 invalid mem access 'inv'",
+ .result = REJECT,
+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
--- /dev/null
+From fc069262261c43ed11d639dadcf982e79bfe652b Mon Sep 17 00:00:00 2001
+From: Syed Nayyar Waris <syednwaris@gmail.com>
+Date: Mon, 16 Mar 2020 18:19:30 +0530
+Subject: counter: 104-quad-8: Add lock guards - generic interface
+
+From: Syed Nayyar Waris <syednwaris@gmail.com>
+
+commit fc069262261c43ed11d639dadcf982e79bfe652b upstream.
+
+Add lock protection from race conditions to 104-quad-8 counter driver
+generic interface code changes. Mutex calls used for protection.
+
+Fixes: f1d8a071d45b ("counter: 104-quad-8: Add Generic Counter interface support")
+
+Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
+Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/counter/104-quad-8.c | 194 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 160 insertions(+), 34 deletions(-)
+
+--- a/drivers/counter/104-quad-8.c
++++ b/drivers/counter/104-quad-8.c
+@@ -42,6 +42,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8
+ * @base: base port address of the IIO device
+ */
+ struct quad8_iio {
++ struct mutex lock;
+ struct counter_device counter;
+ unsigned int preset[QUAD8_NUM_COUNTERS];
+ unsigned int count_mode[QUAD8_NUM_COUNTERS];
+@@ -116,6 +117,8 @@ static int quad8_read_raw(struct iio_dev
+ /* Borrow XOR Carry effectively doubles count range */
+ *val = (borrow ^ carry) << 24;
+
++ mutex_lock(&priv->lock);
++
+ /* Reset Byte Pointer; transfer Counter to Output Latch */
+ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
+ base_offset + 1);
+@@ -123,6 +126,8 @@ static int quad8_read_raw(struct iio_dev
+ for (i = 0; i < 3; i++)
+ *val |= (unsigned int)inb(base_offset) << (8 * i);
+
++ mutex_unlock(&priv->lock);
++
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_ENABLE:
+ *val = priv->ab_enable[chan->channel];
+@@ -153,6 +158,8 @@ static int quad8_write_raw(struct iio_de
+ if ((unsigned int)val > 0xFFFFFF)
+ return -EINVAL;
+
++ mutex_lock(&priv->lock);
++
+ /* Reset Byte Pointer */
+ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+
+@@ -176,12 +183,16 @@ static int quad8_write_raw(struct iio_de
+ /* Reset Error flag */
+ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ case IIO_CHAN_INFO_ENABLE:
+ /* only boolean values accepted */
+ if (val < 0 || val > 1)
+ return -EINVAL;
+
++ mutex_lock(&priv->lock);
++
+ priv->ab_enable[chan->channel] = val;
+
+ ior_cfg = val | priv->preset_enable[chan->channel] << 1;
+@@ -189,11 +200,18 @@ static int quad8_write_raw(struct iio_de
+ /* Load I/O control configuration */
+ outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ case IIO_CHAN_INFO_SCALE:
++ mutex_lock(&priv->lock);
++
+ /* Quadrature scaling only available in quadrature mode */
+- if (!priv->quadrature_mode[chan->channel] && (val2 || val != 1))
++ if (!priv->quadrature_mode[chan->channel] &&
++ (val2 || val != 1)) {
++ mutex_unlock(&priv->lock);
+ return -EINVAL;
++ }
+
+ /* Only three gain states (1, 0.5, 0.25) */
+ if (val == 1 && !val2)
+@@ -207,11 +225,15 @@ static int quad8_write_raw(struct iio_de
+ priv->quadrature_scale[chan->channel] = 2;
+ break;
+ default:
++ mutex_unlock(&priv->lock);
+ return -EINVAL;
+ }
+- else
++ else {
++ mutex_unlock(&priv->lock);
+ return -EINVAL;
++ }
+
++ mutex_unlock(&priv->lock);
+ return 0;
+ }
+
+@@ -248,6 +270,8 @@ static ssize_t quad8_write_preset(struct
+ if (preset > 0xFFFFFF)
+ return -EINVAL;
+
++ mutex_lock(&priv->lock);
++
+ priv->preset[chan->channel] = preset;
+
+ /* Reset Byte Pointer */
+@@ -257,6 +281,8 @@ static ssize_t quad8_write_preset(struct
+ for (i = 0; i < 3; i++)
+ outb(preset >> (8 * i), base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return len;
+ }
+
+@@ -286,6 +312,8 @@ static ssize_t quad8_write_set_to_preset
+ /* Preset enable is active low in Input/Output Control register */
+ preset_enable = !preset_enable;
+
++ mutex_lock(&priv->lock);
++
+ priv->preset_enable[chan->channel] = preset_enable;
+
+ ior_cfg = priv->ab_enable[chan->channel] |
+@@ -294,6 +322,8 @@ static ssize_t quad8_write_set_to_preset
+ /* Load I/O control configuration to Input / Output Control Register */
+ outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return len;
+ }
+
+@@ -351,6 +381,8 @@ static int quad8_set_count_mode(struct i
+ unsigned int mode_cfg = cnt_mode << 1;
+ const int base_offset = priv->base + 2 * chan->channel + 1;
+
++ mutex_lock(&priv->lock);
++
+ priv->count_mode[chan->channel] = cnt_mode;
+
+ /* Add quadrature mode configuration */
+@@ -360,6 +392,8 @@ static int quad8_set_count_mode(struct i
+ /* Load mode configuration to Counter Mode Register */
+ outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -387,19 +421,26 @@ static int quad8_set_synchronous_mode(st
+ const struct iio_chan_spec *chan, unsigned int synchronous_mode)
+ {
+ struct quad8_iio *const priv = iio_priv(indio_dev);
+- const unsigned int idr_cfg = synchronous_mode |
+- priv->index_polarity[chan->channel] << 1;
+ const int base_offset = priv->base + 2 * chan->channel + 1;
++ unsigned int idr_cfg = synchronous_mode;
++
++ mutex_lock(&priv->lock);
++
++ idr_cfg |= priv->index_polarity[chan->channel] << 1;
+
+ /* Index function must be non-synchronous in non-quadrature mode */
+- if (synchronous_mode && !priv->quadrature_mode[chan->channel])
++ if (synchronous_mode && !priv->quadrature_mode[chan->channel]) {
++ mutex_unlock(&priv->lock);
+ return -EINVAL;
++ }
+
+ priv->synchronous_mode[chan->channel] = synchronous_mode;
+
+ /* Load Index Control configuration to Index Control Register */
+ outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -427,8 +468,12 @@ static int quad8_set_quadrature_mode(str
+ const struct iio_chan_spec *chan, unsigned int quadrature_mode)
+ {
+ struct quad8_iio *const priv = iio_priv(indio_dev);
+- unsigned int mode_cfg = priv->count_mode[chan->channel] << 1;
+ const int base_offset = priv->base + 2 * chan->channel + 1;
++ unsigned int mode_cfg;
++
++ mutex_lock(&priv->lock);
++
++ mode_cfg = priv->count_mode[chan->channel] << 1;
+
+ if (quadrature_mode)
+ mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3;
+@@ -446,6 +491,8 @@ static int quad8_set_quadrature_mode(str
+ /* Load mode configuration to Counter Mode Register */
+ outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -473,15 +520,20 @@ static int quad8_set_index_polarity(stru
+ const struct iio_chan_spec *chan, unsigned int index_polarity)
+ {
+ struct quad8_iio *const priv = iio_priv(indio_dev);
+- const unsigned int idr_cfg = priv->synchronous_mode[chan->channel] |
+- index_polarity << 1;
+ const int base_offset = priv->base + 2 * chan->channel + 1;
++ unsigned int idr_cfg = index_polarity << 1;
++
++ mutex_lock(&priv->lock);
++
++ idr_cfg |= priv->synchronous_mode[chan->channel];
+
+ priv->index_polarity[chan->channel] = index_polarity;
+
+ /* Load Index Control configuration to Index Control Register */
+ outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -585,7 +637,7 @@ static int quad8_signal_read(struct coun
+ static int quad8_count_read(struct counter_device *counter,
+ struct counter_count *count, struct counter_count_read_value *val)
+ {
+- const struct quad8_iio *const priv = counter->priv;
++ struct quad8_iio *const priv = counter->priv;
+ const int base_offset = priv->base + 2 * count->id;
+ unsigned int flags;
+ unsigned int borrow;
+@@ -600,6 +652,8 @@ static int quad8_count_read(struct count
+ /* Borrow XOR Carry effectively doubles count range */
+ position = (unsigned long)(borrow ^ carry) << 24;
+
++ mutex_lock(&priv->lock);
++
+ /* Reset Byte Pointer; transfer Counter to Output Latch */
+ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
+ base_offset + 1);
+@@ -609,13 +663,15 @@ static int quad8_count_read(struct count
+
+ counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &position);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+ static int quad8_count_write(struct counter_device *counter,
+ struct counter_count *count, struct counter_count_write_value *val)
+ {
+- const struct quad8_iio *const priv = counter->priv;
++ struct quad8_iio *const priv = counter->priv;
+ const int base_offset = priv->base + 2 * count->id;
+ int err;
+ unsigned long position;
+@@ -630,6 +686,8 @@ static int quad8_count_write(struct coun
+ if (position > 0xFFFFFF)
+ return -EINVAL;
+
++ mutex_lock(&priv->lock);
++
+ /* Reset Byte Pointer */
+ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+
+@@ -653,6 +711,8 @@ static int quad8_count_write(struct coun
+ /* Reset Error flag */
+ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -673,13 +733,13 @@ static enum counter_count_function quad8
+ static int quad8_function_get(struct counter_device *counter,
+ struct counter_count *count, size_t *function)
+ {
+- const struct quad8_iio *const priv = counter->priv;
++ struct quad8_iio *const priv = counter->priv;
+ const int id = count->id;
+- const unsigned int quadrature_mode = priv->quadrature_mode[id];
+- const unsigned int scale = priv->quadrature_scale[id];
+
+- if (quadrature_mode)
+- switch (scale) {
++ mutex_lock(&priv->lock);
++
++ if (priv->quadrature_mode[id])
++ switch (priv->quadrature_scale[id]) {
+ case 0:
+ *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1;
+ break;
+@@ -693,6 +753,8 @@ static int quad8_function_get(struct cou
+ else
+ *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION;
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -703,10 +765,15 @@ static int quad8_function_set(struct cou
+ const int id = count->id;
+ unsigned int *const quadrature_mode = priv->quadrature_mode + id;
+ unsigned int *const scale = priv->quadrature_scale + id;
+- unsigned int mode_cfg = priv->count_mode[id] << 1;
+ unsigned int *const synchronous_mode = priv->synchronous_mode + id;
+- const unsigned int idr_cfg = priv->index_polarity[id] << 1;
+ const int base_offset = priv->base + 2 * id + 1;
++ unsigned int mode_cfg;
++ unsigned int idr_cfg;
++
++ mutex_lock(&priv->lock);
++
++ mode_cfg = priv->count_mode[id] << 1;
++ idr_cfg = priv->index_polarity[id] << 1;
+
+ if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) {
+ *quadrature_mode = 0;
+@@ -742,6 +809,8 @@ static int quad8_function_set(struct cou
+ /* Load mode configuration to Counter Mode Register */
+ outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -858,15 +927,20 @@ static int quad8_index_polarity_set(stru
+ {
+ struct quad8_iio *const priv = counter->priv;
+ const size_t channel_id = signal->id - 16;
+- const unsigned int idr_cfg = priv->synchronous_mode[channel_id] |
+- index_polarity << 1;
+ const int base_offset = priv->base + 2 * channel_id + 1;
++ unsigned int idr_cfg = index_polarity << 1;
++
++ mutex_lock(&priv->lock);
++
++ idr_cfg |= priv->synchronous_mode[channel_id];
+
+ priv->index_polarity[channel_id] = index_polarity;
+
+ /* Load Index Control configuration to Index Control Register */
+ outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -893,19 +967,26 @@ static int quad8_synchronous_mode_set(st
+ {
+ struct quad8_iio *const priv = counter->priv;
+ const size_t channel_id = signal->id - 16;
+- const unsigned int idr_cfg = synchronous_mode |
+- priv->index_polarity[channel_id] << 1;
+ const int base_offset = priv->base + 2 * channel_id + 1;
++ unsigned int idr_cfg = synchronous_mode;
++
++ mutex_lock(&priv->lock);
++
++ idr_cfg |= priv->index_polarity[channel_id] << 1;
+
+ /* Index function must be non-synchronous in non-quadrature mode */
+- if (synchronous_mode && !priv->quadrature_mode[channel_id])
++ if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
++ mutex_unlock(&priv->lock);
+ return -EINVAL;
++ }
+
+ priv->synchronous_mode[channel_id] = synchronous_mode;
+
+ /* Load Index Control configuration to Index Control Register */
+ outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -970,6 +1051,8 @@ static int quad8_count_mode_set(struct c
+ break;
+ }
+
++ mutex_lock(&priv->lock);
++
+ priv->count_mode[count->id] = cnt_mode;
+
+ /* Set count mode configuration value */
+@@ -982,6 +1065,8 @@ static int quad8_count_mode_set(struct c
+ /* Load mode configuration to Counter Mode Register */
+ outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return 0;
+ }
+
+@@ -1023,6 +1108,8 @@ static ssize_t quad8_count_enable_write(
+ if (err)
+ return err;
+
++ mutex_lock(&priv->lock);
++
+ priv->ab_enable[count->id] = ab_enable;
+
+ ior_cfg = ab_enable | priv->preset_enable[count->id] << 1;
+@@ -1030,6 +1117,8 @@ static ssize_t quad8_count_enable_write(
+ /* Load I/O control configuration */
+ outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
+
++ mutex_unlock(&priv->lock);
++
+ return len;
+ }
+
+@@ -1058,14 +1147,28 @@ static ssize_t quad8_count_preset_read(s
+ return sprintf(buf, "%u\n", priv->preset[count->id]);
+ }
+
++static void quad8_preset_register_set(struct quad8_iio *quad8iio, int id,
++ unsigned int preset)
++{
++ const unsigned int base_offset = quad8iio->base + 2 * id;
++ int i;
++
++ quad8iio->preset[id] = preset;
++
++ /* Reset Byte Pointer */
++ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++
++ /* Set Preset Register */
++ for (i = 0; i < 3; i++)
++ outb(preset >> (8 * i), base_offset);
++}
++
+ static ssize_t quad8_count_preset_write(struct counter_device *counter,
+ struct counter_count *count, void *private, const char *buf, size_t len)
+ {
+ struct quad8_iio *const priv = counter->priv;
+- const int base_offset = priv->base + 2 * count->id;
+ unsigned int preset;
+ int ret;
+- int i;
+
+ ret = kstrtouint(buf, 0, &preset);
+ if (ret)
+@@ -1075,14 +1178,11 @@ static ssize_t quad8_count_preset_write(
+ if (preset > 0xFFFFFF)
+ return -EINVAL;
+
+- priv->preset[count->id] = preset;
++ mutex_lock(&priv->lock);
+
+- /* Reset Byte Pointer */
+- outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++ quad8_preset_register_set(priv, count->id, preset);
+
+- /* Set Preset Register */
+- for (i = 0; i < 3; i++)
+- outb(preset >> (8 * i), base_offset);
++ mutex_unlock(&priv->lock);
+
+ return len;
+ }
+@@ -1090,15 +1190,20 @@ static ssize_t quad8_count_preset_write(
+ static ssize_t quad8_count_ceiling_read(struct counter_device *counter,
+ struct counter_count *count, void *private, char *buf)
+ {
+- const struct quad8_iio *const priv = counter->priv;
++ struct quad8_iio *const priv = counter->priv;
++
++ mutex_lock(&priv->lock);
+
+ /* Range Limit and Modulo-N count modes use preset value as ceiling */
+ switch (priv->count_mode[count->id]) {
+ case 1:
+ case 3:
+- return quad8_count_preset_read(counter, count, private, buf);
++ mutex_unlock(&priv->lock);
++ return sprintf(buf, "%u\n", priv->preset[count->id]);
+ }
+
++ mutex_unlock(&priv->lock);
++
+ /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
+ return sprintf(buf, "33554431\n");
+ }
+@@ -1107,15 +1212,29 @@ static ssize_t quad8_count_ceiling_write
+ struct counter_count *count, void *private, const char *buf, size_t len)
+ {
+ struct quad8_iio *const priv = counter->priv;
++ unsigned int ceiling;
++ int ret;
++
++ ret = kstrtouint(buf, 0, &ceiling);
++ if (ret)
++ return ret;
++
++ /* Only 24-bit values are supported */
++ if (ceiling > 0xFFFFFF)
++ return -EINVAL;
++
++ mutex_lock(&priv->lock);
+
+ /* Range Limit and Modulo-N count modes use preset value as ceiling */
+ switch (priv->count_mode[count->id]) {
+ case 1:
+ case 3:
+- return quad8_count_preset_write(counter, count, private, buf,
+- len);
++ quad8_preset_register_set(priv, count->id, ceiling);
++ break;
+ }
+
++ mutex_unlock(&priv->lock);
++
+ return len;
+ }
+
+@@ -1143,6 +1262,8 @@ static ssize_t quad8_count_preset_enable
+ /* Preset enable is active low in Input/Output Control register */
+ preset_enable = !preset_enable;
+
++ mutex_lock(&priv->lock);
++
+ priv->preset_enable[count->id] = preset_enable;
+
+ ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1;
+@@ -1150,6 +1271,8 @@ static ssize_t quad8_count_preset_enable
+ /* Load I/O control configuration to Input / Output Control Register */
+ outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
+
++ mutex_unlock(&priv->lock);
++
+ return len;
+ }
+
+@@ -1320,6 +1443,9 @@ static int quad8_probe(struct device *de
+ quad8iio->counter.priv = quad8iio;
+ quad8iio->base = base[id];
+
++ /* Initialize mutex */
++ mutex_init(&quad8iio->lock);
++
+ /* Reset all counters and disable interrupt function */
+ outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
+ /* Set initial configuration for all counters */
--- /dev/null
+From d0384eedcde21276ac51f57c641f875605024b32 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 8 Apr 2020 17:52:15 +0200
+Subject: drivers: soc: xilinx: fix firmware driver Kconfig dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit d0384eedcde21276ac51f57c641f875605024b32 upstream.
+
+The firmware driver is optional, but the power driver depends on it,
+which needs to be reflected in Kconfig to avoid link errors:
+
+aarch64-linux-ld: drivers/soc/xilinx/zynqmp_power.o: in function `zynqmp_pm_isr':
+zynqmp_power.c:(.text+0x284): undefined reference to `zynqmp_pm_invoke_fn'
+
+The firmware driver can probably be allowed for compile-testing as
+well, so it's best to drop the dependency on the ZYNQ platform
+here and allow building as long as the firmware code is built-in.
+
+Fixes: ab272643d723 ("drivers: soc: xilinx: Add ZynqMP PM driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20200408155224.2070880-1-arnd@arndb.de
+Signed-off-by: Michal Simek <michal.simek@xilinx.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/soc/xilinx/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/soc/xilinx/Kconfig
++++ b/drivers/soc/xilinx/Kconfig
+@@ -19,7 +19,7 @@ config XILINX_VCU
+
+ config ZYNQMP_POWER
+ bool "Enable Xilinx Zynq MPSoC Power Management driver"
+- depends on PM && ARCH_ZYNQMP
++ depends on PM && ZYNQMP_FIRMWARE
+ default y
+ help
+ Say yes to enable power management support for ZyqnMP SoC.
+@@ -31,7 +31,7 @@ config ZYNQMP_POWER
+ config ZYNQMP_PM_DOMAINS
+ bool "Enable Zynq MPSoC generic PM domains"
+ default y
+- depends on PM && ARCH_ZYNQMP && ZYNQMP_FIRMWARE
++ depends on PM && ZYNQMP_FIRMWARE
+ select PM_GENERIC_DOMAINS
+ help
+ Say yes to enable device power management through PM domains
--- /dev/null
+From 28535877ac5b2b84f0d394fd67a5ec71c0c48b10 Mon Sep 17 00:00:00 2001
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Tue, 10 Mar 2020 22:16:54 +0800
+Subject: iio:ad7797: Use correct attribute_group
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+commit 28535877ac5b2b84f0d394fd67a5ec71c0c48b10 upstream.
+
+It should use ad7797_attribute_group in ad7797_info,
+according to commit ("iio:ad7793: Add support for the ad7796 and ad7797").
+
+Scale is fixed for the ad7796 and not programmable, hence
+should not have the scale_available attribute.
+
+Fixes: fd1a8b912841 ("iio:ad7793: Add support for the ad7796 and ad7797")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ad7793.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/ad7793.c
++++ b/drivers/iio/adc/ad7793.c
+@@ -541,7 +541,7 @@ static const struct iio_info ad7797_info
+ .read_raw = &ad7793_read_raw,
+ .write_raw = &ad7793_write_raw,
+ .write_raw_get_fmt = &ad7793_write_raw_get_fmt,
+- .attrs = &ad7793_attribute_group,
++ .attrs = &ad7797_attribute_group,
+ .validate_trigger = ad_sd_validate_trigger,
+ };
+
--- /dev/null
+From 3d4b2238684ac919394eba7fb51bb7eeeec6ab57 Mon Sep 17 00:00:00 2001
+From: Masahiro Yamada <masahiroy@kernel.org>
+Date: Tue, 21 Apr 2020 12:35:28 +0900
+Subject: kbuild: fix DT binding schema rule again to avoid needless rebuilds
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+commit 3d4b2238684ac919394eba7fb51bb7eeeec6ab57 upstream.
+
+Since commit 7a0496056064 ("kbuild: fix DT binding schema rule to detect
+command line changes"), this rule is every time re-run even if you change
+nothing.
+
+cmd_dtc takes one additional parameter to pass to the -O option of dtc.
+
+We need to pass 'yaml' to if_changed_rule. Otherwise, cmd-check invoked
+from if_changed_rule is false positive.
+
+Fixes: 7a0496056064 ("kbuild: fix DT binding schema rule to detect command line changes")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ scripts/Makefile.lib | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -297,7 +297,7 @@ define rule_dtc
+ endef
+
+ $(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
+- $(call if_changed_rule,dtc)
++ $(call if_changed_rule,dtc,yaml)
+
+ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
+
--- /dev/null
+From e1e8399eee72e9d5246d4d1bcacd793debe34dd3 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Fri, 27 Mar 2020 07:50:40 +0300
+Subject: nfsd: memory corruption in nfsd4_lock()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit e1e8399eee72e9d5246d4d1bcacd793debe34dd3 upstream.
+
+New struct nfsd4_blocked_lock allocated in find_or_allocate_block()
+does not initialized nbl_list and nbl_lru.
+If conflock allocation fails rollback can call list_del_init()
+access uninitialized fields and corrupt memory.
+
+v2: just initialize nbl_list and nbl_lru right after nbl allocation.
+
+Fixes: 76d348fadff5 ("nfsd: have nfsd4_lock use blocking locks for v4.1+ lock")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4state.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -266,6 +266,8 @@ find_or_allocate_block(struct nfs4_locko
+ if (!nbl) {
+ nbl= kmalloc(sizeof(*nbl), GFP_KERNEL);
+ if (nbl) {
++ INIT_LIST_HEAD(&nbl->nbl_list);
++ INIT_LIST_HEAD(&nbl->nbl_lru);
+ fh_copy_shallow(&nbl->nbl_fh, fh);
+ locks_init_lock(&nbl->nbl_lock);
+ nfsd4_init_cb(&nbl->nbl_cb, lo->lo_owner.so_client,
--- /dev/null
+From b0d3869ce9eeacbb1bbd541909beeef4126426d5 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Mon, 27 Apr 2020 10:26:22 -0400
+Subject: propagate_one(): mnt_set_mountpoint() needs mount_lock
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit b0d3869ce9eeacbb1bbd541909beeef4126426d5 upstream.
+
+... to protect the modification of mp->m_count done by it. Most of
+the places that modify that thing also have namespace_lock held,
+but not all of them can do so, so we really need mount_lock here.
+Kudos to Piotr Krysiuk <piotras@gmail.com>, who'd spotted a related
+bug in pivot_root(2) (fixed unnoticed in 5.3); search for other
+similar turds has caught out this one.
+
+Cc: stable@kernel.org
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/pnode.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/fs/pnode.c
++++ b/fs/pnode.c
+@@ -261,14 +261,13 @@ static int propagate_one(struct mount *m
+ child = copy_tree(last_source, last_source->mnt.mnt_root, type);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
++ read_seqlock_excl(&mount_lock);
+ mnt_set_mountpoint(m, mp, child);
++ if (m->mnt_master != dest_master)
++ SET_MNT_MARK(m->mnt_master);
++ read_sequnlock_excl(&mount_lock);
+ last_dest = m;
+ last_source = child;
+- if (m->mnt_master != dest_master) {
+- read_seqlock_excl(&mount_lock);
+- SET_MNT_MARK(m->mnt_master);
+- read_sequnlock_excl(&mount_lock);
+- }
+ hlist_add_head(&child->mnt_hash, list);
+ return count_mounts(m->mnt_ns, child);
+ }
--- /dev/null
+From 8ebf6da9db1b2a20bb86cc1bee2552e894d03308 Mon Sep 17 00:00:00 2001
+From: Philipp Rudo <prudo@linux.ibm.com>
+Date: Mon, 6 Apr 2020 14:47:48 +0200
+Subject: s390/ftrace: fix potential crashes when switching tracers
+
+From: Philipp Rudo <prudo@linux.ibm.com>
+
+commit 8ebf6da9db1b2a20bb86cc1bee2552e894d03308 upstream.
+
+Switching tracers include instruction patching. To prevent that a
+instruction is patched while it's read the instruction patching is done
+in stop_machine 'context'. This also means that any function called
+during stop_machine must not be traced. Thus add 'notrace' to all
+functions called within stop_machine.
+
+Fixes: 1ec2772e0c3c ("s390/diag: add a statistic for diagnose calls")
+Fixes: 38f2c691a4b3 ("s390: improve wait logic of stop_machine")
+Fixes: 4ecf0a43e729 ("processor: get rid of cpu_relax_yield")
+Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kernel/diag.c | 2 +-
+ arch/s390/kernel/smp.c | 4 ++--
+ arch/s390/kernel/trace.c | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/s390/kernel/diag.c
++++ b/arch/s390/kernel/diag.c
+@@ -133,7 +133,7 @@ void diag_stat_inc(enum diag_stat_enum n
+ }
+ EXPORT_SYMBOL(diag_stat_inc);
+
+-void diag_stat_inc_norecursion(enum diag_stat_enum nr)
++void notrace diag_stat_inc_norecursion(enum diag_stat_enum nr)
+ {
+ this_cpu_inc(diag_stat.counter[nr]);
+ trace_s390_diagnose_norecursion(diag_map[nr].code);
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -403,7 +403,7 @@ int smp_find_processor_id(u16 address)
+ return -1;
+ }
+
+-bool arch_vcpu_is_preempted(int cpu)
++bool notrace arch_vcpu_is_preempted(int cpu)
+ {
+ if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
+ return false;
+@@ -413,7 +413,7 @@ bool arch_vcpu_is_preempted(int cpu)
+ }
+ EXPORT_SYMBOL(arch_vcpu_is_preempted);
+
+-void smp_yield_cpu(int cpu)
++void notrace smp_yield_cpu(int cpu)
+ {
+ if (MACHINE_HAS_DIAG9C) {
+ diag_stat_inc_norecursion(DIAG_STAT_X09C);
+--- a/arch/s390/kernel/trace.c
++++ b/arch/s390/kernel/trace.c
+@@ -14,7 +14,7 @@ EXPORT_TRACEPOINT_SYMBOL(s390_diagnose);
+
+ static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
+
+-void trace_s390_diagnose_norecursion(int diag_nr)
++void notrace trace_s390_diagnose_norecursion(int diag_nr)
+ {
+ unsigned long flags;
+ unsigned int *depth;
ubifs-fix-ubifs_tnc_lookup-usage-in-do_kill_orphans.patch
printk-queue-wake_up_klogd-irq_work-only-if-per-cpu-areas-are-ready.patch
asoc-stm32-sai-fix-sai-probe.patch
+usb-dwc3-gadget-do-link-recovery-for-ss-and-ssp.patch
+kbuild-fix-dt-binding-schema-rule-again-to-avoid-needless-rebuilds.patch
+usb-gadget-udc-bdc-remove-unnecessary-null-checks-in-bdc_req_complete.patch
+usb-gadget-udc-atmel-fix-vbus-disconnect-handling.patch
+afs-make-record-checking-use-task_uninterruptible-when-appropriate.patch
+afs-fix-to-actually-set-afs_server_fl_have_epoch.patch
+iio-ad7797-use-correct-attribute_group.patch
+propagate_one-mnt_set_mountpoint-needs-mount_lock.patch
+counter-104-quad-8-add-lock-guards-generic-interface.patch
+s390-ftrace-fix-potential-crashes-when-switching-tracers.patch
+asoc-q6dsp6-q6afe-dai-add-missing-channels-to-mi2s-dais.patch
+asoc-tas571x-disable-regulators-on-failed-probe.patch
+asoc-meson-axg-card-fix-codec-to-codec-link-setup.patch
+asoc-wm8960-fix-wrong-clock-after-suspend-resume.patch
+drivers-soc-xilinx-fix-firmware-driver-kconfig-dependency.patch
+nfsd-memory-corruption-in-nfsd4_lock.patch
+bpf-forbid-xadd-on-spilled-pointers-for-unprivileged-users.patch
--- /dev/null
+From d0550cd20e52558ecf6847a0f96ebd5d944c17e4 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Fri, 31 Jan 2020 16:25:50 -0800
+Subject: usb: dwc3: gadget: Do link recovery for SS and SSP
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit d0550cd20e52558ecf6847a0f96ebd5d944c17e4 upstream.
+
+The controller always supports link recovery for device in SS and SSP.
+Remove the speed limit check. Also, when the device is in RESUME or
+RESET state, it means the controller received the resume/reset request.
+The driver must send the link recovery to acknowledge the request. They
+are valid states for the driver to send link recovery.
+
+Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
+Fixes: ee5cd41c9117 ("usb: dwc3: Update speed checks for SuperSpeedPlus")
+Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1725,7 +1725,6 @@ static int __dwc3_gadget_wakeup(struct d
+ u32 reg;
+
+ u8 link_state;
+- u8 speed;
+
+ /*
+ * According to the Databook Remote wakeup request should
+@@ -1735,16 +1734,13 @@ static int __dwc3_gadget_wakeup(struct d
+ */
+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+
+- speed = reg & DWC3_DSTS_CONNECTSPD;
+- if ((speed == DWC3_DSTS_SUPERSPEED) ||
+- (speed == DWC3_DSTS_SUPERSPEED_PLUS))
+- return 0;
+-
+ link_state = DWC3_DSTS_USBLNKST(reg);
+
+ switch (link_state) {
++ case DWC3_LINK_STATE_RESET:
+ case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */
+ case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */
++ case DWC3_LINK_STATE_RESUME:
+ break;
+ default:
+ return -EINVAL;
--- /dev/null
+From 12b94da411f9c6d950beb067d913024fd5617a61 Mon Sep 17 00:00:00 2001
+From: Cristian Birsan <cristian.birsan@microchip.com>
+Date: Fri, 10 Apr 2020 15:14:52 +0300
+Subject: usb: gadget: udc: atmel: Fix vbus disconnect handling
+
+From: Cristian Birsan <cristian.birsan@microchip.com>
+
+commit 12b94da411f9c6d950beb067d913024fd5617a61 upstream.
+
+A DMA transfer can be in progress while vbus is lost due to a cable
+disconnect. For endpoints that use DMA, this condition can lead to
+peripheral hang. The patch ensures that endpoints are disabled before
+the clocks are stopped to prevent this issue.
+
+Fixes: a64ef71ddc13 ("usb: gadget: atmel_usba_udc: condition clocks to vbus state")
+Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/atmel_usba_udc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
++++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
+@@ -1950,10 +1950,10 @@ static irqreturn_t usba_vbus_irq_thread(
+ usba_start(udc);
+ } else {
+ udc->suspended = false;
+- usba_stop(udc);
+-
+ if (udc->driver->disconnect)
+ udc->driver->disconnect(&udc->gadget);
++
++ usba_stop(udc);
+ }
+ udc->vbus_prev = vbus;
+ }
--- /dev/null
+From 09b04abb70f096333bef6bc95fa600b662e7ee13 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <natechancellor@gmail.com>
+Date: Sat, 28 Mar 2020 18:12:46 -0700
+Subject: usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete
+
+From: Nathan Chancellor <natechancellor@gmail.com>
+
+commit 09b04abb70f096333bef6bc95fa600b662e7ee13 upstream.
+
+When building with Clang + -Wtautological-pointer-compare:
+
+drivers/usb/gadget/udc/bdc/bdc_ep.c:543:28: warning: comparison of
+address of 'req->queue' equal to a null pointer is always false
+[-Wtautological-pointer-compare]
+ if (req == NULL || &req->queue == NULL || &req->usb_req == NULL)
+ ~~~~~^~~~~ ~~~~
+drivers/usb/gadget/udc/bdc/bdc_ep.c:543:51: warning: comparison of
+address of 'req->usb_req' equal to a null pointer is always false
+[-Wtautological-pointer-compare]
+ if (req == NULL || &req->queue == NULL || &req->usb_req == NULL)
+ ~~~~~^~~~~~~ ~~~~
+2 warnings generated.
+
+As it notes, these statements will always evaluate to false so remove
+them.
+
+Fixes: efed421a94e6 ("usb: gadget: Add UDC driver for Broadcom USB3.0 device controller IP BDC")
+Link: https://github.com/ClangBuiltLinux/linux/issues/749
+Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/bdc/bdc_ep.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/udc/bdc/bdc_ep.c
++++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c
+@@ -540,7 +540,7 @@ static void bdc_req_complete(struct bdc_
+ {
+ struct bdc *bdc = ep->bdc;
+
+- if (req == NULL || &req->queue == NULL || &req->usb_req == NULL)
++ if (req == NULL)
+ return;
+
+ dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);