]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.20-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Feb 2019 12:40:19 +0000 (13:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Feb 2019 12:40:19 +0000 (13:40 +0100)
added patches:
alsa-compress-fix-stop-handling-on-compressed-capture-streams.patch
alsa-hda-realtek-fix-lose-hp_pins-for-disable-auto-mute.patch
alsa-hda-realtek-headset-microphone-support-for-system76-darp5.patch
alsa-hda-realtek-use-a-common-helper-for-hp-pin-reference.patch
alsa-hda-serialize-codec-registrations.patch
alsa-usb-audio-add-support-for-new-t-a-usb-dac.patch
cuse-fix-ioctl.patch
fuse-call-pipe_buf_release-under-pipe-lock.patch
fuse-decrement-nr_writeback_temp-on-the-right-page.patch
fuse-handle-zero-sized-retrieve-correctly.patch
hid-debug-fix-the-ring-buffer-implementation.patch
xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cached.patch

13 files changed:
queue-4.20/alsa-compress-fix-stop-handling-on-compressed-capture-streams.patch [new file with mode: 0644]
queue-4.20/alsa-hda-realtek-fix-lose-hp_pins-for-disable-auto-mute.patch [new file with mode: 0644]
queue-4.20/alsa-hda-realtek-headset-microphone-support-for-system76-darp5.patch [new file with mode: 0644]
queue-4.20/alsa-hda-realtek-use-a-common-helper-for-hp-pin-reference.patch [new file with mode: 0644]
queue-4.20/alsa-hda-serialize-codec-registrations.patch [new file with mode: 0644]
queue-4.20/alsa-usb-audio-add-support-for-new-t-a-usb-dac.patch [new file with mode: 0644]
queue-4.20/cuse-fix-ioctl.patch [new file with mode: 0644]
queue-4.20/fuse-call-pipe_buf_release-under-pipe-lock.patch [new file with mode: 0644]
queue-4.20/fuse-decrement-nr_writeback_temp-on-the-right-page.patch [new file with mode: 0644]
queue-4.20/fuse-handle-zero-sized-retrieve-correctly.patch [new file with mode: 0644]
queue-4.20/hid-debug-fix-the-ring-buffer-implementation.patch [new file with mode: 0644]
queue-4.20/series
queue-4.20/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cached.patch [new file with mode: 0644]

diff --git a/queue-4.20/alsa-compress-fix-stop-handling-on-compressed-capture-streams.patch b/queue-4.20/alsa-compress-fix-stop-handling-on-compressed-capture-streams.patch
new file mode 100644 (file)
index 0000000..68d66f1
--- /dev/null
@@ -0,0 +1,51 @@
+From 4f2ab5e1d13d6aa77c55f4914659784efd776eb4 Mon Sep 17 00:00:00 2001
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+Date: Tue, 5 Feb 2019 16:29:40 +0000
+Subject: ALSA: compress: Fix stop handling on compressed capture streams
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+commit 4f2ab5e1d13d6aa77c55f4914659784efd776eb4 upstream.
+
+It is normal user behaviour to start, stop, then start a stream
+again without closing it. Currently this works for compressed
+playback streams but not capture ones.
+
+The states on a compressed capture stream go directly from OPEN to
+PREPARED, unlike a playback stream which moves to SETUP and waits
+for a write of data before moving to PREPARED. Currently however,
+when a stop is sent the state is set to SETUP for both types of
+streams. This leaves a capture stream in the situation where a new
+start can't be sent as that requires the state to be PREPARED and
+a new set_params can't be sent as that requires the state to be
+OPEN. The only option being to close the stream, and then reopen.
+
+Correct this issues by allowing snd_compr_drain_notify to set the
+state depending on the stream direction, as we already do in
+set_params.
+
+Fixes: 49bb6402f1aa ("ALSA: compress_core: Add support for capture streams")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/sound/compress_driver.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/sound/compress_driver.h
++++ b/include/sound/compress_driver.h
+@@ -171,7 +171,11 @@ static inline void snd_compr_drain_notif
+       if (snd_BUG_ON(!stream))
+               return;
+-      stream->runtime->state = SNDRV_PCM_STATE_SETUP;
++      if (stream->direction == SND_COMPRESS_PLAYBACK)
++              stream->runtime->state = SNDRV_PCM_STATE_SETUP;
++      else
++              stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
++
+       wake_up(&stream->runtime->sleep);
+ }
diff --git a/queue-4.20/alsa-hda-realtek-fix-lose-hp_pins-for-disable-auto-mute.patch b/queue-4.20/alsa-hda-realtek-fix-lose-hp_pins-for-disable-auto-mute.patch
new file mode 100644 (file)
index 0000000..903a579
--- /dev/null
@@ -0,0 +1,135 @@
+From d561aa0a70bb2e1dd85fde98b6a5561e4175ac3e Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Fri, 1 Feb 2019 16:51:10 +0800
+Subject: ALSA: hda/realtek - Fix lose hp_pins for disable auto mute
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit d561aa0a70bb2e1dd85fde98b6a5561e4175ac3e upstream.
+
+When auto_mute = no or spec->suppress_auto_mute = 1, cfg->hp_pins will
+lose value.
+
+Add this patch to find hp_pins value.
+I add fixed for ALC282 ALC225 ALC256 ALC294 and alc_default_init()
+alc_default_shutup().
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   45 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2963,6 +2963,11 @@ static void alc282_init(struct hda_codec
+       bool hp_pin_sense;
+       int coef78;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       alc282_restore_default_value(codec);
+       if (!hp_pin)
+@@ -3000,6 +3005,11 @@ static void alc282_shutup(struct hda_cod
+       bool hp_pin_sense;
+       int coef78;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3159,6 +3169,11 @@ static void alc256_init(struct hda_codec
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       bool hp_pin_sense;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin)
+               return;
+@@ -3195,6 +3210,11 @@ static void alc256_shutup(struct hda_cod
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       bool hp_pin_sense;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3231,6 +3251,11 @@ static void alc225_init(struct hda_codec
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       bool hp1_pin_sense, hp2_pin_sense;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin)
+               return;
+@@ -3274,6 +3299,11 @@ static void alc225_shutup(struct hda_cod
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       bool hp1_pin_sense, hp2_pin_sense;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3318,6 +3348,11 @@ static void alc_default_init(struct hda_
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       bool hp_pin_sense;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin)
+               return;
+@@ -3347,6 +3382,11 @@ static void alc_default_shutup(struct hd
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       bool hp_pin_sense;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3379,6 +3419,11 @@ static void alc294_hp_init(struct hda_co
+       hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+       int i, val;
++      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++                      hp_pin = spec->gen.autocfg.line_out_pins[0];
++      }
++
+       if (!hp_pin)
+               return;
diff --git a/queue-4.20/alsa-hda-realtek-headset-microphone-support-for-system76-darp5.patch b/queue-4.20/alsa-hda-realtek-headset-microphone-support-for-system76-darp5.patch
new file mode 100644 (file)
index 0000000..320e0d3
--- /dev/null
@@ -0,0 +1,60 @@
+From 89e3a5682edaa4e5bb334719afb180256ac7bf78 Mon Sep 17 00:00:00 2001
+From: Jeremy Soller <jeremy@system76.com>
+Date: Wed, 30 Jan 2019 16:12:31 -0700
+Subject: ALSA: hda/realtek - Headset microphone support for System76 darp5
+
+From: Jeremy Soller <jeremy@system76.com>
+
+commit 89e3a5682edaa4e5bb334719afb180256ac7bf78 upstream.
+
+On the System76 Darter Pro (darp5), there is a headset microphone
+input attached to 0x1a that does not have a jack detect.  In order to
+get it working, the pin configuration needs to be set correctly, and
+the ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC fixup needs to be applied.
+This is similar to the MIC_NO_PRESENCE fixups for some Dell laptops,
+except we have a separate microphone jack that is already configured
+correctly.
+
+Signed-off-by: Jeremy Soller <jeremy@system76.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5572,6 +5572,7 @@ enum {
+       ALC294_FIXUP_ASUS_MIC,
+       ALC294_FIXUP_ASUS_HEADSET_MIC,
+       ALC294_FIXUP_ASUS_SPK,
++      ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
+ };
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -6496,6 +6497,15 @@ static const struct hda_fixup alc269_fix
+               .chained = true,
+               .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
+       },
++      [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -6674,6 +6684,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
++      SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
+       SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
diff --git a/queue-4.20/alsa-hda-realtek-use-a-common-helper-for-hp-pin-reference.patch b/queue-4.20/alsa-hda-realtek-use-a-common-helper-for-hp-pin-reference.patch
new file mode 100644 (file)
index 0000000..6f5f4c5
--- /dev/null
@@ -0,0 +1,257 @@
+From 35a39f98567d8d3f1cea48f0f30de1a7e736b644 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 1 Feb 2019 11:19:50 +0100
+Subject: ALSA: hda/realtek - Use a common helper for hp pin reference
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 35a39f98567d8d3f1cea48f0f30de1a7e736b644 upstream.
+
+Replace the open-codes in many places with a new common helper for
+performing the same thing: referring to the primary headphone pin.
+
+This eventually fixes the potentially missing headphone pin on some
+weird devices, too.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   96 ++++++++++--------------------------------
+ 1 file changed, 24 insertions(+), 72 deletions(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -515,6 +515,15 @@ static void alc_auto_init_amp(struct hda
+       }
+ }
++/* get a primary headphone pin if available */
++static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
++{
++      if (spec->gen.autocfg.hp_pins[0])
++              return spec->gen.autocfg.hp_pins[0];
++      if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++              return spec->gen.autocfg.line_out_pins[0];
++      return 0;
++}
+ /*
+  * Realtek SSID verification
+@@ -725,9 +734,7 @@ do_sku:
+        * 15   : 1 --> enable the function "Mute internal speaker
+        *              when the external headphone out jack is plugged"
+        */
+-      if (!spec->gen.autocfg.hp_pins[0] &&
+-          !(spec->gen.autocfg.line_out_pins[0] &&
+-            spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
++      if (!alc_get_hp_pin(spec)) {
+               hda_nid_t nid;
+               tmp = (ass >> 11) & 0x3;        /* HP to chassis */
+               nid = ports[tmp];
+@@ -2959,15 +2966,10 @@ static void alc282_restore_default_value
+ static void alc282_init(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+       int coef78;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       alc282_restore_default_value(codec);
+       if (!hp_pin)
+@@ -3001,15 +3003,10 @@ static void alc282_init(struct hda_codec
+ static void alc282_shutup(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+       int coef78;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3084,14 +3081,9 @@ static void alc283_restore_default_value
+ static void alc283_init(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       alc283_restore_default_value(codec);
+       if (!hp_pin)
+@@ -3125,14 +3117,9 @@ static void alc283_init(struct hda_codec
+ static void alc283_shutup(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3166,14 +3153,9 @@ static void alc283_shutup(struct hda_cod
+ static void alc256_init(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin)
+               return;
+@@ -3207,14 +3189,9 @@ static void alc256_init(struct hda_codec
+ static void alc256_shutup(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3248,14 +3225,9 @@ static void alc256_shutup(struct hda_cod
+ static void alc225_init(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp1_pin_sense, hp2_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin)
+               return;
+@@ -3296,14 +3268,9 @@ static void alc225_init(struct hda_codec
+ static void alc225_shutup(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp1_pin_sense, hp2_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3345,14 +3312,9 @@ static void alc225_shutup(struct hda_cod
+ static void alc_default_init(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin)
+               return;
+@@ -3379,14 +3341,9 @@ static void alc_default_init(struct hda_
+ static void alc_default_shutup(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin) {
+               alc269_shutup(codec);
+               return;
+@@ -3416,14 +3373,9 @@ static void alc_default_shutup(struct hd
+ static void alc294_hp_init(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       int i, val;
+-      if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+-              if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+-                      hp_pin = spec->gen.autocfg.line_out_pins[0];
+-      }
+-
+       if (!hp_pin)
+               return;
+@@ -4825,7 +4777,7 @@ static void alc_update_headset_mode(stru
+       struct alc_spec *spec = codec->spec;
+       hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
+-      hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++      hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       int new_headset_mode;
+@@ -5104,7 +5056,7 @@ static void alc_fixup_tpt470_dock(struct
+ static void alc_shutup_dell_xps13(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+-      int hp_pin = spec->gen.autocfg.hp_pins[0];
++      int hp_pin = alc_get_hp_pin(spec);
+       /* Prevent pop noises when headphones are plugged in */
+       snd_hda_codec_write(codec, hp_pin, 0,
+@@ -5197,7 +5149,7 @@ static void alc271_hp_gate_mic_jack(stru
+       if (action == HDA_FIXUP_ACT_PROBE) {
+               int mic_pin = find_ext_mic_pin(codec);
+-              int hp_pin = spec->gen.autocfg.hp_pins[0];
++              int hp_pin = alc_get_hp_pin(spec);
+               if (snd_BUG_ON(!mic_pin || !hp_pin))
+                       return;
diff --git a/queue-4.20/alsa-hda-serialize-codec-registrations.patch b/queue-4.20/alsa-hda-serialize-codec-registrations.patch
new file mode 100644 (file)
index 0000000..e158c33
--- /dev/null
@@ -0,0 +1,70 @@
+From 305a0ade180981686eec1f92aa6252a7c6ebb1cf Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 30 Jan 2019 17:46:03 +0100
+Subject: ALSA: hda - Serialize codec registrations
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 305a0ade180981686eec1f92aa6252a7c6ebb1cf upstream.
+
+In the current code, the codec registration may happen both at the
+codec bind time and the end of the controller probe time.  In a rare
+occasion, they race with each other, leading to Oops due to the still
+uninitialized card device.
+
+This patch introduces a simple flag to prevent the codec registration
+at the codec bind time as long as the controller probe is going on.
+The controller probe invokes snd_card_register() that does the whole
+registration task, and we don't need to register each piece
+beforehand.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/sound/hda_codec.h |    1 +
+ sound/pci/hda/hda_bind.c  |    3 ++-
+ sound/pci/hda/hda_intel.c |    2 ++
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/sound/hda_codec.h
++++ b/include/sound/hda_codec.h
+@@ -68,6 +68,7 @@ struct hda_bus {
+       unsigned int response_reset:1;  /* controller was reset */
+       unsigned int in_reset:1;        /* during reset operation */
+       unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
++      unsigned int bus_probing :1;    /* during probing process */
+       int primary_dig_out_type;       /* primary digital out PCM type */
+       unsigned int mixer_assigned;    /* codec addr for mixer name */
+--- a/sound/pci/hda/hda_bind.c
++++ b/sound/pci/hda/hda_bind.c
+@@ -115,7 +115,8 @@ static int hda_codec_driver_probe(struct
+       err = snd_hda_codec_build_controls(codec);
+       if (err < 0)
+               goto error_module;
+-      if (codec->card->registered) {
++      /* only register after the bus probe finished; otherwise it's racy */
++      if (!codec->bus->bus_probing && codec->card->registered) {
+               err = snd_card_register(codec->card);
+               if (err < 0)
+                       goto error_module;
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2228,6 +2228,7 @@ static int azx_probe_continue(struct azx
+       int dev = chip->dev_index;
+       int err;
++      to_hda_bus(bus)->bus_probing = 1;
+       hda->probe_continued = 1;
+       /* bind with i915 if needed */
+@@ -2323,6 +2324,7 @@ i915_power_fail:
+       if (err < 0)
+               hda->init_failed = 1;
+       complete_all(&hda->probe_wait);
++      to_hda_bus(bus)->bus_probing = 0;
+       return err;
+ }
diff --git a/queue-4.20/alsa-usb-audio-add-support-for-new-t-a-usb-dac.patch b/queue-4.20/alsa-usb-audio-add-support-for-new-t-a-usb-dac.patch
new file mode 100644 (file)
index 0000000..00805e3
--- /dev/null
@@ -0,0 +1,33 @@
+From 3bff2407fbd28fd55ad5b5cccd98fc0c9598f23b Mon Sep 17 00:00:00 2001
+From: Udo Eberhardt <udo.eberhardt@thesycon.de>
+Date: Tue, 5 Feb 2019 17:20:47 +0100
+Subject: ALSA: usb-audio: Add support for new T+A USB DAC
+
+From: Udo Eberhardt <udo.eberhardt@thesycon.de>
+
+commit 3bff2407fbd28fd55ad5b5cccd98fc0c9598f23b upstream.
+
+This patch adds the T+A VID to the generic check in order to enable
+native DSD support for T+A devices. This works with the new T+A USB
+DAC model SD3100HV and will also work with future devices which
+support the XMOS/Thesycon style DSD format.
+
+Signed-off-by: Udo Eberhardt <udo.eberhardt@thesycon.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/quirks.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1448,6 +1448,7 @@ u64 snd_usb_interface_dsd_format_quirks(
+       case 0x20b1:  /* XMOS based devices */
+       case 0x152a:  /* Thesycon devices */
+       case 0x25ce:  /* Mytek devices */
++      case 0x2ab6:  /* T+A devices */
+               if (fp->dsd_raw)
+                       return SNDRV_PCM_FMTBIT_DSD_U32_BE;
+               break;
diff --git a/queue-4.20/cuse-fix-ioctl.patch b/queue-4.20/cuse-fix-ioctl.patch
new file mode 100644 (file)
index 0000000..e1f8f31
--- /dev/null
@@ -0,0 +1,40 @@
+From 8a3177db59cd644fde05ba9efee29392dfdec8aa Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 16 Jan 2019 10:27:59 +0100
+Subject: cuse: fix ioctl
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 8a3177db59cd644fde05ba9efee29392dfdec8aa upstream.
+
+cuse_process_init_reply() doesn't initialize fc->max_pages and thus all
+cuse bases ioctls fail with ENOMEM.
+
+Reported-by: Andreas Steinmetz <ast@domdv.de>
+Fixes: 5da784cce430 ("fuse: add max_pages to init_out")
+Cc: <stable@vger.kernel.org> # v4.20
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/inode.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -628,6 +628,7 @@ void fuse_conn_init(struct fuse_conn *fc
+       get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
+       fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
+       fc->user_ns = get_user_ns(user_ns);
++      fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
+ }
+ EXPORT_SYMBOL_GPL(fuse_conn_init);
+@@ -1162,7 +1163,6 @@ static int fuse_fill_super(struct super_
+       fc->user_id = d.user_id;
+       fc->group_id = d.group_id;
+       fc->max_read = max_t(unsigned, 4096, d.max_read);
+-      fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
+       /* Used by get_root_inode() */
+       sb->s_fs_info = fc;
diff --git a/queue-4.20/fuse-call-pipe_buf_release-under-pipe-lock.patch b/queue-4.20/fuse-call-pipe_buf_release-under-pipe-lock.patch
new file mode 100644 (file)
index 0000000..1ee632b
--- /dev/null
@@ -0,0 +1,40 @@
+From 9509941e9c534920ccc4771ae70bd6cbbe79df1c Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Sat, 12 Jan 2019 02:39:05 +0100
+Subject: fuse: call pipe_buf_release() under pipe lock
+
+From: Jann Horn <jannh@google.com>
+
+commit 9509941e9c534920ccc4771ae70bd6cbbe79df1c upstream.
+
+Some of the pipe_buf_release() handlers seem to assume that the pipe is
+locked - in particular, anon_pipe_buf_release() accesses pipe->tmp_page
+without taking any extra locks. From a glance through the callers of
+pipe_buf_release(), it looks like FUSE is the only one that calls
+pipe_buf_release() without having the pipe locked.
+
+This bug should only lead to a memory leak, nothing terrible.
+
+Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -2077,8 +2077,10 @@ static ssize_t fuse_dev_splice_write(str
+       ret = fuse_dev_do_write(fud, &cs, len);
++      pipe_lock(pipe);
+       for (idx = 0; idx < nbuf; idx++)
+               pipe_buf_release(pipe, &bufs[idx]);
++      pipe_unlock(pipe);
+ out:
+       kvfree(bufs);
diff --git a/queue-4.20/fuse-decrement-nr_writeback_temp-on-the-right-page.patch b/queue-4.20/fuse-decrement-nr_writeback_temp-on-the-right-page.patch
new file mode 100644 (file)
index 0000000..b25a7a6
--- /dev/null
@@ -0,0 +1,32 @@
+From a2ebba824106dabe79937a9f29a875f837e1b6d4 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 16 Jan 2019 10:27:59 +0100
+Subject: fuse: decrement NR_WRITEBACK_TEMP on the right page
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit a2ebba824106dabe79937a9f29a875f837e1b6d4 upstream.
+
+NR_WRITEBACK_TEMP is accounted on the temporary page in the request, not
+the page cache page.
+
+Fixes: 8b284dc47291 ("fuse: writepages: handle same page rewrites")
+Cc: <stable@vger.kernel.org> # v3.13
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/file.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1782,7 +1782,7 @@ static bool fuse_writepage_in_flight(str
+               spin_unlock(&fc->lock);
+               dec_wb_stat(&bdi->wb, WB_WRITEBACK);
+-              dec_node_page_state(page, NR_WRITEBACK_TEMP);
++              dec_node_page_state(new_req->pages[0], NR_WRITEBACK_TEMP);
+               wb_writeout_inc(&bdi->wb);
+               fuse_writepage_free(fc, new_req);
+               fuse_request_free(new_req);
diff --git a/queue-4.20/fuse-handle-zero-sized-retrieve-correctly.patch b/queue-4.20/fuse-handle-zero-sized-retrieve-correctly.patch
new file mode 100644 (file)
index 0000000..02691f4
--- /dev/null
@@ -0,0 +1,40 @@
+From 97e1532ef81acb31c30f9e75bf00306c33a77812 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 16 Jan 2019 10:27:59 +0100
+Subject: fuse: handle zero sized retrieve correctly
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 97e1532ef81acb31c30f9e75bf00306c33a77812 upstream.
+
+Dereferencing req->page_descs[0] will Oops if req->max_pages is zero.
+
+Reported-by: syzbot+c1e36d30ee3416289cc0@syzkaller.appspotmail.com
+Tested-by: syzbot+c1e36d30ee3416289cc0@syzkaller.appspotmail.com
+Fixes: b2430d7567a3 ("fuse: add per-page descriptor <offset, length> to fuse_req")
+Cc: <stable@vger.kernel.org> # v3.9
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -1742,7 +1742,6 @@ static int fuse_retrieve(struct fuse_con
+       req->in.h.nodeid = outarg->nodeid;
+       req->in.numargs = 2;
+       req->in.argpages = 1;
+-      req->page_descs[0].offset = offset;
+       req->end = fuse_retrieve_end;
+       index = outarg->offset >> PAGE_SHIFT;
+@@ -1757,6 +1756,7 @@ static int fuse_retrieve(struct fuse_con
+               this_num = min_t(unsigned, num, PAGE_SIZE - offset);
+               req->pages[req->num_pages] = page;
++              req->page_descs[req->num_pages].offset = offset;
+               req->page_descs[req->num_pages].length = this_num;
+               req->num_pages++;
diff --git a/queue-4.20/hid-debug-fix-the-ring-buffer-implementation.patch b/queue-4.20/hid-debug-fix-the-ring-buffer-implementation.patch
new file mode 100644 (file)
index 0000000..da24da5
--- /dev/null
@@ -0,0 +1,257 @@
+From 13054abbaa4f1fd4e6f3b4b63439ec033b4c8035 Mon Sep 17 00:00:00 2001
+From: Vladis Dronov <vdronov@redhat.com>
+Date: Tue, 29 Jan 2019 11:58:35 +0100
+Subject: HID: debug: fix the ring buffer implementation
+
+From: Vladis Dronov <vdronov@redhat.com>
+
+commit 13054abbaa4f1fd4e6f3b4b63439ec033b4c8035 upstream.
+
+Ring buffer implementation in hid_debug_event() and hid_debug_events_read()
+is strange allowing lost or corrupted data. After commit 717adfdaf147
+("HID: debug: check length before copy_to_user()") it is possible to enter
+an infinite loop in hid_debug_events_read() by providing 0 as count, this
+locks up a system. Fix this by rewriting the ring buffer implementation
+with kfifo and simplify the code.
+
+This fixes CVE-2019-3819.
+
+v2: fix an execution logic and add a comment
+v3: use __set_current_state() instead of set_current_state()
+
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=1669187
+Cc: stable@vger.kernel.org # v4.18+
+Fixes: cd667ce24796 ("HID: use debugfs for events/reports dumping")
+Fixes: 717adfdaf147 ("HID: debug: check length before copy_to_user()")
+Signed-off-by: Vladis Dronov <vdronov@redhat.com>
+Reviewed-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-debug.c   |  120 ++++++++++++++++++----------------------------
+ include/linux/hid-debug.h |    9 +--
+ 2 files changed, 51 insertions(+), 78 deletions(-)
+
+--- a/drivers/hid/hid-debug.c
++++ b/drivers/hid/hid-debug.c
+@@ -30,6 +30,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
++#include <linux/kfifo.h>
+ #include <linux/sched/signal.h>
+ #include <linux/export.h>
+ #include <linux/slab.h>
+@@ -661,17 +662,12 @@ EXPORT_SYMBOL_GPL(hid_dump_device);
+ /* enqueue string to 'events' ring buffer */
+ void hid_debug_event(struct hid_device *hdev, char *buf)
+ {
+-      unsigned i;
+       struct hid_debug_list *list;
+       unsigned long flags;
+       spin_lock_irqsave(&hdev->debug_list_lock, flags);
+-      list_for_each_entry(list, &hdev->debug_list, node) {
+-              for (i = 0; buf[i]; i++)
+-                      list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] =
+-                              buf[i];
+-              list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
+-        }
++      list_for_each_entry(list, &hdev->debug_list, node)
++              kfifo_in(&list->hid_debug_fifo, buf, strlen(buf));
+       spin_unlock_irqrestore(&hdev->debug_list_lock, flags);
+       wake_up_interruptible(&hdev->debug_wait);
+@@ -722,8 +718,7 @@ void hid_dump_input(struct hid_device *h
+       hid_debug_event(hdev, buf);
+       kfree(buf);
+-        wake_up_interruptible(&hdev->debug_wait);
+-
++      wake_up_interruptible(&hdev->debug_wait);
+ }
+ EXPORT_SYMBOL_GPL(hid_dump_input);
+@@ -1088,8 +1083,8 @@ static int hid_debug_events_open(struct
+               goto out;
+       }
+-      if (!(list->hid_debug_buf = kzalloc(HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
+-              err = -ENOMEM;
++      err = kfifo_alloc(&list->hid_debug_fifo, HID_DEBUG_FIFOSIZE, GFP_KERNEL);
++      if (err) {
+               kfree(list);
+               goto out;
+       }
+@@ -1109,77 +1104,57 @@ static ssize_t hid_debug_events_read(str
+               size_t count, loff_t *ppos)
+ {
+       struct hid_debug_list *list = file->private_data;
+-      int ret = 0, len;
++      int ret = 0, copied;
+       DECLARE_WAITQUEUE(wait, current);
+       mutex_lock(&list->read_mutex);
+-      while (ret == 0) {
+-              if (list->head == list->tail) {
+-                      add_wait_queue(&list->hdev->debug_wait, &wait);
+-                      set_current_state(TASK_INTERRUPTIBLE);
+-
+-                      while (list->head == list->tail) {
+-                              if (file->f_flags & O_NONBLOCK) {
+-                                      ret = -EAGAIN;
+-                                      break;
+-                              }
+-                              if (signal_pending(current)) {
+-                                      ret = -ERESTARTSYS;
+-                                      break;
+-                              }
+-
+-                              if (!list->hdev || !list->hdev->debug) {
+-                                      ret = -EIO;
+-                                      set_current_state(TASK_RUNNING);
+-                                      goto out;
+-                              }
+-
+-                              /* allow O_NONBLOCK from other threads */
+-                              mutex_unlock(&list->read_mutex);
+-                              schedule();
+-                              mutex_lock(&list->read_mutex);
+-                              set_current_state(TASK_INTERRUPTIBLE);
++      if (kfifo_is_empty(&list->hid_debug_fifo)) {
++              add_wait_queue(&list->hdev->debug_wait, &wait);
++              set_current_state(TASK_INTERRUPTIBLE);
++
++              while (kfifo_is_empty(&list->hid_debug_fifo)) {
++                      if (file->f_flags & O_NONBLOCK) {
++                              ret = -EAGAIN;
++                              break;
+                       }
+-                      set_current_state(TASK_RUNNING);
+-                      remove_wait_queue(&list->hdev->debug_wait, &wait);
+-              }
+-
+-              if (ret)
+-                      goto out;
+-
+-              /* pass the ringbuffer contents to userspace */
+-copy_rest:
+-              if (list->tail == list->head)
+-                      goto out;
+-              if (list->tail > list->head) {
+-                      len = list->tail - list->head;
+-                      if (len > count)
+-                              len = count;
+-
+-                      if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
+-                              ret = -EFAULT;
+-                              goto out;
++                      if (signal_pending(current)) {
++                              ret = -ERESTARTSYS;
++                              break;
+                       }
+-                      ret += len;
+-                      list->head += len;
+-              } else {
+-                      len = HID_DEBUG_BUFSIZE - list->head;
+-                      if (len > count)
+-                              len = count;
+-                      if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
+-                              ret = -EFAULT;
++                      /* if list->hdev is NULL we cannot remove_wait_queue().
++                       * if list->hdev->debug is 0 then hid_debug_unregister()
++                       * was already called and list->hdev is being destroyed.
++                       * if we add remove_wait_queue() here we can hit a race.
++                       */
++                      if (!list->hdev || !list->hdev->debug) {
++                              ret = -EIO;
++                              set_current_state(TASK_RUNNING);
+                               goto out;
+                       }
+-                      list->head = 0;
+-                      ret += len;
+-                      count -= len;
+-                      if (count > 0)
+-                              goto copy_rest;
++
++                      /* allow O_NONBLOCK from other threads */
++                      mutex_unlock(&list->read_mutex);
++                      schedule();
++                      mutex_lock(&list->read_mutex);
++                      set_current_state(TASK_INTERRUPTIBLE);
+               }
++              __set_current_state(TASK_RUNNING);
++              remove_wait_queue(&list->hdev->debug_wait, &wait);
++
++              if (ret)
++                      goto out;
+       }
++
++      /* pass the fifo content to userspace, locking is not needed with only
++       * one concurrent reader and one concurrent writer
++       */
++      ret = kfifo_to_user(&list->hid_debug_fifo, buffer, count, &copied);
++      if (ret)
++              goto out;
++      ret = copied;
+ out:
+       mutex_unlock(&list->read_mutex);
+       return ret;
+@@ -1190,7 +1165,7 @@ static __poll_t hid_debug_events_poll(st
+       struct hid_debug_list *list = file->private_data;
+       poll_wait(file, &list->hdev->debug_wait, wait);
+-      if (list->head != list->tail)
++      if (!kfifo_is_empty(&list->hid_debug_fifo))
+               return EPOLLIN | EPOLLRDNORM;
+       if (!list->hdev->debug)
+               return EPOLLERR | EPOLLHUP;
+@@ -1205,7 +1180,7 @@ static int hid_debug_events_release(stru
+       spin_lock_irqsave(&list->hdev->debug_list_lock, flags);
+       list_del(&list->node);
+       spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);
+-      kfree(list->hid_debug_buf);
++      kfifo_free(&list->hid_debug_fifo);
+       kfree(list);
+       return 0;
+@@ -1256,4 +1231,3 @@ void hid_debug_exit(void)
+ {
+       debugfs_remove_recursive(hid_debug_root);
+ }
+-
+--- a/include/linux/hid-debug.h
++++ b/include/linux/hid-debug.h
+@@ -24,7 +24,10 @@
+ #ifdef CONFIG_DEBUG_FS
++#include <linux/kfifo.h>
++
+ #define HID_DEBUG_BUFSIZE 512
++#define HID_DEBUG_FIFOSIZE 512
+ void hid_dump_input(struct hid_device *, struct hid_usage *, __s32);
+ void hid_dump_report(struct hid_device *, int , u8 *, int);
+@@ -37,11 +40,8 @@ void hid_debug_init(void);
+ void hid_debug_exit(void);
+ void hid_debug_event(struct hid_device *, char *);
+-
+ struct hid_debug_list {
+-      char *hid_debug_buf;
+-      int head;
+-      int tail;
++      DECLARE_KFIFO_PTR(hid_debug_fifo, char);
+       struct fasync_struct *fasync;
+       struct hid_device *hdev;
+       struct list_head node;
+@@ -64,4 +64,3 @@ struct hid_debug_list {
+ #endif
+ #endif
+-
index 4d3c21d6446b4dbde89c763cc807cbf3b100e166..71c1ddf5a500f89c564383b8990cc03b41df0f0d 100644 (file)
@@ -310,3 +310,15 @@ net-cls_flower-remove-filter-from-mask-before-freeing-it.patch
 net-dsa-b53-fix-for-failure-when-irq-is-not-defined-in-dt.patch
 net-mlx5e-use-the-inner-headers-to-determine-tc-pedit-offload-limitation-on-decap-flows.patch
 net-mlx5e-force-checksum_unnecessary-for-short-ethernet-frames.patch
+xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cached.patch
+alsa-compress-fix-stop-handling-on-compressed-capture-streams.patch
+alsa-usb-audio-add-support-for-new-t-a-usb-dac.patch
+alsa-hda-serialize-codec-registrations.patch
+alsa-hda-realtek-fix-lose-hp_pins-for-disable-auto-mute.patch
+alsa-hda-realtek-use-a-common-helper-for-hp-pin-reference.patch
+alsa-hda-realtek-headset-microphone-support-for-system76-darp5.patch
+fuse-call-pipe_buf_release-under-pipe-lock.patch
+fuse-decrement-nr_writeback_temp-on-the-right-page.patch
+fuse-handle-zero-sized-retrieve-correctly.patch
+cuse-fix-ioctl.patch
+hid-debug-fix-the-ring-buffer-implementation.patch
diff --git a/queue-4.20/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cached.patch b/queue-4.20/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cached.patch
new file mode 100644 (file)
index 0000000..bcb8fa4
--- /dev/null
@@ -0,0 +1,64 @@
+From aa6ee4ab69293969867ab09b57546d226ace3d7a Mon Sep 17 00:00:00 2001
+From: Brian Foster <bfoster@redhat.com>
+Date: Fri, 1 Feb 2019 09:36:36 -0800
+Subject: xfs: eof trim writeback mapping as soon as it is cached
+
+From: Brian Foster <bfoster@redhat.com>
+
+commit aa6ee4ab69293969867ab09b57546d226ace3d7a upstream.
+
+The cached writeback mapping is EOF trimmed to try and avoid races
+between post-eof block management and writeback that result in
+sending cached data to a stale location. The cached mapping is
+currently trimmed on the validation check, which leaves a race
+window between the time the mapping is cached and when it is trimmed
+against the current inode size.
+
+For example, if a new mapping is cached by delalloc conversion on a
+blocksize == page size fs, we could cycle various locks, perform
+memory allocations, etc.  in the writeback codepath before the
+associated mapping is eventually trimmed to i_size. This leaves
+enough time for a post-eof truncate and file append before the
+cached mapping is trimmed. The former event essentially invalidates
+a range of the cached mapping and the latter bumps the inode size
+such the trim on the next writepage event won't trim all of the
+invalid blocks. fstest generic/464 reproduces this scenario
+occasionally and causes a lost writeback and stale delalloc blocks
+warning on inode inactivation.
+
+To work around this problem, trim the cached writeback mapping as
+soon as it is cached in addition to on subsequent validation checks.
+This is a minor tweak to tighten the race window as much as possible
+until a proper invalidation mechanism is available.
+
+Fixes: 40214d128e07 ("xfs: trim writepage mapping to within eof")
+Cc: <stable@vger.kernel.org> # v4.14+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_aops.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -449,6 +449,7 @@ xfs_map_blocks(
+       }
+       wpc->imap = imap;
++      xfs_trim_extent_eof(&wpc->imap, ip);
+       trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap);
+       return 0;
+ allocate_blocks:
+@@ -459,6 +460,7 @@ allocate_blocks:
+       ASSERT(whichfork == XFS_COW_FORK || cow_fsb == NULLFILEOFF ||
+              imap.br_startoff + imap.br_blockcount <= cow_fsb);
+       wpc->imap = imap;
++      xfs_trim_extent_eof(&wpc->imap, ip);
+       trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap);
+       return 0;
+ }