]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Jun 2019 08:25:17 +0000 (10:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Jun 2019 08:25:17 +0000 (10:25 +0200)
added patches:
brcmfmac-fix-null-pointer-derefence-during-usb-disconnect.patch
btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch
btrfs-fix-race-updating-log-root-item-during-fsync.patch
btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch
btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch
include-linux-bitops.h-sanitize-rotate-primitives.patch
media-smsusb-better-handle-optional-alignment.patch
media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch
media-usb-siano-fix-general-protection-fault-in-smsusb.patch
scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch
scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch
sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch
tracing-avoid-memory-leak-in-predicate_parse.patch
usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch
usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch
usb-rio500-fix-memory-leak-in-close-after-disconnect.patch
usb-rio500-refuse-more-than-one-device-at-a-time.patch
usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch
usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch
usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch
usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch
xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch
xhci-update-bounce-buffer-with-correct-sg-num.patch
xhci-use-zu-for-printing-size_t-type.patch

25 files changed:
queue-4.19/brcmfmac-fix-null-pointer-derefence-during-usb-disconnect.patch [new file with mode: 0644]
queue-4.19/btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch [new file with mode: 0644]
queue-4.19/btrfs-fix-race-updating-log-root-item-during-fsync.patch [new file with mode: 0644]
queue-4.19/btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch [new file with mode: 0644]
queue-4.19/btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch [new file with mode: 0644]
queue-4.19/include-linux-bitops.h-sanitize-rotate-primitives.patch [new file with mode: 0644]
queue-4.19/media-smsusb-better-handle-optional-alignment.patch [new file with mode: 0644]
queue-4.19/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch [new file with mode: 0644]
queue-4.19/media-usb-siano-fix-general-protection-fault-in-smsusb.patch [new file with mode: 0644]
queue-4.19/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch [new file with mode: 0644]
queue-4.19/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch [new file with mode: 0644]
queue-4.19/series [new file with mode: 0644]
queue-4.19/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch [new file with mode: 0644]
queue-4.19/tracing-avoid-memory-leak-in-predicate_parse.patch [new file with mode: 0644]
queue-4.19/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch [new file with mode: 0644]
queue-4.19/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch [new file with mode: 0644]
queue-4.19/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch [new file with mode: 0644]
queue-4.19/usb-rio500-refuse-more-than-one-device-at-a-time.patch [new file with mode: 0644]
queue-4.19/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch [new file with mode: 0644]
queue-4.19/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch [new file with mode: 0644]
queue-4.19/usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch [new file with mode: 0644]
queue-4.19/usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch [new file with mode: 0644]
queue-4.19/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch [new file with mode: 0644]
queue-4.19/xhci-update-bounce-buffer-with-correct-sg-num.patch [new file with mode: 0644]
queue-4.19/xhci-use-zu-for-printing-size_t-type.patch [new file with mode: 0644]

diff --git a/queue-4.19/brcmfmac-fix-null-pointer-derefence-during-usb-disconnect.patch b/queue-4.19/brcmfmac-fix-null-pointer-derefence-during-usb-disconnect.patch
new file mode 100644 (file)
index 0000000..265f5b6
--- /dev/null
@@ -0,0 +1,223 @@
+From 5cdb0ef6144f47440850553579aa923c20a63f23 Mon Sep 17 00:00:00 2001
+From: Piotr Figiel <p.figiel@camlintechnologies.com>
+Date: Mon, 4 Mar 2019 15:42:52 +0000
+Subject: brcmfmac: fix NULL pointer derefence during USB disconnect
+
+From: Piotr Figiel <p.figiel@camlintechnologies.com>
+
+commit 5cdb0ef6144f47440850553579aa923c20a63f23 upstream.
+
+In case USB disconnect happens at the moment transmitting workqueue is in
+progress the underlying interface may be gone causing a NULL pointer
+dereference. Add synchronization of the workqueue destruction with the
+detach implementation in core so that the transmitting workqueue is stopped
+during detach before the interfaces are removed.
+
+Fix following Oops:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000008
+pgd = 9e6a802d
+[00000008] *pgd=00000000
+Internal error: Oops: 5 [#1] PREEMPT SMP ARM
+Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle
+xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4
+iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether
+usb_serial_simple usbserial cdc_acm brcmfmac brcmutil smsc95xx usbnet
+ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base
+libcomposite configfs udc_core
+CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 4.19.23-00076-g03740aa-dirty #102
+Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
+Workqueue: brcmf_fws_wq brcmf_fws_dequeue_worker [brcmfmac]
+PC is at brcmf_txfinalize+0x34/0x90 [brcmfmac]
+LR is at brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac]
+pc : [<7f0dee64>]    lr : [<7f0e4140>]    psr: 60010093
+sp : ee8abef0  ip : 00000000  fp : edf38000
+r10: ffffffed  r9 : edf38970  r8 : edf38004
+r7 : edf3e970  r6 : 00000000  r5 : ede69000  r4 : 00000000
+r3 : 00000a97  r2 : 00000000  r1 : 0000888e  r0 : ede69000
+Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
+Control: 10c5387d  Table: 7d03c04a  DAC: 00000051
+Process kworker/u8:0 (pid: 7, stack limit = 0x24ec3e04)
+Stack: (0xee8abef0 to 0xee8ac000)
+bee0:                                     ede69000 00000000 ed56c3e0 7f0e4140
+bf00: 00000001 00000000 edf38004 edf3e99c ed56c3e0 80d03d00 edfea43a edf3e970
+bf20: ee809880 ee804200 ee971100 00000000 edf3e974 00000000 ee804200 80135a70
+bf40: 80d03d00 ee804218 ee809880 ee809894 ee804200 80d03d00 ee804218 ee8aa000
+bf60: 00000088 80135d5c 00000000 ee829f00 ee829dc0 00000000 ee809880 80135d30
+bf80: ee829f1c ee873eac 00000000 8013b1a0 ee829dc0 8013b07c 00000000 00000000
+bfa0: 00000000 00000000 00000000 801010e8 00000000 00000000 00000000 00000000
+bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
+[<7f0dee64>] (brcmf_txfinalize [brcmfmac]) from [<7f0e4140>] (brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac])
+[<7f0e4140>] (brcmf_fws_dequeue_worker [brcmfmac]) from [<80135a70>] (process_one_work+0x138/0x3f8)
+[<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554)
+[<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154)
+[<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c)
+Exception stack(0xee8abfb0 to 0xee8abff8)
+bfa0:                                     00000000 00000000 00000000 00000000
+bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
+Code: e1530001 0a000007 e3560000 e1a00005 (05942008)
+---[ end trace 079239dd31c86e90 ]---
+
+Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c     |   11 ++++++--
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h     |    6 +++-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c     |    4 ++-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c |   16 +++++++++---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h |    3 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c    |   10 ++++++-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h    |    3 +-
+ 7 files changed, 40 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
+@@ -490,11 +490,18 @@ fail:
+       return -ENOMEM;
+ }
+-void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
++void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr)
++{
++      struct brcmf_bcdc *bcdc = drvr->proto->pd;
++
++      brcmf_fws_detach_pre_delif(bcdc->fws);
++}
++
++void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr)
+ {
+       struct brcmf_bcdc *bcdc = drvr->proto->pd;
+       drvr->proto->pd = NULL;
+-      brcmf_fws_detach(bcdc->fws);
++      brcmf_fws_detach_post_delif(bcdc->fws);
+       kfree(bcdc);
+ }
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h
+@@ -18,14 +18,16 @@
+ #ifdef CONFIG_BRCMFMAC_PROTO_BCDC
+ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
+-void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
++void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr);
++void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr);
+ void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state);
+ void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
+                                bool success);
+ struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr);
+ #else
+ static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; }
+-static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {}
++static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {};
++static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {}
+ #endif
+ #endif /* BRCMFMAC_BCDC_H */
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1244,6 +1244,8 @@ void brcmf_detach(struct device *dev)
+       brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
++      brcmf_proto_detach_pre_delif(drvr);
++
+       /* make sure primary interface removed last */
+       for (i = BRCMF_MAX_IFS-1; i > -1; i--)
+               brcmf_remove_interface(drvr->iflist[i], false);
+@@ -1253,7 +1255,7 @@ void brcmf_detach(struct device *dev)
+       brcmf_bus_stop(drvr->bus_if);
+-      brcmf_proto_detach(drvr);
++      brcmf_proto_detach_post_delif(drvr);
+       bus_if->drvr = NULL;
+       wiphy_free(drvr->wiphy);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+@@ -2410,17 +2410,25 @@ struct brcmf_fws_info *brcmf_fws_attach(
+       return fws;
+ fail:
+-      brcmf_fws_detach(fws);
++      brcmf_fws_detach_pre_delif(fws);
++      brcmf_fws_detach_post_delif(fws);
+       return ERR_PTR(rc);
+ }
+-void brcmf_fws_detach(struct brcmf_fws_info *fws)
++void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws)
+ {
+       if (!fws)
+               return;
+-
+-      if (fws->fws_wq)
++      if (fws->fws_wq) {
+               destroy_workqueue(fws->fws_wq);
++              fws->fws_wq = NULL;
++      }
++}
++
++void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws)
++{
++      if (!fws)
++              return;
+       /* cleanup */
+       brcmf_fws_lock(fws);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
+@@ -19,7 +19,8 @@
+ #define FWSIGNAL_H_
+ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr);
+-void brcmf_fws_detach(struct brcmf_fws_info *fws);
++void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws);
++void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws);
+ void brcmf_fws_debugfs_create(struct brcmf_pub *drvr);
+ bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws);
+ bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c
+@@ -67,16 +67,22 @@ fail:
+       return -ENOMEM;
+ }
+-void brcmf_proto_detach(struct brcmf_pub *drvr)
++void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr)
+ {
+       brcmf_dbg(TRACE, "Enter\n");
+       if (drvr->proto) {
+               if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC)
+-                      brcmf_proto_bcdc_detach(drvr);
++                      brcmf_proto_bcdc_detach_post_delif(drvr);
+               else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF)
+                       brcmf_proto_msgbuf_detach(drvr);
+               kfree(drvr->proto);
+               drvr->proto = NULL;
+       }
+ }
++
++void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr)
++{
++      if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC)
++              brcmf_proto_bcdc_detach_pre_delif(drvr);
++}
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
+@@ -54,7 +54,8 @@ struct brcmf_proto {
+ int brcmf_proto_attach(struct brcmf_pub *drvr);
+-void brcmf_proto_detach(struct brcmf_pub *drvr);
++void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr);
++void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr);
+ static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
+                                     struct sk_buff *skb,
diff --git a/queue-4.19/btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch b/queue-4.19/btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch
new file mode 100644 (file)
index 0000000..d511151
--- /dev/null
@@ -0,0 +1,97 @@
+From 60d9f50308e5df19bc18c2fefab0eba4a843900a Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Thu, 16 May 2019 15:48:55 +0100
+Subject: Btrfs: fix fsync not persisting changed attributes of a directory
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 60d9f50308e5df19bc18c2fefab0eba4a843900a upstream.
+
+While logging an inode we follow its ancestors and for each one we mark
+it as logged in the current transaction, even if we have not logged it.
+As a consequence if we change an attribute of an ancestor, such as the
+UID or GID for example, and then explicitly fsync it, we end up not
+logging the inode at all despite returning success to user space, which
+results in the attribute being lost if a power failure happens after
+the fsync.
+
+Sample reproducer:
+
+  $ mkfs.btrfs -f /dev/sdb
+  $ mount /dev/sdb /mnt
+
+  $ mkdir /mnt/dir
+  $ chown 6007:6007 /mnt/dir
+
+  $ sync
+
+  $ chown 9003:9003 /mnt/dir
+  $ touch /mnt/dir/file
+  $ xfs_io -c fsync /mnt/dir/file
+
+  # fsync our directory after fsync'ing the new file, should persist the
+  # new values for the uid and gid.
+  $ xfs_io -c fsync /mnt/dir
+
+  <power failure>
+
+  $ mount /dev/sdb /mnt
+  $ stat -c %u:%g /mnt/dir
+  6007:6007
+
+    --> should be 9003:9003, the uid and gid were not persisted, despite
+        the explicit fsync on the directory prior to the power failure
+
+Fix this by not updating the logged_trans field of ancestor inodes when
+logging an inode, since we have not logged them. Let only future calls to
+btrfs_log_inode() to mark inodes as logged.
+
+This could be triggered by my recent fsync fuzz tester for fstests, for
+which an fstests patch exists titled "fstests: generic, fsync fuzz tester
+with fsstress".
+
+Fixes: 12fcfd22fe5b ("Btrfs: tree logging unlink/rename fixes")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c |   12 ------------
+ 1 file changed, 12 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -5312,7 +5312,6 @@ static noinline int check_parent_dirs_fo
+ {
+       int ret = 0;
+       struct dentry *old_parent = NULL;
+-      struct btrfs_inode *orig_inode = inode;
+       /*
+        * for regular files, if its inode is already on disk, we don't
+@@ -5332,16 +5331,6 @@ static noinline int check_parent_dirs_fo
+       }
+       while (1) {
+-              /*
+-               * If we are logging a directory then we start with our inode,
+-               * not our parent's inode, so we need to skip setting the
+-               * logged_trans so that further down in the log code we don't
+-               * think this inode has already been logged.
+-               */
+-              if (inode != orig_inode)
+-                      inode->logged_trans = trans->transid;
+-              smp_mb();
+-
+               if (btrfs_must_commit_transaction(trans, inode)) {
+                       ret = 1;
+                       break;
+@@ -6070,7 +6059,6 @@ void btrfs_record_unlink_dir(struct btrf
+        * if this directory was already logged any new
+        * names for this file/dir will get recorded
+        */
+-      smp_mb();
+       if (dir->logged_trans == trans->transid)
+               return;
diff --git a/queue-4.19/btrfs-fix-race-updating-log-root-item-during-fsync.patch b/queue-4.19/btrfs-fix-race-updating-log-root-item-during-fsync.patch
new file mode 100644 (file)
index 0000000..1437d44
--- /dev/null
@@ -0,0 +1,125 @@
+From 06989c799f04810f6876900d4760c0edda369cf7 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 15 May 2019 16:03:17 +0100
+Subject: Btrfs: fix race updating log root item during fsync
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 06989c799f04810f6876900d4760c0edda369cf7 upstream.
+
+When syncing the log, the final phase of a fsync operation, we need to
+either create a log root's item or update the existing item in the log
+tree of log roots, and that depends on the current value of the log
+root's log_transid - if it's 1 we need to create the log root item,
+otherwise it must exist already and we update it. Since there is no
+synchronization between updating the log_transid and checking it for
+deciding whether the log root's item needs to be created or updated, we
+end up with a tiny race window that results in attempts to update the
+item to fail because the item was not yet created:
+
+              CPU 1                                    CPU 2
+
+  btrfs_sync_log()
+
+    lock root->log_mutex
+
+    set log root's log_transid to 1
+
+    unlock root->log_mutex
+
+                                               btrfs_sync_log()
+
+                                                 lock root->log_mutex
+
+                                                 sets log root's
+                                                 log_transid to 2
+
+                                                 unlock root->log_mutex
+
+    update_log_root()
+
+      sees log root's log_transid
+      with a value of 2
+
+        calls btrfs_update_root(),
+        which fails with -EUCLEAN
+        and causes transaction abort
+
+Until recently the race lead to a BUG_ON at btrfs_update_root(), but after
+the recent commit 7ac1e464c4d47 ("btrfs: Don't panic when we can't find a
+root key") we just abort the current transaction.
+
+A sample trace of the BUG_ON() on a SLE12 kernel:
+
+  ------------[ cut here ]------------
+  kernel BUG at ../fs/btrfs/root-tree.c:157!
+  Oops: Exception in kernel mode, sig: 5 [#1]
+  SMP NR_CPUS=2048 NUMA pSeries
+  (...)
+  Supported: Yes, External
+  CPU: 78 PID: 76303 Comm: rtas_errd Tainted: G                 X 4.4.156-94.57-default #1
+  task: c00000ffa906d010 ti: c00000ff42b08000 task.ti: c00000ff42b08000
+  NIP: d000000036ae5cdc LR: d000000036ae5cd8 CTR: 0000000000000000
+  REGS: c00000ff42b0b860 TRAP: 0700   Tainted: G                 X  (4.4.156-94.57-default)
+  MSR: 8000000002029033 <SF,VEC,EE,ME,IR,DR,RI,LE>  CR: 22444484  XER: 20000000
+  CFAR: d000000036aba66c SOFTE: 1
+  GPR00: d000000036ae5cd8 c00000ff42b0bae0 d000000036bda220 0000000000000054
+  GPR04: 0000000000000001 0000000000000000 c00007ffff8d37c8 0000000000000000
+  GPR08: c000000000e19c00 0000000000000000 0000000000000000 3736343438312079
+  GPR12: 3930373337303434 c000000007a3a800 00000000007fffff 0000000000000023
+  GPR16: c00000ffa9d26028 c00000ffa9d261f8 0000000000000010 c00000ffa9d2ab28
+  GPR20: c00000ff42b0bc48 0000000000000001 c00000ff9f0d9888 0000000000000001
+  GPR24: c00000ffa9d26000 c00000ffa9d261e8 c00000ffa9d2a800 c00000ff9f0d9888
+  GPR28: c00000ffa9d26028 c00000ffa9d2aa98 0000000000000001 c00000ffa98f5b20
+  NIP [d000000036ae5cdc] btrfs_update_root+0x25c/0x4e0 [btrfs]
+  LR [d000000036ae5cd8] btrfs_update_root+0x258/0x4e0 [btrfs]
+  Call Trace:
+  [c00000ff42b0bae0] [d000000036ae5cd8] btrfs_update_root+0x258/0x4e0 [btrfs] (unreliable)
+  [c00000ff42b0bba0] [d000000036b53610] btrfs_sync_log+0x2d0/0xc60 [btrfs]
+  [c00000ff42b0bce0] [d000000036b1785c] btrfs_sync_file+0x44c/0x4e0 [btrfs]
+  [c00000ff42b0bd80] [c00000000032e300] vfs_fsync_range+0x70/0x120
+  [c00000ff42b0bdd0] [c00000000032e44c] do_fsync+0x5c/0xb0
+  [c00000ff42b0be10] [c00000000032e8dc] SyS_fdatasync+0x2c/0x40
+  [c00000ff42b0be30] [c000000000009488] system_call+0x3c/0x100
+  Instruction dump:
+  7f43d378 4bffebb9 60000000 88d90008 3d220000 e8b90000 3b390009 e87a01f0
+  e8898e08 e8f90000 4bfd48e5 60000000 <0fe00000> e95b0060 39200004 394a0ea0
+  ---[ end trace 8f2dc8f919cabab8 ]---
+
+So fix this by doing the check of log_transid and updating or creating the
+log root's item while holding the root's log_mutex.
+
+Fixes: 7237f1833601d ("Btrfs: fix tree logs parallel sync")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3038,6 +3038,12 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       log->log_transid = root->log_transid;
+       root->log_start_pid = 0;
+       /*
++       * Update or create log root item under the root's log_mutex to prevent
++       * races with concurrent log syncs that can lead to failure to update
++       * log root item because it was not created yet.
++       */
++      ret = update_log_root(trans, log);
++      /*
+        * IO has been started, blocks of the log tree have WRITTEN flag set
+        * in their headers. new modifications of the log will be written to
+        * new positions. so it's safe to allow log writers to go in.
+@@ -3056,8 +3062,6 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       mutex_unlock(&log_root_tree->log_mutex);
+-      ret = update_log_root(trans, log);
+-
+       mutex_lock(&log_root_tree->log_mutex);
+       if (atomic_dec_and_test(&log_root_tree->log_writers)) {
+               /* atomic_dec_and_test implies a barrier */
diff --git a/queue-4.19/btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch b/queue-4.19/btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch
new file mode 100644 (file)
index 0000000..8b610dd
--- /dev/null
@@ -0,0 +1,80 @@
+From 5338e43abbab13791144d37fd8846847062351c6 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 15 May 2019 16:02:47 +0100
+Subject: Btrfs: fix wrong ctime and mtime of a directory after log replay
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 5338e43abbab13791144d37fd8846847062351c6 upstream.
+
+When replaying a log that contains a new file or directory name that needs
+to be added to its parent directory, we end up updating the mtime and the
+ctime of the parent directory to the current time after we have set their
+values to the correct ones (set at fsync time), efectivelly losing them.
+
+Sample reproducer:
+
+  $ mkfs.btrfs -f /dev/sdb
+  $ mount /dev/sdb /mnt
+
+  $ mkdir /mnt/dir
+  $ touch /mnt/dir/file
+
+  # fsync of the directory is optional, not needed
+  $ xfs_io -c fsync /mnt/dir
+  $ xfs_io -c fsync /mnt/dir/file
+
+  $ stat -c %Y /mnt/dir
+  1557856079
+
+  <power failure>
+
+  $ sleep 3
+  $ mount /dev/sdb /mnt
+  $ stat -c %Y /mnt/dir
+  1557856082
+
+    --> should have been 1557856079, the mtime is updated to the current
+        time when replaying the log
+
+Fix this by not updating the mtime and ctime to the current time at
+btrfs_add_link() when we are replaying a log tree.
+
+This could be triggered by my recent fsync fuzz tester for fstests, for
+which an fstests patch exists titled "fstests: generic, fsync fuzz tester
+with fsstress".
+
+Fixes: e02119d5a7b43 ("Btrfs: Add a write ahead tree log to optimize synchronous operations")
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c |   14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -6426,8 +6426,18 @@ int btrfs_add_link(struct btrfs_trans_ha
+       btrfs_i_size_write(parent_inode, parent_inode->vfs_inode.i_size +
+                          name_len * 2);
+       inode_inc_iversion(&parent_inode->vfs_inode);
+-      parent_inode->vfs_inode.i_mtime = parent_inode->vfs_inode.i_ctime =
+-              current_time(&parent_inode->vfs_inode);
++      /*
++       * If we are replaying a log tree, we do not want to update the mtime
++       * and ctime of the parent directory with the current time, since the
++       * log replay procedure is responsible for setting them to their correct
++       * values (the ones it had when the fsync was done).
++       */
++      if (!test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags)) {
++              struct timespec64 now = current_time(&parent_inode->vfs_inode);
++
++              parent_inode->vfs_inode.i_mtime = now;
++              parent_inode->vfs_inode.i_ctime = now;
++      }
+       ret = btrfs_update_inode(trans, root, &parent_inode->vfs_inode);
+       if (ret)
+               btrfs_abort_transaction(trans, ret);
diff --git a/queue-4.19/btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch b/queue-4.19/btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch
new file mode 100644 (file)
index 0000000..934ee0a
--- /dev/null
@@ -0,0 +1,80 @@
+From 6b1f72e5b82a5c2a4da4d1ebb8cc01913ddbea21 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 20 May 2019 09:55:42 +0100
+Subject: Btrfs: incremental send, fix file corruption when no-holes feature is enabled
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 6b1f72e5b82a5c2a4da4d1ebb8cc01913ddbea21 upstream.
+
+When using the no-holes feature, if we have a file with prealloc extents
+with a start offset beyond the file's eof, doing an incremental send can
+cause corruption of the file due to incorrect hole detection. Such case
+requires that the prealloc extent(s) exist in both the parent and send
+snapshots, and that a hole is punched into the file that covers all its
+extents that do not cross the eof boundary.
+
+Example reproducer:
+
+  $ mkfs.btrfs -f -O no-holes /dev/sdb
+  $ mount /dev/sdb /mnt/sdb
+
+  $ xfs_io -f -c "pwrite -S 0xab 0 500K" /mnt/sdb/foobar
+  $ xfs_io -c "falloc -k 1200K 800K" /mnt/sdb/foobar
+
+  $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/base
+
+  $ btrfs send -f /tmp/base.snap /mnt/sdb/base
+
+  $ xfs_io -c "fpunch 0 500K" /mnt/sdb/foobar
+
+  $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/incr
+
+  $ btrfs send -p /mnt/sdb/base -f /tmp/incr.snap /mnt/sdb/incr
+
+  $ md5sum /mnt/sdb/incr/foobar
+  816df6f64deba63b029ca19d880ee10a   /mnt/sdb/incr/foobar
+
+  $ mkfs.btrfs -f /dev/sdc
+  $ mount /dev/sdc /mnt/sdc
+
+  $ btrfs receive -f /tmp/base.snap /mnt/sdc
+  $ btrfs receive -f /tmp/incr.snap /mnt/sdc
+
+  $ md5sum /mnt/sdc/incr/foobar
+  cf2ef71f4a9e90c2f6013ba3b2257ed2   /mnt/sdc/incr/foobar
+
+    --> Different checksum, because the prealloc extent beyond the
+        file's eof confused the hole detection code and it assumed
+        a hole starting at offset 0 and ending at the offset of the
+        prealloc extent (1200Kb) instead of ending at the offset
+        500Kb (the file's size).
+
+Fix this by ensuring we never cross the file's size when issuing the
+write operations for a hole.
+
+Fixes: 16e7549f045d33 ("Btrfs: incompatible format change to remove hole extents")
+CC: stable@vger.kernel.org # 3.14+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/send.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5021,6 +5021,12 @@ static int send_hole(struct send_ctx *sc
+       if (offset >= sctx->cur_inode_size)
+               return 0;
++      /*
++       * Don't go beyond the inode's i_size due to prealloc extents that start
++       * after the i_size.
++       */
++      end = min_t(u64, end, sctx->cur_inode_size);
++
+       if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
+               return send_update_extent(sctx, offset, end - offset);
diff --git a/queue-4.19/include-linux-bitops.h-sanitize-rotate-primitives.patch b/queue-4.19/include-linux-bitops.h-sanitize-rotate-primitives.patch
new file mode 100644 (file)
index 0000000..2fd988c
--- /dev/null
@@ -0,0 +1,133 @@
+From ef4d6f6b275c498f8e5626c99dbeefdc5027f843 Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Date: Tue, 14 May 2019 15:43:27 -0700
+Subject: include/linux/bitops.h: sanitize rotate primitives
+
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+
+commit ef4d6f6b275c498f8e5626c99dbeefdc5027f843 upstream.
+
+The ror32 implementation (word >> shift) | (word << (32 - shift) has
+undefined behaviour if shift is outside the [1, 31] range.  Similarly
+for the 64 bit variants.  Most callers pass a compile-time constant
+(naturally in that range), but there's an UBSAN report that these may
+actually be called with a shift count of 0.
+
+Instead of special-casing that, we can make them DTRT for all values of
+shift while also avoiding UB.  For some reason, this was already partly
+done for rol32 (which was well-defined for [0, 31]).  gcc 8 recognizes
+these patterns as rotates, so for example
+
+  __u32 rol32(__u32 word, unsigned int shift)
+  {
+       return (word << (shift & 31)) | (word >> ((-shift) & 31));
+  }
+
+compiles to
+
+0000000000000020 <rol32>:
+  20:   89 f8                   mov    %edi,%eax
+  22:   89 f1                   mov    %esi,%ecx
+  24:   d3 c0                   rol    %cl,%eax
+  26:   c3                      retq
+
+Older compilers unfortunately do not do as well, but this only affects
+the small minority of users that don't pass constants.
+
+Due to integer promotions, ro[lr]8 were already well-defined for shifts
+in [0, 8], and ro[lr]16 were mostly well-defined for shifts in [0, 16]
+(only mostly - u16 gets promoted to _signed_ int, so if bit 15 is set,
+word << 16 is undefined).  For consistency, update those as well.
+
+Link: http://lkml.kernel.org/r/20190410211906.2190-1-linux@rasmusvillemoes.dk
+Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Reported-by: Ido Schimmel <idosch@mellanox.com>
+Tested-by: Ido Schimmel <idosch@mellanox.com>
+Reviewed-by: Will Deacon <will.deacon@arm.com>
+Cc: Vadim Pasternak <vadimp@mellanox.com>
+Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Cc: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Cc: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/bitops.h |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -60,7 +60,7 @@ static __always_inline unsigned long hwe
+  */
+ static inline __u64 rol64(__u64 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> (64 - shift));
++      return (word << (shift & 63)) | (word >> ((-shift) & 63));
+ }
+ /**
+@@ -70,7 +70,7 @@ static inline __u64 rol64(__u64 word, un
+  */
+ static inline __u64 ror64(__u64 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (64 - shift));
++      return (word >> (shift & 63)) | (word << ((-shift) & 63));
+ }
+ /**
+@@ -80,7 +80,7 @@ static inline __u64 ror64(__u64 word, un
+  */
+ static inline __u32 rol32(__u32 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> ((-shift) & 31));
++      return (word << (shift & 31)) | (word >> ((-shift) & 31));
+ }
+ /**
+@@ -90,7 +90,7 @@ static inline __u32 rol32(__u32 word, un
+  */
+ static inline __u32 ror32(__u32 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (32 - shift));
++      return (word >> (shift & 31)) | (word << ((-shift) & 31));
+ }
+ /**
+@@ -100,7 +100,7 @@ static inline __u32 ror32(__u32 word, un
+  */
+ static inline __u16 rol16(__u16 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> (16 - shift));
++      return (word << (shift & 15)) | (word >> ((-shift) & 15));
+ }
+ /**
+@@ -110,7 +110,7 @@ static inline __u16 rol16(__u16 word, un
+  */
+ static inline __u16 ror16(__u16 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (16 - shift));
++      return (word >> (shift & 15)) | (word << ((-shift) & 15));
+ }
+ /**
+@@ -120,7 +120,7 @@ static inline __u16 ror16(__u16 word, un
+  */
+ static inline __u8 rol8(__u8 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> (8 - shift));
++      return (word << (shift & 7)) | (word >> ((-shift) & 7));
+ }
+ /**
+@@ -130,7 +130,7 @@ static inline __u8 rol8(__u8 word, unsig
+  */
+ static inline __u8 ror8(__u8 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (8 - shift));
++      return (word >> (shift & 7)) | (word << ((-shift) & 7));
+ }
+ /**
diff --git a/queue-4.19/media-smsusb-better-handle-optional-alignment.patch b/queue-4.19/media-smsusb-better-handle-optional-alignment.patch
new file mode 100644 (file)
index 0000000..524d6d8
--- /dev/null
@@ -0,0 +1,72 @@
+From a47686636d84eaec5c9c6e84bd5f96bed34d526d Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Date: Fri, 24 May 2019 10:59:43 -0400
+Subject: media: smsusb: better handle optional alignment
+
+From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+
+commit a47686636d84eaec5c9c6e84bd5f96bed34d526d upstream.
+
+Most Siano devices require an alignment for the response.
+
+Changeset f3be52b0056a ("media: usb: siano: Fix general protection fault in smsusb")
+changed the logic with gets such aligment, but it now produces a
+sparce warning:
+
+drivers/media/usb/siano/smsusb.c: In function 'smsusb_init_device':
+drivers/media/usb/siano/smsusb.c:447:37: warning: 'in_maxp' may be used uninitialized in this function [-Wmaybe-uninitialized]
+  447 |   dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);
+      |                             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The sparse message itself is bogus, but a broken (or fake) USB
+eeprom could produce a negative value for response_alignment.
+
+So, change the code in order to check if the result is not
+negative.
+
+Fixes: 31e0456de5be ("media: usb: siano: Fix general protection fault in smsusb")
+CC: <stable@vger.kernel.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/siano/smsusb.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -401,7 +401,7 @@ static int smsusb_init_device(struct usb
+       struct smsusb_device_t *dev;
+       void *mdev;
+       int i, rc;
+-      int in_maxp = 0;
++      int align = 0;
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
+@@ -419,14 +419,14 @@ static int smsusb_init_device(struct usb
+               if (desc->bEndpointAddress & USB_DIR_IN) {
+                       dev->in_ep = desc->bEndpointAddress;
+-                      in_maxp = usb_endpoint_maxp(desc);
++                      align = usb_endpoint_maxp(desc) - sizeof(struct sms_msg_hdr);
+               } else {
+                       dev->out_ep = desc->bEndpointAddress;
+               }
+       }
+       pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
+-      if (!dev->in_ep || !dev->out_ep) {      /* Missing endpoints? */
++      if (!dev->in_ep || !dev->out_ep || align < 0) {  /* Missing endpoints? */
+               smsusb_term_device(intf);
+               return -ENODEV;
+       }
+@@ -445,7 +445,7 @@ static int smsusb_init_device(struct usb
+               /* fall-thru */
+       default:
+               dev->buffer_size = USB2_BUFFER_SIZE;
+-              dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);
++              dev->response_alignment = align;
+               params.flags |= SMS_DEVICE_FAMILY2;
+               break;
diff --git a/queue-4.19/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch b/queue-4.19/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch
new file mode 100644 (file)
index 0000000..395e3db
--- /dev/null
@@ -0,0 +1,33 @@
+From 45457c01171fd1488a7000d1751c06ed8560ee38 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 21 May 2019 11:38:07 -0400
+Subject: media: usb: siano: Fix false-positive "uninitialized variable" warning
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 45457c01171fd1488a7000d1751c06ed8560ee38 upstream.
+
+GCC complains about an apparently uninitialized variable recently
+added to smsusb_init_device().  It's a false positive, but to silence
+the warning this patch adds a trivial initialization.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: kbuild test robot <lkp@intel.com>
+CC: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/siano/smsusb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -401,7 +401,7 @@ static int smsusb_init_device(struct usb
+       struct smsusb_device_t *dev;
+       void *mdev;
+       int i, rc;
+-      int in_maxp;
++      int in_maxp = 0;
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
diff --git a/queue-4.19/media-usb-siano-fix-general-protection-fault-in-smsusb.patch b/queue-4.19/media-usb-siano-fix-general-protection-fault-in-smsusb.patch
new file mode 100644 (file)
index 0000000..71f08aa
--- /dev/null
@@ -0,0 +1,90 @@
+From 31e0456de5be379b10fea0fa94a681057114a96e Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 7 May 2019 12:39:47 -0400
+Subject: media: usb: siano: Fix general protection fault in smsusb
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 31e0456de5be379b10fea0fa94a681057114a96e upstream.
+
+The syzkaller USB fuzzer found a general-protection-fault bug in the
+smsusb part of the Siano DVB driver.  The fault occurs during probe
+because the driver assumes without checking that the device has both
+IN and OUT endpoints and the IN endpoint is ep1.
+
+By slightly rearranging the driver's initialization code, we can make
+the appropriate checks early on and thus avoid the problem.  If the
+expected endpoints aren't present, the new code safely returns -ENODEV
+from the probe routine.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: syzbot+53f029db71c19a47325a@syzkaller.appspotmail.com
+CC: <stable@vger.kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/siano/smsusb.c |   33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -401,6 +401,7 @@ static int smsusb_init_device(struct usb
+       struct smsusb_device_t *dev;
+       void *mdev;
+       int i, rc;
++      int in_maxp;
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
+@@ -412,6 +413,24 @@ static int smsusb_init_device(struct usb
+       dev->udev = interface_to_usbdev(intf);
+       dev->state = SMSUSB_DISCONNECTED;
++      for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
++              struct usb_endpoint_descriptor *desc =
++                              &intf->cur_altsetting->endpoint[i].desc;
++
++              if (desc->bEndpointAddress & USB_DIR_IN) {
++                      dev->in_ep = desc->bEndpointAddress;
++                      in_maxp = usb_endpoint_maxp(desc);
++              } else {
++                      dev->out_ep = desc->bEndpointAddress;
++              }
++      }
++
++      pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
++      if (!dev->in_ep || !dev->out_ep) {      /* Missing endpoints? */
++              smsusb_term_device(intf);
++              return -ENODEV;
++      }
++
+       params.device_type = sms_get_board(board_id)->type;
+       switch (params.device_type) {
+@@ -426,24 +445,12 @@ static int smsusb_init_device(struct usb
+               /* fall-thru */
+       default:
+               dev->buffer_size = USB2_BUFFER_SIZE;
+-              dev->response_alignment =
+-                  le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
+-                  sizeof(struct sms_msg_hdr);
++              dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);
+               params.flags |= SMS_DEVICE_FAMILY2;
+               break;
+       }
+-      for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+-              if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
+-                      dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
+-              else
+-                      dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
+-      }
+-
+-      pr_debug("in_ep = %02x, out_ep = %02x\n",
+-              dev->in_ep, dev->out_ep);
+-
+       params.device = &dev->udev->dev;
+       params.usb_device = dev->udev;
+       params.buffer_size = dev->buffer_size;
diff --git a/queue-4.19/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch b/queue-4.19/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch
new file mode 100644 (file)
index 0000000..b2d4d46
--- /dev/null
@@ -0,0 +1,35 @@
+From d27e5e07f9c49bf2a6a4ef254ce531c1b4fb5a38 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.ibm.com>
+Date: Thu, 23 May 2019 15:23:45 +0200
+Subject: scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove
+
+From: Steffen Maier <maier@linux.ibm.com>
+
+commit d27e5e07f9c49bf2a6a4ef254ce531c1b4fb5a38 upstream.
+
+With this early return due to zfcp_unit child(ren), we don't use the
+zfcp_port reference from the earlier zfcp_get_port_by_wwpn() anymore and
+need to put it.
+
+Signed-off-by: Steffen Maier <maier@linux.ibm.com>
+Fixes: d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove")
+Cc: <stable@vger.kernel.org> #3.7+
+Reviewed-by: Jens Remus <jremus@linux.ibm.com>
+Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_sysfs.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/s390/scsi/zfcp_sysfs.c
++++ b/drivers/s390/scsi/zfcp_sysfs.c
+@@ -261,6 +261,7 @@ static ssize_t zfcp_sysfs_port_remove_st
+       if (atomic_read(&port->units) > 0) {
+               retval = -EBUSY;
+               mutex_unlock(&zfcp_sysfs_port_units_mutex);
++              put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
+               goto out;
+       }
+       /* port is about to be removed, so no more unit_add */
diff --git a/queue-4.19/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch b/queue-4.19/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch
new file mode 100644 (file)
index 0000000..6ee7d6e
--- /dev/null
@@ -0,0 +1,186 @@
+From ef4021fe5fd77ced0323cede27979d80a56211ca Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.ibm.com>
+Date: Thu, 23 May 2019 15:23:46 +0200
+Subject: scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs)
+
+From: Steffen Maier <maier@linux.ibm.com>
+
+commit ef4021fe5fd77ced0323cede27979d80a56211ca upstream.
+
+When the user tries to remove a zfcp port via sysfs, we only rejected it if
+there are zfcp unit children under the port. With purely automatically
+scanned LUNs there are no zfcp units but only SCSI devices. In such cases,
+the port_remove erroneously continued. We close the port and this
+implicitly closes all LUNs under the port. The SCSI devices survive with
+their private zfcp_scsi_dev still holding a reference to the "removed"
+zfcp_port (still allocated but invisible in sysfs) [zfcp_get_port_by_wwpn
+in zfcp_scsi_slave_alloc]. This is not a problem as long as the fc_rport
+stays blocked. Once (auto) port scan brings back the removed port, we
+unblock its fc_rport again by design.  However, there is no mechanism that
+would recover (open) the LUNs under the port (no "ersfs_3" without
+zfcp_unit [zfcp_erp_strategy_followup_success]).  Any pending or new I/O to
+such LUN leads to repeated:
+
+  Done: NEEDS_RETRY Result: hostbyte=DID_IMM_RETRY driverbyte=DRIVER_OK
+
+See also v4.10 commit 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race
+with LUN recovery"). Even a manual LUN recovery
+(echo 0 > /sys/bus/scsi/devices/H:C:T:L/zfcp_failed)
+does not help, as the LUN links to the old "removed" port which remains
+to lack ZFCP_STATUS_COMMON_RUNNING [zfcp_erp_required_act].
+The only workaround is to first ensure that the fc_rport is blocked
+(e.g. port_remove again in case it was re-discovered by (auto) port scan),
+then delete the SCSI devices, and finally re-discover by (auto) port scan.
+The port scan includes an fc_rport unblock, which in turn triggers
+a new scan on the scsi target to freshly get new pure auto scan LUNs.
+
+Fix this by rejecting port_remove also if there are SCSI devices
+(even without any zfcp_unit) under this port. Re-use mechanics from v3.7
+commit d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove").
+However, we have to give up zfcp_sysfs_port_units_mutex earlier in unit_add
+to prevent a deadlock with scsi_host scan taking shost->scan_mutex first
+and then zfcp_sysfs_port_units_mutex now in our zfcp_scsi_slave_alloc().
+
+Signed-off-by: Steffen Maier <maier@linux.ibm.com>
+Fixes: b62a8d9b45b9 ("[SCSI] zfcp: Use SCSI device data zfcp scsi dev instead of zfcp unit")
+Fixes: f8210e34887e ("[SCSI] zfcp: Allow midlayer to scan for LUNs when running in NPIV mode")
+Cc: <stable@vger.kernel.org> #2.6.37+
+Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_ext.h   |    1 
+ drivers/s390/scsi/zfcp_scsi.c  |    9 ++++++
+ drivers/s390/scsi/zfcp_sysfs.c |   54 ++++++++++++++++++++++++++++++++++++-----
+ drivers/s390/scsi/zfcp_unit.c  |    8 +++++-
+ 4 files changed, 65 insertions(+), 7 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -164,6 +164,7 @@ extern const struct attribute_group *zfc
+ extern struct mutex zfcp_sysfs_port_units_mutex;
+ extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
+ extern struct device_attribute *zfcp_sysfs_shost_attrs[];
++bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port);
+ /* zfcp_unit.c */
+ extern int zfcp_unit_add(struct zfcp_port *, u64);
+--- a/drivers/s390/scsi/zfcp_scsi.c
++++ b/drivers/s390/scsi/zfcp_scsi.c
+@@ -125,6 +125,15 @@ static int zfcp_scsi_slave_alloc(struct
+       zfcp_sdev->erp_action.port = port;
++      mutex_lock(&zfcp_sysfs_port_units_mutex);
++      if (zfcp_sysfs_port_is_removing(port)) {
++              /* port is already gone */
++              mutex_unlock(&zfcp_sysfs_port_units_mutex);
++              put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
++              return -ENXIO;
++      }
++      mutex_unlock(&zfcp_sysfs_port_units_mutex);
++
+       unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
+       if (unit)
+               put_device(&unit->dev);
+--- a/drivers/s390/scsi/zfcp_sysfs.c
++++ b/drivers/s390/scsi/zfcp_sysfs.c
+@@ -235,6 +235,53 @@ static ZFCP_DEV_ATTR(adapter, port_resca
+ DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
++static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port)
++{
++      lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
++      atomic_set(&port->units, -1);
++}
++
++bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port)
++{
++      lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
++      return atomic_read(&port->units) == -1;
++}
++
++static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port)
++{
++      struct zfcp_adapter *const adapter = port->adapter;
++      unsigned long flags;
++      struct scsi_device *sdev;
++      bool in_use = true;
++
++      mutex_lock(&zfcp_sysfs_port_units_mutex);
++      if (atomic_read(&port->units) > 0)
++              goto unlock_port_units_mutex; /* zfcp_unit(s) under port */
++
++      spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
++      __shost_for_each_device(sdev, adapter->scsi_host) {
++              const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
++
++              if (sdev->sdev_state == SDEV_DEL ||
++                  sdev->sdev_state == SDEV_CANCEL)
++                      continue;
++              if (zsdev->port != port)
++                      continue;
++              /* alive scsi_device under port of interest */
++              goto unlock_host_lock;
++      }
++
++      /* port is about to be removed, so no more unit_add or slave_alloc */
++      zfcp_sysfs_port_set_removing(port);
++      in_use = false;
++
++unlock_host_lock:
++      spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
++unlock_port_units_mutex:
++      mutex_unlock(&zfcp_sysfs_port_units_mutex);
++      return in_use;
++}
++
+ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
+                                           struct device_attribute *attr,
+                                           const char *buf, size_t count)
+@@ -257,16 +304,11 @@ static ssize_t zfcp_sysfs_port_remove_st
+       else
+               retval = 0;
+-      mutex_lock(&zfcp_sysfs_port_units_mutex);
+-      if (atomic_read(&port->units) > 0) {
++      if (zfcp_sysfs_port_in_use(port)) {
+               retval = -EBUSY;
+-              mutex_unlock(&zfcp_sysfs_port_units_mutex);
+               put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
+               goto out;
+       }
+-      /* port is about to be removed, so no more unit_add */
+-      atomic_set(&port->units, -1);
+-      mutex_unlock(&zfcp_sysfs_port_units_mutex);
+       write_lock_irq(&adapter->port_list_lock);
+       list_del(&port->list);
+--- a/drivers/s390/scsi/zfcp_unit.c
++++ b/drivers/s390/scsi/zfcp_unit.c
+@@ -124,7 +124,7 @@ int zfcp_unit_add(struct zfcp_port *port
+       int retval = 0;
+       mutex_lock(&zfcp_sysfs_port_units_mutex);
+-      if (atomic_read(&port->units) == -1) {
++      if (zfcp_sysfs_port_is_removing(port)) {
+               /* port is already gone */
+               retval = -ENODEV;
+               goto out;
+@@ -168,8 +168,14 @@ int zfcp_unit_add(struct zfcp_port *port
+       write_lock_irq(&port->unit_list_lock);
+       list_add_tail(&unit->list, &port->unit_list);
+       write_unlock_irq(&port->unit_list_lock);
++      /*
++       * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex
++       * due to      zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc()
++       */
++      mutex_unlock(&zfcp_sysfs_port_units_mutex);
+       zfcp_unit_scsi_scan(unit);
++      return retval;
+ out:
+       mutex_unlock(&zfcp_sysfs_port_units_mutex);
diff --git a/queue-4.19/series b/queue-4.19/series
new file mode 100644 (file)
index 0000000..59bf734
--- /dev/null
@@ -0,0 +1,24 @@
+sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch
+include-linux-bitops.h-sanitize-rotate-primitives.patch
+xhci-update-bounce-buffer-with-correct-sg-num.patch
+xhci-use-zu-for-printing-size_t-type.patch
+xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch
+usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch
+usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch
+usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch
+usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch
+usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch
+usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch
+usb-rio500-refuse-more-than-one-device-at-a-time.patch
+usb-rio500-fix-memory-leak-in-close-after-disconnect.patch
+media-usb-siano-fix-general-protection-fault-in-smsusb.patch
+media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch
+media-smsusb-better-handle-optional-alignment.patch
+brcmfmac-fix-null-pointer-derefence-during-usb-disconnect.patch
+scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch
+scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch
+tracing-avoid-memory-leak-in-predicate_parse.patch
+btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch
+btrfs-fix-race-updating-log-root-item-during-fsync.patch
+btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch
+btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch
diff --git a/queue-4.19/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch b/queue-4.19/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch
new file mode 100644 (file)
index 0000000..f32d28a
--- /dev/null
@@ -0,0 +1,47 @@
+From d3c976c14ad8af421134c428b0a89ff8dd3bd8f8 Mon Sep 17 00:00:00 2001
+From: James Clarke <jrtc27@jrtc27.com>
+Date: Wed, 29 May 2019 22:31:31 +0100
+Subject: sparc64: Fix regression in non-hypervisor TLB flush xcall
+
+From: James Clarke <jrtc27@jrtc27.com>
+
+commit d3c976c14ad8af421134c428b0a89ff8dd3bd8f8 upstream.
+
+Previously, %g2 would end up with the value PAGE_SIZE, but after the
+commit mentioned below it ends up with the value 1 due to being reused
+for a different purpose. We need it to be PAGE_SIZE as we use it to step
+through pages in our demap loop, otherwise we set different flags in the
+low 12 bits of the address written to, thereby doing things other than a
+nucleus page flush.
+
+Fixes: a74ad5e660a9 ("sparc64: Handle extremely large kernel TLB range flushes more gracefully.")
+Reported-by: Meelis Roos <mroos@linux.ee>
+Tested-by: Meelis Roos <mroos@linux.ee>
+Signed-off-by: James Clarke <jrtc27@jrtc27.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/sparc/mm/ultra.S |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/mm/ultra.S
++++ b/arch/sparc/mm/ultra.S
+@@ -587,7 +587,7 @@ xcall_flush_tlb_kernel_range:      /* 44 insn
+       sub             %g7, %g1, %g3
+       srlx            %g3, 18, %g2
+       brnz,pn         %g2, 2f
+-       add            %g2, 1, %g2
++       sethi          %hi(PAGE_SIZE), %g2
+       sub             %g3, %g2, %g3
+       or              %g1, 0x20, %g1          ! Nucleus
+ 1:    stxa            %g0, [%g1 + %g3] ASI_DMMU_DEMAP
+@@ -751,7 +751,7 @@ __cheetah_xcall_flush_tlb_kernel_range:
+       sub             %g7, %g1, %g3
+       srlx            %g3, 18, %g2
+       brnz,pn         %g2, 2f
+-       add            %g2, 1, %g2
++       sethi          %hi(PAGE_SIZE), %g2
+       sub             %g3, %g2, %g3
+       or              %g1, 0x20, %g1          ! Nucleus
+ 1:    stxa            %g0, [%g1 + %g3] ASI_DMMU_DEMAP
diff --git a/queue-4.19/tracing-avoid-memory-leak-in-predicate_parse.patch b/queue-4.19/tracing-avoid-memory-leak-in-predicate_parse.patch
new file mode 100644 (file)
index 0000000..a90b3c6
--- /dev/null
@@ -0,0 +1,53 @@
+From dfb4a6f2191a80c8b790117d0ff592fd712d3296 Mon Sep 17 00:00:00 2001
+From: Tomas Bortoli <tomasbortoli@gmail.com>
+Date: Tue, 28 May 2019 17:43:38 +0200
+Subject: tracing: Avoid memory leak in predicate_parse()
+
+From: Tomas Bortoli <tomasbortoli@gmail.com>
+
+commit dfb4a6f2191a80c8b790117d0ff592fd712d3296 upstream.
+
+In case of errors, predicate_parse() goes to the out_free label
+to free memory and to return an error code.
+
+However, predicate_parse() does not free the predicates of the
+temporary prog_stack array, thence leaking them.
+
+Link: http://lkml.kernel.org/r/20190528154338.29976-1-tomasbortoli@gmail.com
+
+Cc: stable@vger.kernel.org
+Fixes: 80765597bc587 ("tracing: Rewrite filter logic to be simpler and faster")
+Reported-by: syzbot+6b8e0fb820e570c59e19@syzkaller.appspotmail.com
+Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
+[ Added protection around freeing prog_stack[i].pred ]
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace_events_filter.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/kernel/trace/trace_events_filter.c
++++ b/kernel/trace/trace_events_filter.c
+@@ -427,7 +427,7 @@ predicate_parse(const char *str, int nr_
+       op_stack = kmalloc_array(nr_parens, sizeof(*op_stack), GFP_KERNEL);
+       if (!op_stack)
+               return ERR_PTR(-ENOMEM);
+-      prog_stack = kmalloc_array(nr_preds, sizeof(*prog_stack), GFP_KERNEL);
++      prog_stack = kcalloc(nr_preds, sizeof(*prog_stack), GFP_KERNEL);
+       if (!prog_stack) {
+               parse_error(pe, -ENOMEM, 0);
+               goto out_free;
+@@ -576,7 +576,11 @@ predicate_parse(const char *str, int nr_
+ out_free:
+       kfree(op_stack);
+       kfree(inverts);
+-      kfree(prog_stack);
++      if (prog_stack) {
++              for (i = 0; prog_stack[i].pred; i++)
++                      kfree(prog_stack[i].pred);
++              kfree(prog_stack);
++      }
+       return ERR_PTR(ret);
+ }
diff --git a/queue-4.19/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch b/queue-4.19/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch
new file mode 100644 (file)
index 0000000..9e0fae0
--- /dev/null
@@ -0,0 +1,37 @@
+From ea261113385ac0a71c2838185f39e8452d54b152 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Thu, 16 May 2019 17:08:31 +0200
+Subject: USB: Add LPM quirk for Surface Dock GigE adapter
+
+From: Maximilian Luz <luzmaximilian@gmail.com>
+
+commit ea261113385ac0a71c2838185f39e8452d54b152 upstream.
+
+Without USB_QUIRK_NO_LPM ethernet will not work and rtl8152 will
+complain with
+
+    r8152 <device...>: Stop submitting intr, status -71
+
+Adding the quirk resolves this. As the dock is externally powered, this
+should not have any drawbacks.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -209,6 +209,9 @@ static const struct usb_device_id usb_qu
+       /* Microsoft LifeCam-VX700 v2.0 */
+       { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
++      /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */
++      { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM },
++
+       /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
+       { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/queue-4.19/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch b/queue-4.19/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch
new file mode 100644 (file)
index 0000000..df1d9d0
--- /dev/null
@@ -0,0 +1,38 @@
+From a03ff54460817c76105f81f3aa8ef655759ccc9a Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 13 May 2019 13:14:29 -0400
+Subject: USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit a03ff54460817c76105f81f3aa8ef655759ccc9a upstream.
+
+The syzkaller USB fuzzer found a slab-out-of-bounds write bug in the
+USB core, caused by a failure to check the actual size of a BOS
+descriptor.  This patch adds a check to make sure the descriptor is at
+least as large as it is supposed to be, so that the code doesn't
+inadvertently access memory beyond the end of the allocated region
+when assigning to dev->bos->desc->bNumDeviceCaps later on.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: syzbot+71f1e64501a309fcc012@syzkaller.appspotmail.com
+CC: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -936,8 +936,8 @@ int usb_get_bos_descriptor(struct usb_de
+       /* Get BOS descriptor */
+       ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE);
+-      if (ret < USB_DT_BOS_SIZE) {
+-              dev_err(ddev, "unable to get BOS descriptor\n");
++      if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) {
++              dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n");
+               if (ret >= 0)
+                       ret = -ENOMSG;
+               kfree(bos);
diff --git a/queue-4.19/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch b/queue-4.19/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch
new file mode 100644 (file)
index 0000000..bdf9a35
--- /dev/null
@@ -0,0 +1,47 @@
+From e0feb73428b69322dd5caae90b0207de369b5575 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 9 May 2019 11:30:59 +0200
+Subject: USB: rio500: fix memory leak in close after disconnect
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit e0feb73428b69322dd5caae90b0207de369b5575 upstream.
+
+If a disconnected device is closed, rio_close() must free
+the buffers.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/rio500.c |   17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/rio500.c
++++ b/drivers/usb/misc/rio500.c
+@@ -86,9 +86,22 @@ static int close_rio(struct inode *inode
+ {
+       struct rio_usb_data *rio = &rio_instance;
+-      rio->isopen = 0;
++      /* against disconnect() */
++      mutex_lock(&rio500_mutex);
++      mutex_lock(&(rio->lock));
+-      dev_info(&rio->rio_dev->dev, "Rio closed.\n");
++      rio->isopen = 0;
++      if (!rio->present) {
++              /* cleanup has been delayed */
++              kfree(rio->ibuf);
++              kfree(rio->obuf);
++              rio->ibuf = NULL;
++              rio->obuf = NULL;
++      } else {
++              dev_info(&rio->rio_dev->dev, "Rio closed.\n");
++      }
++      mutex_unlock(&(rio->lock));
++      mutex_unlock(&rio500_mutex);
+       return 0;
+ }
diff --git a/queue-4.19/usb-rio500-refuse-more-than-one-device-at-a-time.patch b/queue-4.19/usb-rio500-refuse-more-than-one-device-at-a-time.patch
new file mode 100644 (file)
index 0000000..e2b634a
--- /dev/null
@@ -0,0 +1,83 @@
+From 3864d33943b4a76c6e64616280e98d2410b1190f Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 9 May 2019 11:30:58 +0200
+Subject: USB: rio500: refuse more than one device at a time
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 3864d33943b4a76c6e64616280e98d2410b1190f upstream.
+
+This driver is using a global variable. It cannot handle more than
+one device at a time. The issue has been existing since the dawn
+of the driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Reported-by: syzbot+35f04d136fc975a70da4@syzkaller.appspotmail.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/rio500.c |   24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/misc/rio500.c
++++ b/drivers/usb/misc/rio500.c
+@@ -447,15 +447,23 @@ static int probe_rio(struct usb_interfac
+ {
+       struct usb_device *dev = interface_to_usbdev(intf);
+       struct rio_usb_data *rio = &rio_instance;
+-      int retval;
++      int retval = 0;
+-      dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
++      mutex_lock(&rio500_mutex);
++      if (rio->present) {
++              dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum);
++              retval = -EBUSY;
++              goto bail_out;
++      } else {
++              dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
++      }
+       retval = usb_register_dev(intf, &usb_rio_class);
+       if (retval) {
+               dev_err(&dev->dev,
+                       "Not able to get a minor for this device.\n");
+-              return -ENOMEM;
++              retval = -ENOMEM;
++              goto bail_out;
+       }
+       rio->rio_dev = dev;
+@@ -464,7 +472,8 @@ static int probe_rio(struct usb_interfac
+               dev_err(&dev->dev,
+                       "probe_rio: Not enough memory for the output buffer\n");
+               usb_deregister_dev(intf, &usb_rio_class);
+-              return -ENOMEM;
++              retval = -ENOMEM;
++              goto bail_out;
+       }
+       dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
+@@ -473,7 +482,8 @@ static int probe_rio(struct usb_interfac
+                       "probe_rio: Not enough memory for the input buffer\n");
+               usb_deregister_dev(intf, &usb_rio_class);
+               kfree(rio->obuf);
+-              return -ENOMEM;
++              retval = -ENOMEM;
++              goto bail_out;
+       }
+       dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
+@@ -481,8 +491,10 @@ static int probe_rio(struct usb_interfac
+       usb_set_intfdata (intf, rio);
+       rio->present = 1;
++bail_out:
++      mutex_unlock(&rio500_mutex);
+-      return 0;
++      return retval;
+ }
+ static void disconnect_rio(struct usb_interface *intf)
diff --git a/queue-4.19/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch b/queue-4.19/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch
new file mode 100644 (file)
index 0000000..595fd52
--- /dev/null
@@ -0,0 +1,55 @@
+From 9a5729f68d3a82786aea110b1bfe610be318f80a Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 9 May 2019 14:41:50 +0200
+Subject: USB: sisusbvga: fix oops in error path of sisusb_probe
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 9a5729f68d3a82786aea110b1bfe610be318f80a upstream.
+
+The pointer used to log a failure of usb_register_dev() must
+be set before the error is logged.
+
+v2: fix that minor is not available before registration
+
+Signed-off-by: oliver Neukum <oneukum@suse.com>
+Reported-by: syzbot+a0cbdbd6d169020c8959@syzkaller.appspotmail.com
+Fixes: 7b5cd5fefbe02 ("USB: SisUSB2VGA: Convert printk to dev_* macros")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/sisusbvga/sisusb.c |   15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/misc/sisusbvga/sisusb.c
++++ b/drivers/usb/misc/sisusbvga/sisusb.c
+@@ -3029,6 +3029,13 @@ static int sisusb_probe(struct usb_inter
+       mutex_init(&(sisusb->lock));
++      sisusb->sisusb_dev = dev;
++      sisusb->vrambase   = SISUSB_PCI_MEMBASE;
++      sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
++      sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
++      sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
++      /* Everything else is zero */
++
+       /* Register device */
+       retval = usb_register_dev(intf, &usb_sisusb_class);
+       if (retval) {
+@@ -3039,13 +3046,7 @@ static int sisusb_probe(struct usb_inter
+               goto error_1;
+       }
+-      sisusb->sisusb_dev = dev;
+-      sisusb->minor      = intf->minor;
+-      sisusb->vrambase   = SISUSB_PCI_MEMBASE;
+-      sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
+-      sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
+-      sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
+-      /* Everything else is zero */
++      sisusb->minor = intf->minor;
+       /* Allocate buffers */
+       sisusb->ibufsize = SISUSB_IBUF_SIZE;
diff --git a/queue-4.19/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch b/queue-4.19/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch
new file mode 100644 (file)
index 0000000..fba3661
--- /dev/null
@@ -0,0 +1,106 @@
+From 7aa1bb2ffd84d6b9b5f546b079bb15cd0ab6e76e Mon Sep 17 00:00:00 2001
+From: Carsten Schmid <carsten_schmid@mentor.com>
+Date: Wed, 22 May 2019 14:33:59 +0300
+Subject: usb: xhci: avoid null pointer deref when bos field is NULL
+
+From: Carsten Schmid <carsten_schmid@mentor.com>
+
+commit 7aa1bb2ffd84d6b9b5f546b079bb15cd0ab6e76e upstream.
+
+With defective USB sticks we see the following error happen:
+usb 1-3: new high-speed USB device number 6 using xhci_hcd
+usb 1-3: device descriptor read/64, error -71
+usb 1-3: device descriptor read/64, error -71
+usb 1-3: new high-speed USB device number 7 using xhci_hcd
+usb 1-3: device descriptor read/64, error -71
+usb 1-3: unable to get BOS descriptor set
+usb 1-3: New USB device found, idVendor=0781, idProduct=5581
+usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+...
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
+
+This comes from the following place:
+[ 1660.215380] IP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd]
+[ 1660.222092] PGD 0 P4D 0
+[ 1660.224918] Oops: 0000 [#1] PREEMPT SMP NOPTI
+[ 1660.425520] CPU: 1 PID: 38 Comm: kworker/1:1 Tainted: P     U  W  O    4.14.67-apl #1
+[ 1660.434277] Workqueue: usb_hub_wq hub_event [usbcore]
+[ 1660.439918] task: ffffa295b6ae4c80 task.stack: ffffad4580150000
+[ 1660.446532] RIP: 0010:xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd]
+[ 1660.453821] RSP: 0018:ffffad4580153c70 EFLAGS: 00010046
+[ 1660.459655] RAX: 0000000000000000 RBX: ffffa295b4d7c000 RCX: 0000000000000002
+[ 1660.467625] RDX: 0000000000000002 RSI: ffffffff984a55b2 RDI: ffffffff984a55b2
+[ 1660.475586] RBP: ffffad4580153cc8 R08: 0000000000d6520a R09: 0000000000000001
+[ 1660.483556] R10: ffffad4580a004a0 R11: 0000000000000286 R12: ffffa295b4d7c000
+[ 1660.491525] R13: 0000000000010648 R14: ffffa295a84e1800 R15: 0000000000000000
+[ 1660.499494] FS:  0000000000000000(0000) GS:ffffa295bfc80000(0000) knlGS:0000000000000000
+[ 1660.508530] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1660.514947] CR2: 0000000000000008 CR3: 000000025a114000 CR4: 00000000003406a0
+[ 1660.522917] Call Trace:
+[ 1660.525657]  usb_set_usb2_hardware_lpm+0x3d/0x70 [usbcore]
+[ 1660.531792]  usb_disable_device+0x242/0x260 [usbcore]
+[ 1660.537439]  usb_disconnect+0xc1/0x2b0 [usbcore]
+[ 1660.542600]  hub_event+0x596/0x18f0 [usbcore]
+[ 1660.547467]  ? trace_preempt_on+0xdf/0x100
+[ 1660.552040]  ? process_one_work+0x1c1/0x410
+[ 1660.556708]  process_one_work+0x1d2/0x410
+[ 1660.561184]  ? preempt_count_add.part.3+0x21/0x60
+[ 1660.566436]  worker_thread+0x2d/0x3f0
+[ 1660.570522]  kthread+0x122/0x140
+[ 1660.574123]  ? process_one_work+0x410/0x410
+[ 1660.578792]  ? kthread_create_on_node+0x60/0x60
+[ 1660.583849]  ret_from_fork+0x3a/0x50
+[ 1660.587839] Code: 00 49 89 c3 49 8b 84 24 50 16 00 00 8d 4a ff 48 8d 04 c8 48 89 ca 4c 8b 10 45 8b 6a 04 48 8b 00 48 89 45 c0 49 8b 86 80 03 00 00 <48> 8b 40 08 8b 40 03 0f 1f 44 00 00 45 85 ff 0f 84 81 01 00 00
+[ 1660.608980] RIP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd] RSP: ffffad4580153c70
+[ 1660.617921] CR2: 0000000000000008
+
+Tracking this down shows that udev->bos is NULL in the following code:
+(xhci.c, in xhci_set_usb2_hardware_lpm)
+       field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);  <<<<<<< here
+
+       xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
+                       enable ? "enable" : "disable", port_num + 1);
+
+       if (enable) {
+               /* Host supports BESL timeout instead of HIRD */
+               if (udev->usb2_hw_lpm_besl_capable) {
+                       /* if device doesn't have a preferred BESL value use a
+                        * default one which works with mixed HIRD and BESL
+                        * systems. See XHCI_DEFAULT_BESL definition in xhci.h
+                        */
+                       if ((field & USB_BESL_SUPPORT) &&
+                           (field & USB_BESL_BASELINE_VALID))
+                               hird = USB_GET_BESL_BASELINE(field);
+                       else
+                               hird = udev->l1_params.besl;
+
+The failing case is when disabling LPM. So it is sufficient to avoid
+access to udev->bos by moving the instruction into the "enable" clause.
+
+Cc: Stable <stable@vger.kernel.org>
+Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4287,7 +4287,6 @@ static int xhci_set_usb2_hardware_lpm(st
+       pm_addr = ports[port_num]->addr + PORTPMSC;
+       pm_val = readl(pm_addr);
+       hlpm_addr = ports[port_num]->addr + PORTHLPMC;
+-      field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
+       xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
+                       enable ? "enable" : "disable", port_num + 1);
+@@ -4299,6 +4298,7 @@ static int xhci_set_usb2_hardware_lpm(st
+                        * default one which works with mixed HIRD and BESL
+                        * systems. See XHCI_DEFAULT_BESL definition in xhci.h
+                        */
++                      field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
+                       if ((field & USB_BESL_SUPPORT) &&
+                           (field & USB_BESL_BASELINE_VALID))
+                               hird = USB_GET_BESL_BASELINE(field);
diff --git a/queue-4.19/usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch b/queue-4.19/usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch
new file mode 100644 (file)
index 0000000..84f607d
--- /dev/null
@@ -0,0 +1,242 @@
+From 0c9e8b3cad654bfc499c10b652fbf8f0b890af8f Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Thu, 2 May 2019 13:47:02 -0600
+Subject: usbip: usbip_host: fix BUG: sleeping function called from invalid context
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 0c9e8b3cad654bfc499c10b652fbf8f0b890af8f upstream.
+
+stub_probe() and stub_disconnect() call functions which could call
+sleeping function in invalid context whil holding busid_lock.
+
+Fix the problem by refining the lock holds to short critical sections
+to change the busid_priv fields. This fix restructures the code to
+limit the lock holds in stub_probe() and stub_disconnect().
+
+stub_probe():
+
+[15217.927028] BUG: sleeping function called from invalid context at mm/slab.h:418
+[15217.927038] in_atomic(): 1, irqs_disabled(): 0, pid: 29087, name: usbip
+[15217.927044] 5 locks held by usbip/29087:
+[15217.927047]  #0: 0000000091647f28 (sb_writers#6){....}, at: vfs_write+0x191/0x1c0
+[15217.927062]  #1: 000000008f9ba75b (&of->mutex){....}, at: kernfs_fop_write+0xf7/0x1b0
+[15217.927072]  #2: 00000000872e5b4b (&dev->mutex){....}, at: __device_driver_lock+0x3b/0x50
+[15217.927082]  #3: 00000000e74ececc (&dev->mutex){....}, at: __device_driver_lock+0x46/0x50
+[15217.927090]  #4: 00000000b20abbe0 (&(&busid_table[i].busid_lock)->rlock){....}, at: get_busid_priv+0x48/0x60 [usbip_host]
+[15217.927103] CPU: 3 PID: 29087 Comm: usbip Tainted: G        W         5.1.0-rc6+ #40
+[15217.927106] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013
+[15217.927109] Call Trace:
+[15217.927118]  dump_stack+0x63/0x85
+[15217.927127]  ___might_sleep+0xff/0x120
+[15217.927133]  __might_sleep+0x4a/0x80
+[15217.927143]  kmem_cache_alloc_trace+0x1aa/0x210
+[15217.927156]  stub_probe+0xe8/0x440 [usbip_host]
+[15217.927171]  usb_probe_device+0x34/0x70
+
+stub_disconnect():
+
+[15279.182478] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:908
+[15279.182487] in_atomic(): 1, irqs_disabled(): 0, pid: 29114, name: usbip
+[15279.182492] 5 locks held by usbip/29114:
+[15279.182494]  #0: 0000000091647f28 (sb_writers#6){....}, at: vfs_write+0x191/0x1c0
+[15279.182506]  #1: 00000000702cf0f3 (&of->mutex){....}, at: kernfs_fop_write+0xf7/0x1b0
+[15279.182514]  #2: 00000000872e5b4b (&dev->mutex){....}, at: __device_driver_lock+0x3b/0x50
+[15279.182522]  #3: 00000000e74ececc (&dev->mutex){....}, at: __device_driver_lock+0x46/0x50
+[15279.182529]  #4: 00000000b20abbe0 (&(&busid_table[i].busid_lock)->rlock){....}, at: get_busid_priv+0x48/0x60 [usbip_host]
+[15279.182541] CPU: 0 PID: 29114 Comm: usbip Tainted: G        W         5.1.0-rc6+ #40
+[15279.182543] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013
+[15279.182546] Call Trace:
+[15279.182554]  dump_stack+0x63/0x85
+[15279.182561]  ___might_sleep+0xff/0x120
+[15279.182566]  __might_sleep+0x4a/0x80
+[15279.182574]  __mutex_lock+0x55/0x950
+[15279.182582]  ? get_busid_priv+0x48/0x60 [usbip_host]
+[15279.182587]  ? reacquire_held_locks+0xec/0x1a0
+[15279.182591]  ? get_busid_priv+0x48/0x60 [usbip_host]
+[15279.182597]  ? find_held_lock+0x94/0xa0
+[15279.182609]  mutex_lock_nested+0x1b/0x20
+[15279.182614]  ? mutex_lock_nested+0x1b/0x20
+[15279.182618]  kernfs_remove_by_name_ns+0x2a/0x90
+[15279.182625]  sysfs_remove_file_ns+0x15/0x20
+[15279.182629]  device_remove_file+0x19/0x20
+[15279.182634]  stub_disconnect+0x6d/0x180 [usbip_host]
+[15279.182643]  usb_unbind_device+0x27/0x60
+
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_dev.c |   65 ++++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 22 deletions(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -301,9 +301,17 @@ static int stub_probe(struct usb_device
+       const char *udev_busid = dev_name(&udev->dev);
+       struct bus_id_priv *busid_priv;
+       int rc = 0;
++      char save_status;
+       dev_dbg(&udev->dev, "Enter probe\n");
++      /* Not sure if this is our device. Allocate here to avoid
++       * calling alloc while holding busid_table lock.
++       */
++      sdev = stub_device_alloc(udev);
++      if (!sdev)
++              return -ENOMEM;
++
+       /* check we should claim or not by busid_table */
+       busid_priv = get_busid_priv(udev_busid);
+       if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
+@@ -318,14 +326,14 @@ static int stub_probe(struct usb_device
+                * See driver_probe_device() in driver/base/dd.c
+                */
+               rc = -ENODEV;
+-              goto call_put_busid_priv;
++              goto sdev_free;
+       }
+       if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
+               dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n",
+                        udev_busid);
+               rc = -ENODEV;
+-              goto call_put_busid_priv;
++              goto sdev_free;
+       }
+       if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
+@@ -334,15 +342,9 @@ static int stub_probe(struct usb_device
+                       udev_busid);
+               rc = -ENODEV;
+-              goto call_put_busid_priv;
++              goto sdev_free;
+       }
+-      /* ok, this is my device */
+-      sdev = stub_device_alloc(udev);
+-      if (!sdev) {
+-              rc = -ENOMEM;
+-              goto call_put_busid_priv;
+-      }
+       dev_info(&udev->dev,
+               "usbip-host: register new device (bus %u dev %u)\n",
+@@ -352,9 +354,13 @@ static int stub_probe(struct usb_device
+       /* set private data to usb_device */
+       dev_set_drvdata(&udev->dev, sdev);
++
+       busid_priv->sdev = sdev;
+       busid_priv->udev = udev;
++      save_status = busid_priv->status;
++      busid_priv->status = STUB_BUSID_ALLOC;
++
+       /*
+        * Claim this hub port.
+        * It doesn't matter what value we pass as owner
+@@ -367,15 +373,16 @@ static int stub_probe(struct usb_device
+               goto err_port;
+       }
++      /* release the busid_lock */
++      put_busid_priv(busid_priv);
++
+       rc = stub_add_files(&udev->dev);
+       if (rc) {
+               dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
+               goto err_files;
+       }
+-      busid_priv->status = STUB_BUSID_ALLOC;
+-      rc = 0;
+-      goto call_put_busid_priv;
++      return 0;
+ err_files:
+       usb_hub_release_port(udev->parent, udev->portnum,
+@@ -384,23 +391,24 @@ err_port:
+       dev_set_drvdata(&udev->dev, NULL);
+       usb_put_dev(udev);
++      /* we already have busid_priv, just lock busid_lock */
++      spin_lock(&busid_priv->busid_lock);
+       busid_priv->sdev = NULL;
++      busid_priv->status = save_status;
++sdev_free:
+       stub_device_free(sdev);
+-
+-call_put_busid_priv:
++      /* release the busid_lock */
+       put_busid_priv(busid_priv);
++
+       return rc;
+ }
+ static void shutdown_busid(struct bus_id_priv *busid_priv)
+ {
+-      if (busid_priv->sdev && !busid_priv->shutdown_busid) {
+-              busid_priv->shutdown_busid = 1;
+-              usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
++      usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
+-              /* wait for the stop of the event handler */
+-              usbip_stop_eh(&busid_priv->sdev->ud);
+-      }
++      /* wait for the stop of the event handler */
++      usbip_stop_eh(&busid_priv->sdev->ud);
+ }
+ /*
+@@ -432,6 +440,9 @@ static void stub_disconnect(struct usb_d
+       dev_set_drvdata(&udev->dev, NULL);
++      /* release busid_lock before call to remove device files */
++      put_busid_priv(busid_priv);
++
+       /*
+        * NOTE: rx/tx threads are invoked for each usb_device.
+        */
+@@ -442,18 +453,27 @@ static void stub_disconnect(struct usb_d
+                                 (struct usb_dev_state *) udev);
+       if (rc) {
+               dev_dbg(&udev->dev, "unable to release port\n");
+-              goto call_put_busid_priv;
++              return;
+       }
+       /* If usb reset is called from event handler */
+       if (usbip_in_eh(current))
+-              goto call_put_busid_priv;
++              return;
++
++      /* we already have busid_priv, just lock busid_lock */
++      spin_lock(&busid_priv->busid_lock);
++      if (!busid_priv->shutdown_busid)
++              busid_priv->shutdown_busid = 1;
++      /* release busid_lock */
++      put_busid_priv(busid_priv);
+       /* shutdown the current connection */
+       shutdown_busid(busid_priv);
+       usb_put_dev(sdev->udev);
++      /* we already have busid_priv, just lock busid_lock */
++      spin_lock(&busid_priv->busid_lock);
+       /* free sdev */
+       busid_priv->sdev = NULL;
+       stub_device_free(sdev);
+@@ -462,6 +482,7 @@ static void stub_disconnect(struct usb_d
+               busid_priv->status = STUB_BUSID_ADDED;
+ call_put_busid_priv:
++      /* release busid_lock */
+       put_busid_priv(busid_priv);
+ }
diff --git a/queue-4.19/usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch b/queue-4.19/usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch
new file mode 100644 (file)
index 0000000..1945afd
--- /dev/null
@@ -0,0 +1,154 @@
+From 3ea3091f1bd8586125848c62be295910e9802af0 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Wed, 29 May 2019 13:46:15 -0600
+Subject: usbip: usbip_host: fix stub_dev lock context imbalance regression
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 3ea3091f1bd8586125848c62be295910e9802af0 upstream.
+
+Fix the following sparse context imbalance regression introduced in
+a patch that fixed sleeping function called from invalid context bug.
+
+kbuild test robot reported on:
+
+tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git  usb-linus
+
+Regressions in current branch:
+
+drivers/usb/usbip/stub_dev.c:399:9: sparse: sparse: context imbalance in 'stub_probe' - different lock contexts for basic block
+drivers/usb/usbip/stub_dev.c:418:13: sparse: sparse: context imbalance in 'stub_disconnect' - different lock contexts for basic block
+drivers/usb/usbip/stub_dev.c:464:1-10: second lock on line 476
+
+Error ids grouped by kconfigs:
+
+recent_errors
+├── i386-allmodconfig
+│   └── drivers-usb-usbip-stub_dev.c:second-lock-on-line
+├── x86_64-allmodconfig
+│   ├── drivers-usb-usbip-stub_dev.c:sparse:sparse:context-imbalance-in-stub_disconnect-different-lock-contexts-for-basic-block
+│   └── drivers-usb-usbip-stub_dev.c:sparse:sparse:context-imbalance-in-stub_probe-different-lock-contexts-for-basic-block
+└── x86_64-allyesconfig
+    └── drivers-usb-usbip-stub_dev.c:second-lock-on-line
+
+This is a real problem in an error leg where spin_lock() is called on an
+already held lock.
+
+Fix the imbalance in stub_probe() and stub_disconnect().
+
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Fixes: 0c9e8b3cad65 ("usbip: usbip_host: fix BUG: sleeping function called from invalid context")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_dev.c |   36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -326,14 +326,17 @@ static int stub_probe(struct usb_device
+                * See driver_probe_device() in driver/base/dd.c
+                */
+               rc = -ENODEV;
+-              goto sdev_free;
++              if (!busid_priv)
++                      goto sdev_free;
++
++              goto call_put_busid_priv;
+       }
+       if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
+               dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n",
+                        udev_busid);
+               rc = -ENODEV;
+-              goto sdev_free;
++              goto call_put_busid_priv;
+       }
+       if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
+@@ -342,7 +345,7 @@ static int stub_probe(struct usb_device
+                       udev_busid);
+               rc = -ENODEV;
+-              goto sdev_free;
++              goto call_put_busid_priv;
+       }
+@@ -361,6 +364,9 @@ static int stub_probe(struct usb_device
+       save_status = busid_priv->status;
+       busid_priv->status = STUB_BUSID_ALLOC;
++      /* release the busid_lock */
++      put_busid_priv(busid_priv);
++
+       /*
+        * Claim this hub port.
+        * It doesn't matter what value we pass as owner
+@@ -373,9 +379,6 @@ static int stub_probe(struct usb_device
+               goto err_port;
+       }
+-      /* release the busid_lock */
+-      put_busid_priv(busid_priv);
+-
+       rc = stub_add_files(&udev->dev);
+       if (rc) {
+               dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
+@@ -395,11 +398,17 @@ err_port:
+       spin_lock(&busid_priv->busid_lock);
+       busid_priv->sdev = NULL;
+       busid_priv->status = save_status;
+-sdev_free:
+-      stub_device_free(sdev);
++      spin_unlock(&busid_priv->busid_lock);
++      /* lock is released - go to free */
++      goto sdev_free;
++
++call_put_busid_priv:
+       /* release the busid_lock */
+       put_busid_priv(busid_priv);
++sdev_free:
++      stub_device_free(sdev);
++
+       return rc;
+ }
+@@ -435,7 +444,9 @@ static void stub_disconnect(struct usb_d
+       /* get stub_device */
+       if (!sdev) {
+               dev_err(&udev->dev, "could not get device");
+-              goto call_put_busid_priv;
++              /* release busid_lock */
++              put_busid_priv(busid_priv);
++              return;
+       }
+       dev_set_drvdata(&udev->dev, NULL);
+@@ -465,7 +476,7 @@ static void stub_disconnect(struct usb_d
+       if (!busid_priv->shutdown_busid)
+               busid_priv->shutdown_busid = 1;
+       /* release busid_lock */
+-      put_busid_priv(busid_priv);
++      spin_unlock(&busid_priv->busid_lock);
+       /* shutdown the current connection */
+       shutdown_busid(busid_priv);
+@@ -480,10 +491,9 @@ static void stub_disconnect(struct usb_d
+       if (busid_priv->status == STUB_BUSID_ALLOC)
+               busid_priv->status = STUB_BUSID_ADDED;
+-
+-call_put_busid_priv:
+       /* release busid_lock */
+-      put_busid_priv(busid_priv);
++      spin_unlock(&busid_priv->busid_lock);
++      return;
+ }
+ #ifdef CONFIG_PM
diff --git a/queue-4.19/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch b/queue-4.19/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch
new file mode 100644 (file)
index 0000000..c8e6662
--- /dev/null
@@ -0,0 +1,76 @@
+From f7fac17ca925faa03fc5eb854c081a24075f8bad Mon Sep 17 00:00:00 2001
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+Date: Wed, 22 May 2019 14:34:01 +0300
+Subject: xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()
+
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+
+commit f7fac17ca925faa03fc5eb854c081a24075f8bad upstream.
+
+Xhci_handshake() implements the algorithm already captured by
+readl_poll_timeout_atomic(). Convert the former to use the latter to
+avoid repetition.
+
+Turned out this patch also fixes a bug on the AMD Stoneyridge platform
+where usleep(1) sometimes takes over 10ms.
+This means a 5 second timeout can easily take over 15 seconds which will
+trigger the watchdog and reboot the system.
+
+[Add info about patch fixing a bug to commit message -Mathias]
+Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
+Tested-by: Raul E Rangel <rrangel@chromium.org>
+Reviewed-by: Raul E Rangel <rrangel@chromium.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |   22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -9,6 +9,7 @@
+  */
+ #include <linux/pci.h>
++#include <linux/iopoll.h>
+ #include <linux/irq.h>
+ #include <linux/log2.h>
+ #include <linux/module.h>
+@@ -52,7 +53,6 @@ static bool td_on_ring(struct xhci_td *t
+       return false;
+ }
+-/* TODO: copied from ehci-hcd.c - can this be refactored? */
+ /*
+  * xhci_handshake - spin reading hc until handshake completes or fails
+  * @ptr: address of hc register to be read
+@@ -69,18 +69,16 @@ static bool td_on_ring(struct xhci_td *t
+ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
+ {
+       u32     result;
++      int     ret;
+-      do {
+-              result = readl(ptr);
+-              if (result == ~(u32)0)          /* card removed */
+-                      return -ENODEV;
+-              result &= mask;
+-              if (result == done)
+-                      return 0;
+-              udelay(1);
+-              usec--;
+-      } while (usec > 0);
+-      return -ETIMEDOUT;
++      ret = readl_poll_timeout_atomic(ptr, result,
++                                      (result & mask) == done ||
++                                      result == U32_MAX,
++                                      1, usec);
++      if (result == U32_MAX)          /* card removed */
++              return -ENODEV;
++
++      return ret;
+ }
+ /*
diff --git a/queue-4.19/xhci-update-bounce-buffer-with-correct-sg-num.patch b/queue-4.19/xhci-update-bounce-buffer-with-correct-sg-num.patch
new file mode 100644 (file)
index 0000000..3b4c6a9
--- /dev/null
@@ -0,0 +1,82 @@
+From 597c56e372dab2c7f79b8d700aad3a5deebf9d1b Mon Sep 17 00:00:00 2001
+From: Henry Lin <henryl@nvidia.com>
+Date: Wed, 22 May 2019 14:33:57 +0300
+Subject: xhci: update bounce buffer with correct sg num
+
+From: Henry Lin <henryl@nvidia.com>
+
+commit 597c56e372dab2c7f79b8d700aad3a5deebf9d1b upstream.
+
+This change fixes a data corruption issue occurred on USB hard disk for
+the case that bounce buffer is used during transferring data.
+
+While updating data between sg list and bounce buffer, current
+implementation passes mapped sg number (urb->num_mapped_sgs) to
+sg_pcopy_from_buffer() and sg_pcopy_to_buffer(). This causes data
+not get copied if target buffer is located in the elements after
+mapped sg elements. This change passes sg number for full list to
+fix issue.
+
+Besides, for copying data from bounce buffer, calling dma_unmap_single()
+on the bounce buffer before copying data to sg list can avoid cache issue.
+
+Fixes: f9c589e142d0 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer")
+Cc: <stable@vger.kernel.org> # v4.8+
+Signed-off-by: Henry Lin <henryl@nvidia.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -656,6 +656,7 @@ static void xhci_unmap_td_bounce_buffer(
+       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct xhci_segment *seg = td->bounce_seg;
+       struct urb *urb = td->urb;
++      size_t len;
+       if (!ring || !seg || !urb)
+               return;
+@@ -666,11 +667,14 @@ static void xhci_unmap_td_bounce_buffer(
+               return;
+       }
+-      /* for in tranfers we need to copy the data from bounce to sg */
+-      sg_pcopy_from_buffer(urb->sg, urb->num_mapped_sgs, seg->bounce_buf,
+-                           seg->bounce_len, seg->bounce_offs);
+       dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
+                        DMA_FROM_DEVICE);
++      /* for in tranfers we need to copy the data from bounce to sg */
++      len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
++                           seg->bounce_len, seg->bounce_offs);
++      if (len != seg->bounce_len)
++              xhci_warn(xhci, "WARN Wrong bounce buffer read length: %ld != %d\n",
++                              len, seg->bounce_len);
+       seg->bounce_len = 0;
+       seg->bounce_offs = 0;
+ }
+@@ -3104,6 +3108,7 @@ static int xhci_align_td(struct xhci_hcd
+       unsigned int unalign;
+       unsigned int max_pkt;
+       u32 new_buff_len;
++      size_t len;
+       max_pkt = usb_endpoint_maxp(&urb->ep->desc);
+       unalign = (enqd_len + *trb_buff_len) % max_pkt;
+@@ -3134,8 +3139,12 @@ static int xhci_align_td(struct xhci_hcd
+       /* create a max max_pkt sized bounce buffer pointed to by last trb */
+       if (usb_urb_dir_out(urb)) {
+-              sg_pcopy_to_buffer(urb->sg, urb->num_mapped_sgs,
++              len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
+                                  seg->bounce_buf, new_buff_len, enqd_len);
++              if (len != seg->bounce_len)
++                      xhci_warn(xhci,
++                              "WARN Wrong bounce buffer write length: %ld != %d\n",
++                              len, seg->bounce_len);
+               seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
+                                                max_pkt, DMA_TO_DEVICE);
+       } else {
diff --git a/queue-4.19/xhci-use-zu-for-printing-size_t-type.patch b/queue-4.19/xhci-use-zu-for-printing-size_t-type.patch
new file mode 100644 (file)
index 0000000..8a2642e
--- /dev/null
@@ -0,0 +1,47 @@
+From c1a145a3ed9a40f3b6145feb97789e8eb49c5566 Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@gmail.com>
+Date: Wed, 22 May 2019 10:35:29 -0300
+Subject: xhci: Use %zu for printing size_t type
+
+From: Fabio Estevam <festevam@gmail.com>
+
+commit c1a145a3ed9a40f3b6145feb97789e8eb49c5566 upstream.
+
+Commit 597c56e372da ("xhci: update bounce buffer with correct sg num")
+caused the following build warnings:
+
+drivers/usb/host/xhci-ring.c:676:19: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
+
+Use %zu for printing size_t type in order to fix the warnings.
+
+Fixes: 597c56e372da ("xhci: update bounce buffer with correct sg num")
+Reported-by: kbuild test robot <lkp@intel.com>
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -673,7 +673,7 @@ static void xhci_unmap_td_bounce_buffer(
+       len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
+                            seg->bounce_len, seg->bounce_offs);
+       if (len != seg->bounce_len)
+-              xhci_warn(xhci, "WARN Wrong bounce buffer read length: %ld != %d\n",
++              xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
+                               len, seg->bounce_len);
+       seg->bounce_len = 0;
+       seg->bounce_offs = 0;
+@@ -3143,7 +3143,7 @@ static int xhci_align_td(struct xhci_hcd
+                                  seg->bounce_buf, new_buff_len, enqd_len);
+               if (len != seg->bounce_len)
+                       xhci_warn(xhci,
+-                              "WARN Wrong bounce buffer write length: %ld != %d\n",
++                              "WARN Wrong bounce buffer write length: %zu != %d\n",
+                               len, seg->bounce_len);
+               seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
+                                                max_pkt, DMA_TO_DEVICE);