]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.14
authorSasha Levin <sashal@kernel.org>
Sun, 28 Jun 2020 22:14:14 +0000 (18:14 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 28 Jun 2020 22:14:14 +0000 (18:14 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.14/alsa-usb-audio-clean-up-mixer-element-list-traverse.patch [new file with mode: 0644]
queue-4.14/alsa-usb-audio-fix-oob-access-of-mixer-element-list.patch [new file with mode: 0644]
queue-4.14/alsa-usb-audio-uac1-invalidate-ctl-on-interrupt.patch [new file with mode: 0644]
queue-4.14/cifs-smb3-fix-data-inconsistent-when-punch-hole.patch [new file with mode: 0644]
queue-4.14/cifs-smb3-fix-data-inconsistent-when-zero-file-range.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/xhci-poll-for-u0-after-disabling-usb2-lpm.patch [new file with mode: 0644]

diff --git a/queue-4.14/alsa-usb-audio-clean-up-mixer-element-list-traverse.patch b/queue-4.14/alsa-usb-audio-clean-up-mixer-element-list-traverse.patch
new file mode 100644 (file)
index 0000000..609e7f2
--- /dev/null
@@ -0,0 +1,159 @@
+From 7235fe0ab22d32e7800a3651c63974be4f19a4cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 May 2018 12:33:32 +0200
+Subject: ALSA: usb-audio: Clean up mixer element list traverse
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 8c558076c740e8009a96c6fdc3d4245dde62be77 ]
+
+Introduce a new macro for iterating over mixer element list for
+avoiding the open codes in many places.  Also the open-coded
+container_of() and the forced cast to struct usb_mixer_elem_info are
+replaced with another simple macro, too.
+
+No functional changes but just readability improvement.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer.c          | 20 +++++++++-----------
+ sound/usb/mixer.h          |  6 ++++++
+ sound/usb/mixer_quirks.c   |  2 +-
+ sound/usb/mixer_scarlett.c |  6 ++----
+ 4 files changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index 33deb5ec8b7a1..1a8d706491e65 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -2403,9 +2403,9 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
+ {
+       struct usb_mixer_elem_list *list;
+-      for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) {
++      for_each_mixer_elem(list, mixer, unitid) {
+               struct usb_mixer_elem_info *info =
+-                      (struct usb_mixer_elem_info *)list;
++                      mixer_elem_list_to_info(list);
+               /* invalidate cache, so the value is read from the device */
+               info->cached = 0;
+               snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+@@ -2416,7 +2416,7 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
+ static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
+                                   struct usb_mixer_elem_list *list)
+ {
+-      struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list;
++      struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
+       static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
+                                   "S8", "U8", "S16", "U16"};
+       snd_iprintf(buffer, "    Info: id=%i, control=%i, cmask=0x%x, "
+@@ -2442,8 +2442,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
+                               mixer->ignore_ctl_error);
+               snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
+               for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
+-                      for (list = mixer->id_elems[unitid]; list;
+-                           list = list->next_id_elem) {
++                      for_each_mixer_elem(list, mixer, unitid) {
+                               snd_iprintf(buffer, "  Unit: %i\n", list->id);
+                               if (list->kctl)
+                                       snd_iprintf(buffer,
+@@ -2473,19 +2472,19 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
+               return;
+       }
+-      for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem)
++      for_each_mixer_elem(list, mixer, unitid)
+               count++;
+       if (count == 0)
+               return;
+-      for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) {
++      for_each_mixer_elem(list, mixer, unitid) {
+               struct usb_mixer_elem_info *info;
+               if (!list->kctl)
+                       continue;
+-              info = (struct usb_mixer_elem_info *)list;
++              info = mixer_elem_list_to_info(list);
+               if (count > 1 && info->control != control)
+                       continue;
+@@ -2705,7 +2704,7 @@ int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer)
+ static int restore_mixer_value(struct usb_mixer_elem_list *list)
+ {
+-      struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list;
++      struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
+       int c, err, idx;
+       if (cval->cmask) {
+@@ -2741,8 +2740,7 @@ int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
+       if (reset_resume) {
+               /* restore cached mixer values */
+               for (id = 0; id < MAX_ID_ELEMS; id++) {
+-                      for (list = mixer->id_elems[id]; list;
+-                           list = list->next_id_elem) {
++                      for_each_mixer_elem(list, mixer, id) {
+                               if (list->resume) {
+                                       err = list->resume(list);
+                                       if (err < 0)
+diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
+index ba27f7ade670e..e02653465e292 100644
+--- a/sound/usb/mixer.h
++++ b/sound/usb/mixer.h
+@@ -53,6 +53,12 @@ struct usb_mixer_elem_list {
+       usb_mixer_elem_resume_func_t resume;
+ };
++/* iterate over mixer element list of the given unit id */
++#define for_each_mixer_elem(list, mixer, id)  \
++      for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem)
++#define mixer_elem_list_to_info(list) \
++      container_of(list, struct usb_mixer_elem_info, head)
++
+ struct usb_mixer_elem_info {
+       struct usb_mixer_elem_list head;
+       unsigned int control;   /* CS or ICN (high byte) */
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index b9ea4a42aee4e..ead0456a747c2 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -1171,7 +1171,7 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
+       int unitid = 12; /* SamleRate ExtensionUnit ID */
+       list_for_each_entry(mixer, &chip->mixer_list, list) {
+-              cval = (struct usb_mixer_elem_info *)mixer->id_elems[unitid];
++              cval = mixer_elem_list_to_info(mixer->id_elems[unitid]);
+               if (cval) {
+                       snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
+                                                   cval->control << 8,
+diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c
+index c33e2378089d5..4aeb9488a0c99 100644
+--- a/sound/usb/mixer_scarlett.c
++++ b/sound/usb/mixer_scarlett.c
+@@ -287,8 +287,7 @@ static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl,
+ static int scarlett_ctl_resume(struct usb_mixer_elem_list *list)
+ {
+-      struct usb_mixer_elem_info *elem =
+-              container_of(list, struct usb_mixer_elem_info, head);
++      struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
+       int i;
+       for (i = 0; i < elem->channels; i++)
+@@ -447,8 +446,7 @@ static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
+ static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
+ {
+-      struct usb_mixer_elem_info *elem =
+-              container_of(list, struct usb_mixer_elem_info, head);
++      struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
+       if (elem->cached)
+               snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
+-- 
+2.25.1
+
diff --git a/queue-4.14/alsa-usb-audio-fix-oob-access-of-mixer-element-list.patch b/queue-4.14/alsa-usb-audio-fix-oob-access-of-mixer-element-list.patch
new file mode 100644 (file)
index 0000000..dc4752f
--- /dev/null
@@ -0,0 +1,125 @@
+From 399b8d1ccab2d3084f198ac8873381a5e8ac32e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2020 14:23:40 +0200
+Subject: ALSA: usb-audio: Fix OOB access of mixer element list
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 220345e98f1cdc768eeb6e3364a0fa7ab9647fe7 ]
+
+The USB-audio mixer code holds a linked list of usb_mixer_elem_list,
+and several operations are performed for each mixer element.  A few of
+them (snd_usb_mixer_notify_id() and snd_usb_mixer_interrupt_v2())
+assume each mixer element being a usb_mixer_elem_info object that is a
+subclass of usb_mixer_elem_list, cast via container_of() and access it
+members.  This may result in an out-of-bound access when a
+non-standard list element has been added, as spotted by syzkaller
+recently.
+
+This patch adds a new field, is_std_info, in usb_mixer_elem_list to
+indicate that the element is the usb_mixer_elem_info type or not, and
+skip the access to such an element if needed.
+
+Reported-by: syzbot+fb14314433463ad51625@syzkaller.appspotmail.com
+Reported-by: syzbot+2405ca3401e943c538b5@syzkaller.appspotmail.com
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200624122340.9615-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer.c        | 15 +++++++++++----
+ sound/usb/mixer.h        |  9 +++++++--
+ sound/usb/mixer_quirks.c |  3 ++-
+ 3 files changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index 1a8d706491e65..b29a3546ab6af 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -591,8 +591,9 @@ static int check_matrix_bitmap(unsigned char *bmap,
+  * if failed, give up and free the control instance.
+  */
+-int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list,
+-                            struct snd_kcontrol *kctl)
++int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list,
++                         struct snd_kcontrol *kctl,
++                         bool is_std_info)
+ {
+       struct usb_mixer_interface *mixer = list->mixer;
+       int err;
+@@ -605,6 +606,7 @@ int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list,
+               return err;
+       }
+       list->kctl = kctl;
++      list->is_std_info = is_std_info;
+       list->next_id_elem = mixer->id_elems[list->id];
+       mixer->id_elems[list->id] = list;
+       return 0;
+@@ -2404,8 +2406,11 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
+       struct usb_mixer_elem_list *list;
+       for_each_mixer_elem(list, mixer, unitid) {
+-              struct usb_mixer_elem_info *info =
+-                      mixer_elem_list_to_info(list);
++              struct usb_mixer_elem_info *info;
++
++              if (!list->is_std_info)
++                      continue;
++              info = mixer_elem_list_to_info(list);
+               /* invalidate cache, so the value is read from the device */
+               info->cached = 0;
+               snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+@@ -2483,6 +2488,8 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
+               if (!list->kctl)
+                       continue;
++              if (!list->is_std_info)
++                      continue;
+               info = mixer_elem_list_to_info(list);
+               if (count > 1 && info->control != control)
+diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
+index e02653465e292..7c824a44589b0 100644
+--- a/sound/usb/mixer.h
++++ b/sound/usb/mixer.h
+@@ -49,6 +49,7 @@ struct usb_mixer_elem_list {
+       struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */
+       struct snd_kcontrol *kctl;
+       unsigned int id;
++      bool is_std_info;
+       usb_mixer_elem_dump_func_t dump;
+       usb_mixer_elem_resume_func_t resume;
+ };
+@@ -86,8 +87,12 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
+ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
+                               int request, int validx, int value_set);
+-int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list,
+-                            struct snd_kcontrol *kctl);
++int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list,
++                         struct snd_kcontrol *kctl,
++                         bool is_std_info);
++
++#define snd_usb_mixer_add_control(list, kctl) \
++      snd_usb_mixer_add_list(list, kctl, true)
+ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
+                                struct usb_mixer_interface *mixer,
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index ead0456a747c2..5604cce30a582 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -169,7 +169,8 @@ static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
+               return -ENOMEM;
+       }
+       kctl->private_free = snd_usb_mixer_elem_free;
+-      return snd_usb_mixer_add_control(list, kctl);
++      /* don't use snd_usb_mixer_add_control() here, this is a special list element */
++      return snd_usb_mixer_add_list(list, kctl, false);
+ }
+ /*
+-- 
+2.25.1
+
diff --git a/queue-4.14/alsa-usb-audio-uac1-invalidate-ctl-on-interrupt.patch b/queue-4.14/alsa-usb-audio-uac1-invalidate-ctl-on-interrupt.patch
new file mode 100644 (file)
index 0000000..5fa31a5
--- /dev/null
@@ -0,0 +1,44 @@
+From 84a08162da3de7ac2f682a77bee58a8b9e4bf036 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2017 17:35:17 +0100
+Subject: ALSA: usb-audio: uac1: Invalidate ctl on interrupt
+
+From: Julian Scheel <julian@jusst.de>
+
+[ Upstream commit b2500b584cfd228d67e1e43daf27c8af865b499e ]
+
+When an interrupt occurs, the value of at least one of the belonging
+controls should have changed. To make sure they get re-read from device
+on the next read, invalidate the cache. This was correctly implemented
+for uac2 already, but missing for uac1.
+
+Signed-off-by: Julian Scheel <julian@jusst.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index dbbc5609b453b..33deb5ec8b7a1 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -2403,9 +2403,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
+ {
+       struct usb_mixer_elem_list *list;
+-      for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem)
++      for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) {
++              struct usb_mixer_elem_info *info =
++                      (struct usb_mixer_elem_info *)list;
++              /* invalidate cache, so the value is read from the device */
++              info->cached = 0;
+               snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &list->kctl->id);
++      }
+ }
+ static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
+-- 
+2.25.1
+
diff --git a/queue-4.14/cifs-smb3-fix-data-inconsistent-when-punch-hole.patch b/queue-4.14/cifs-smb3-fix-data-inconsistent-when-punch-hole.patch
new file mode 100644 (file)
index 0000000..5d70777
--- /dev/null
@@ -0,0 +1,57 @@
+From 86dfa1cf0b1bae628c603bdb0bb0985cfb56a2c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2020 07:31:53 -0400
+Subject: cifs/smb3: Fix data inconsistent when punch hole
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit acc91c2d8de4ef46ed751c5f9df99ed9a109b100 ]
+
+When punch hole success, we also can read old data from file:
+  # strace -e trace=pread64,fallocate xfs_io -f -c "pread 20 40" \
+           -c "fpunch 20 40" -c"pread 20 40" file
+  pread64(3, " version 5.8.0-rc1+"..., 40, 20) = 40
+  fallocate(3, FALLOC_FL_KEEP_SIZE|FALLOC_FL_PUNCH_HOLE, 20, 40) = 0
+  pread64(3, " version 5.8.0-rc1+"..., 40, 20) = 40
+
+CIFS implements the fallocate(FALLOCATE_FL_PUNCH_HOLE) with send SMB
+ioctl(FSCTL_SET_ZERO_DATA) to server. It just set the range of the
+remote file to zero, but local page caches not updated, then the
+local page caches inconsistent with server.
+
+Also can be found by xfstests generic/316.
+
+So, we need to remove the page caches before send the SMB
+ioctl(FSCTL_SET_ZERO_DATA) to server.
+
+Fixes: 31742c5a33176 ("enable fallocate punch hole ("fallocate -p") for SMB3")
+Suggested-by: Pavel Shilovsky <pshilov@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Cc: stable@vger.kernel.org # v3.17
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 951c444d83e7b..61ea429e1210b 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1824,6 +1824,12 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
+               return rc;
+       }
++      /*
++       * We implement the punch hole through ioctl, so we need remove the page
++       * caches first, otherwise the data may be inconsistent with the server.
++       */
++      truncate_pagecache_range(inode, offset, offset + len - 1);
++
+       cifs_dbg(FYI, "offset %lld len %lld", offset, len);
+       fsctl_buf.FileOffset = cpu_to_le64(offset);
+-- 
+2.25.1
+
diff --git a/queue-4.14/cifs-smb3-fix-data-inconsistent-when-zero-file-range.patch b/queue-4.14/cifs-smb3-fix-data-inconsistent-when-zero-file-range.patch
new file mode 100644 (file)
index 0000000..c5d58fd
--- /dev/null
@@ -0,0 +1,49 @@
+From a94c42f513bb2098c480ac5aeb7ea72cc2832a21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2020 07:31:54 -0400
+Subject: cifs/smb3: Fix data inconsistent when zero file range
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit 6b69040247e14b43419a520f841f2b3052833df9 ]
+
+CIFS implements the fallocate(FALLOC_FL_ZERO_RANGE) with send SMB
+ioctl(FSCTL_SET_ZERO_DATA) to server. It just set the range of the
+remote file to zero, but local page cache not update, then the data
+inconsistent with server, which leads the xfstest generic/008 failed.
+
+So we need to remove the local page caches before send SMB
+ioctl(FSCTL_SET_ZERO_DATA) to server. After next read, it will
+re-cache it.
+
+Fixes: 30175628bf7f5 ("[SMB3] Enable fallocate -z support for SMB3 mounts")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Cc: stable@vger.kernel.org # v3.17
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 61ea429e1210b..b46fdb2b8d349 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1755,6 +1755,12 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
+       inode = d_inode(cfile->dentry);
+       cifsi = CIFS_I(inode);
++      /*
++       * We zero the range through ioctl, so we need remove the page caches
++       * first, otherwise the data may be inconsistent with the server.
++       */
++      truncate_pagecache_range(inode, offset, offset + len - 1);
++
+       /* if file not oplocked can't be sure whether asking to extend size */
+       if (!CIFS_CACHE_READ(cifsi))
+               if (keep_size == false) {
+-- 
+2.25.1
+
index 7ee20e9640e3583e1e27ab6ca286b09b7a16140c..255ed4840142566a72926f58449d4cf61178fd6e 100644 (file)
@@ -30,3 +30,9 @@ alsa-usb-audio-add-quirk-for-denon-dcd-1500re.patch
 xhci-fix-incorrect-ep_state_mask.patch
 xhci-fix-enumeration-issue-when-setting-max-packet-size-for-fs-devices.patch
 cdc-acm-add-disable_echo-quirk-for-microchip-smsc-chip.patch
+alsa-usb-audio-uac1-invalidate-ctl-on-interrupt.patch
+alsa-usb-audio-clean-up-mixer-element-list-traverse.patch
+alsa-usb-audio-fix-oob-access-of-mixer-element-list.patch
+xhci-poll-for-u0-after-disabling-usb2-lpm.patch
+cifs-smb3-fix-data-inconsistent-when-punch-hole.patch
+cifs-smb3-fix-data-inconsistent-when-zero-file-range.patch
diff --git a/queue-4.14/xhci-poll-for-u0-after-disabling-usb2-lpm.patch b/queue-4.14/xhci-poll-for-u0-after-disabling-usb2-lpm.patch
new file mode 100644 (file)
index 0000000..56cf6ed
--- /dev/null
@@ -0,0 +1,64 @@
+From 34ce3bf9cc3665aa79988b9c6be0589b7d310acc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2020 16:59:49 +0300
+Subject: xhci: Poll for U0 after disabling USB2 LPM
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit b3d71abd135e6919ca0b6cab463738472653ddfb ]
+
+USB2 devices with LPM enabled may interrupt the system suspend:
+[  932.510475] usb 1-7: usb suspend, wakeup 0
+[  932.510549] hub 1-0:1.0: hub_suspend
+[  932.510581] usb usb1: bus suspend, wakeup 0
+[  932.510590] xhci_hcd 0000:00:14.0: port 9 not suspended
+[  932.510593] xhci_hcd 0000:00:14.0: port 8 not suspended
+..
+[  932.520323] xhci_hcd 0000:00:14.0: Port change event, 1-7, id 7, portsc: 0x400e03
+..
+[  932.591405] PM: pci_pm_suspend(): hcd_pci_suspend+0x0/0x30 returns -16
+[  932.591414] PM: dpm_run_callback(): pci_pm_suspend+0x0/0x160 returns -16
+[  932.591418] PM: Device 0000:00:14.0 failed to suspend async: error -16
+
+During system suspend, USB core will let HC suspends the device if it
+doesn't have remote wakeup enabled and doesn't have any children.
+However, from the log above we can see that the usb 1-7 doesn't get bus
+suspended due to not in U0. After a while the port finished U2 -> U0
+transition, interrupts the suspend process.
+
+The observation is that after disabling LPM, port doesn't transit to U0
+immediately and can linger in U2. xHCI spec 4.23.5.2 states that the
+maximum exit latency for USB2 LPM should be BESL + 10us. The BESL for
+the affected device is advertised as 400us, which is still not enough
+based on my testing result.
+
+So let's use the maximum permitted latency, 10000, to poll for U0
+status to solve the issue.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200624135949.22611-6-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index d727cbbad44a2..cdf1c91554035 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4226,6 +4226,9 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
+                       mutex_lock(hcd->bandwidth_mutex);
+                       xhci_change_max_exit_latency(xhci, udev, 0);
+                       mutex_unlock(hcd->bandwidth_mutex);
++                      readl_poll_timeout(port_array[port_num], pm_val,
++                                         (pm_val & PORT_PLS_MASK) == XDEV_U0,
++                                         100, 10000);
+                       return 0;
+               }
+       }
+-- 
+2.25.1
+