From: Greg Kroah-Hartman Date: Tue, 4 Jun 2019 08:20:45 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v5.1.8~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a4f7a213bc842780c550f059923b5d1acf523f30;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: 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 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 --- diff --git a/queue-4.14/btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch b/queue-4.14/btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch new file mode 100644 index 00000000000..52c4f4470a7 --- /dev/null +++ b/queue-4.14/btrfs-fix-fsync-not-persisting-changed-attributes-of-a-directory.patch @@ -0,0 +1,97 @@ +From 60d9f50308e5df19bc18c2fefab0eba4a843900a Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Thu, 16 May 2019 15:48:55 +0100 +Subject: Btrfs: fix fsync not persisting changed attributes of a directory + +From: Filipe Manana + +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 + + + + $ 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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 12 ------------ + 1 file changed, 12 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -5332,7 +5332,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 +@@ -5352,16 +5351,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; +@@ -6091,7 +6080,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.14/btrfs-fix-race-updating-log-root-item-during-fsync.patch b/queue-4.14/btrfs-fix-race-updating-log-root-item-during-fsync.patch new file mode 100644 index 00000000000..cf233a3d95e --- /dev/null +++ b/queue-4.14/btrfs-fix-race-updating-log-root-item-during-fsync.patch @@ -0,0 +1,125 @@ +From 06989c799f04810f6876900d4760c0edda369cf7 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 15 May 2019 16:03:17 +0100 +Subject: Btrfs: fix race updating log root item during fsync + +From: Filipe Manana + +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 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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -2907,6 +2907,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. +@@ -2925,8 +2931,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)) { + /* diff --git a/queue-4.14/btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch b/queue-4.14/btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch new file mode 100644 index 00000000000..199325991a8 --- /dev/null +++ b/queue-4.14/btrfs-fix-wrong-ctime-and-mtime-of-a-directory-after-log-replay.patch @@ -0,0 +1,80 @@ +From 5338e43abbab13791144d37fd8846847062351c6 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +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 + +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 + + + + $ 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 +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -6580,8 +6580,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.14/btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch b/queue-4.14/btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch new file mode 100644 index 00000000000..bd43fcc3b3b --- /dev/null +++ b/queue-4.14/btrfs-incremental-send-fix-file-corruption-when-no-holes-feature-is-enabled.patch @@ -0,0 +1,80 @@ +From 6b1f72e5b82a5c2a4da4d1ebb8cc01913ddbea21 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +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 + +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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/send.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -5013,6 +5013,12 @@ static int send_hole(struct send_ctx *sc + u64 len; + int ret = 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.14/include-linux-bitops.h-sanitize-rotate-primitives.patch b/queue-4.14/include-linux-bitops.h-sanitize-rotate-primitives.patch new file mode 100644 index 00000000000..a4dc39aa62c --- /dev/null +++ b/queue-4.14/include-linux-bitops.h-sanitize-rotate-primitives.patch @@ -0,0 +1,133 @@ +From ef4d6f6b275c498f8e5626c99dbeefdc5027f843 Mon Sep 17 00:00:00 2001 +From: Rasmus Villemoes +Date: Tue, 14 May 2019 15:43:27 -0700 +Subject: include/linux/bitops.h: sanitize rotate primitives + +From: Rasmus Villemoes + +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 : + 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 +Reported-by: Ido Schimmel +Tested-by: Ido Schimmel +Reviewed-by: Will Deacon +Cc: Vadim Pasternak +Cc: Andrey Ryabinin +Cc: Jacek Anaszewski +Cc: Pavel Machek +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Matthias Kaehlcke +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/bitops.h | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/include/linux/bitops.h ++++ b/include/linux/bitops.h +@@ -59,7 +59,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)); + } + + /** +@@ -69,7 +69,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)); + } + + /** +@@ -79,7 +79,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)); + } + + /** +@@ -89,7 +89,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)); + } + + /** +@@ -99,7 +99,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)); + } + + /** +@@ -109,7 +109,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)); + } + + /** +@@ -119,7 +119,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)); + } + + /** +@@ -129,7 +129,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.14/media-smsusb-better-handle-optional-alignment.patch b/queue-4.14/media-smsusb-better-handle-optional-alignment.patch new file mode 100644 index 00000000000..1d0160108fe --- /dev/null +++ b/queue-4.14/media-smsusb-better-handle-optional-alignment.patch @@ -0,0 +1,72 @@ +From a47686636d84eaec5c9c6e84bd5f96bed34d526d Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 24 May 2019 10:59:43 -0400 +Subject: media: smsusb: better handle optional alignment + +From: Mauro Carvalho Chehab + +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: +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -402,7 +402,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); +@@ -420,14 +420,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; + } +@@ -446,7 +446,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.14/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch b/queue-4.14/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch new file mode 100644 index 00000000000..0ccb1b26430 --- /dev/null +++ b/queue-4.14/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch @@ -0,0 +1,33 @@ +From 45457c01171fd1488a7000d1751c06ed8560ee38 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 21 May 2019 11:38:07 -0400 +Subject: media: usb: siano: Fix false-positive "uninitialized variable" warning + +From: Alan Stern + +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 +Reported-by: kbuild test robot +CC: +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -402,7 +402,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.14/media-usb-siano-fix-general-protection-fault-in-smsusb.patch b/queue-4.14/media-usb-siano-fix-general-protection-fault-in-smsusb.patch new file mode 100644 index 00000000000..230c4e700f6 --- /dev/null +++ b/queue-4.14/media-usb-siano-fix-general-protection-fault-in-smsusb.patch @@ -0,0 +1,90 @@ +From 31e0456de5be379b10fea0fa94a681057114a96e Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 7 May 2019 12:39:47 -0400 +Subject: media: usb: siano: Fix general protection fault in smsusb + +From: Alan Stern + +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 +Reported-and-tested-by: syzbot+53f029db71c19a47325a@syzkaller.appspotmail.com +CC: +Reviewed-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -402,6 +402,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); +@@ -413,6 +414,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) { +@@ -427,24 +446,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.buffer_size = dev->buffer_size; + params.num_buffers = MAX_BUFFERS; diff --git a/queue-4.14/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch b/queue-4.14/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch new file mode 100644 index 00000000000..b9d9cf8d589 --- /dev/null +++ b/queue-4.14/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch @@ -0,0 +1,35 @@ +From d27e5e07f9c49bf2a6a4ef254ce531c1b4fb5a38 Mon Sep 17 00:00:00 2001 +From: Steffen Maier +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 + +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 +Fixes: d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove") +Cc: #3.7+ +Reviewed-by: Jens Remus +Reviewed-by: Benjamin Block +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -264,6 +264,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.14/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch b/queue-4.14/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch new file mode 100644 index 00000000000..a65cf18f0ea --- /dev/null +++ b/queue-4.14/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch @@ -0,0 +1,186 @@ +From ef4021fe5fd77ced0323cede27979d80a56211ca Mon Sep 17 00:00:00 2001 +From: Steffen Maier +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 + +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 +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: #2.6.37+ +Reviewed-by: Benjamin Block +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -161,6 +161,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 +@@ -238,6 +238,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) +@@ -260,16 +307,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.14/series b/queue-4.14/series index a9282828356..e3dc4feeecb 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -18,3 +18,25 @@ crypto-vmx-ghash-do-nosimd-fallback-manually.patch xen-pciback-don-t-disable-pci_command-on-pci-device-reset.patch revert-tipc-fix-modprobe-tipc-failed-after-switch-order-of-device-registration.patch tipc-fix-modprobe-tipc-failed-after-switch-order-of-device-registration.patch +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 +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 +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.14/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch b/queue-4.14/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch new file mode 100644 index 00000000000..f32d28a904c --- /dev/null +++ b/queue-4.14/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch @@ -0,0 +1,47 @@ +From d3c976c14ad8af421134c428b0a89ff8dd3bd8f8 Mon Sep 17 00:00:00 2001 +From: James Clarke +Date: Wed, 29 May 2019 22:31:31 +0100 +Subject: sparc64: Fix regression in non-hypervisor TLB flush xcall + +From: James Clarke + +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 +Tested-by: Meelis Roos +Signed-off-by: James Clarke +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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.14/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch b/queue-4.14/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch new file mode 100644 index 00000000000..bb5cd0ef016 --- /dev/null +++ b/queue-4.14/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch @@ -0,0 +1,37 @@ +From ea261113385ac0a71c2838185f39e8452d54b152 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Thu, 16 May 2019 17:08:31 +0200 +Subject: USB: Add LPM quirk for Surface Dock GigE adapter + +From: Maximilian Luz + +commit ea261113385ac0a71c2838185f39e8452d54b152 upstream. + +Without USB_QUIRK_NO_LPM ethernet will not work and rtl8152 will +complain with + + r8152 : 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 +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -64,6 +64,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.14/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch b/queue-4.14/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch new file mode 100644 index 00000000000..df1d9d0e852 --- /dev/null +++ b/queue-4.14/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch @@ -0,0 +1,38 @@ +From a03ff54460817c76105f81f3aa8ef655759ccc9a Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 + +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 +Reported-and-tested-by: syzbot+71f1e64501a309fcc012@syzkaller.appspotmail.com +CC: +Signed-off-by: Greg Kroah-Hartman + +--- + 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.14/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch b/queue-4.14/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch new file mode 100644 index 00000000000..006835a87c3 --- /dev/null +++ b/queue-4.14/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch @@ -0,0 +1,47 @@ +From e0feb73428b69322dd5caae90b0207de369b5575 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 9 May 2019 11:30:59 +0200 +Subject: USB: rio500: fix memory leak in close after disconnect + +From: Oliver Neukum + +commit e0feb73428b69322dd5caae90b0207de369b5575 upstream. + +If a disconnected device is closed, rio_close() must free +the buffers. + +Signed-off-by: Oliver Neukum +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -99,9 +99,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.14/usb-rio500-refuse-more-than-one-device-at-a-time.patch b/queue-4.14/usb-rio500-refuse-more-than-one-device-at-a-time.patch new file mode 100644 index 00000000000..6531ef321cf --- /dev/null +++ b/queue-4.14/usb-rio500-refuse-more-than-one-device-at-a-time.patch @@ -0,0 +1,83 @@ +From 3864d33943b4a76c6e64616280e98d2410b1190f Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 9 May 2019 11:30:58 +0200 +Subject: USB: rio500: refuse more than one device at a time + +From: Oliver Neukum + +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 +Reported-by: syzbot+35f04d136fc975a70da4@syzkaller.appspotmail.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -460,15 +460,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; +@@ -477,7 +485,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); + +@@ -486,7 +495,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); + +@@ -494,8 +504,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.14/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch b/queue-4.14/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch new file mode 100644 index 00000000000..69957499196 --- /dev/null +++ b/queue-4.14/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch @@ -0,0 +1,55 @@ +From 9a5729f68d3a82786aea110b1bfe610be318f80a Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 9 May 2019 14:41:50 +0200 +Subject: USB: sisusbvga: fix oops in error path of sisusb_probe + +From: Oliver Neukum + +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 +Reported-by: syzbot+a0cbdbd6d169020c8959@syzkaller.appspotmail.com +Fixes: 7b5cd5fefbe02 ("USB: SisUSB2VGA: Convert printk to dev_* macros") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -3028,6 +3028,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) { +@@ -3038,13 +3045,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.14/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch b/queue-4.14/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch new file mode 100644 index 00000000000..af9252edc73 --- /dev/null +++ b/queue-4.14/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch @@ -0,0 +1,106 @@ +From 7aa1bb2ffd84d6b9b5f546b079bb15cd0ab6e76e Mon Sep 17 00:00:00 2001 +From: Carsten Schmid +Date: Wed, 22 May 2019 14:33:59 +0300 +Subject: usb: xhci: avoid null pointer deref when bos field is NULL + +From: Carsten Schmid + +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 +Signed-off-by: Carsten Schmid +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -4153,7 +4153,6 @@ static int xhci_set_usb2_hardware_lpm(st + pm_addr = port_array[port_num] + PORTPMSC; + pm_val = readl(pm_addr); + hlpm_addr = port_array[port_num] + 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); +@@ -4165,6 +4164,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.14/usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch b/queue-4.14/usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch new file mode 100644 index 00000000000..087a7582355 --- /dev/null +++ b/queue-4.14/usbip-usbip_host-fix-bug-sleeping-function-called-from-invalid-context.patch @@ -0,0 +1,242 @@ +From 0c9e8b3cad654bfc499c10b652fbf8f0b890af8f Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 2 May 2019 13:47:02 -0600 +Subject: usbip: usbip_host: fix BUG: sleeping function called from invalid context + +From: Shuah Khan + +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 +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -315,9 +315,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) || +@@ -332,14 +340,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")) { +@@ -348,15 +356,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", +@@ -366,9 +368,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 +@@ -381,15 +387,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, +@@ -398,23 +405,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); + } + + /* +@@ -446,6 +454,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. + */ +@@ -456,18 +467,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); +@@ -476,6 +496,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.14/usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch b/queue-4.14/usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch new file mode 100644 index 00000000000..d5335c2ade0 --- /dev/null +++ b/queue-4.14/usbip-usbip_host-fix-stub_dev-lock-context-imbalance-regression.patch @@ -0,0 +1,154 @@ +From 3ea3091f1bd8586125848c62be295910e9802af0 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +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 + +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 +Fixes: 0c9e8b3cad65 ("usbip: usbip_host: fix BUG: sleeping function called from invalid context") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -340,14 +340,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")) { +@@ -356,7 +359,7 @@ static int stub_probe(struct usb_device + udev_busid); + + rc = -ENODEV; +- goto sdev_free; ++ goto call_put_busid_priv; + } + + +@@ -375,6 +378,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 +@@ -387,9 +393,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); +@@ -409,11 +412,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; + } + +@@ -449,7 +458,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); +@@ -479,7 +490,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); +@@ -494,10 +505,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.14/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch b/queue-4.14/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch new file mode 100644 index 00000000000..456e2364246 --- /dev/null +++ b/queue-4.14/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch @@ -0,0 +1,76 @@ +From f7fac17ca925faa03fc5eb854c081a24075f8bad Mon Sep 17 00:00:00 2001 +From: Andrey Smirnov +Date: Wed, 22 May 2019 14:34:01 +0300 +Subject: xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() + +From: Andrey Smirnov + +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 +Tested-by: Raul E Rangel +Reviewed-by: Raul E Rangel +Cc: +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -21,6 +21,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -62,7 +63,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 +@@ -79,18 +79,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.14/xhci-update-bounce-buffer-with-correct-sg-num.patch b/queue-4.14/xhci-update-bounce-buffer-with-correct-sg-num.patch new file mode 100644 index 00000000000..11c67c9ebe7 --- /dev/null +++ b/queue-4.14/xhci-update-bounce-buffer-with-correct-sg-num.patch @@ -0,0 +1,82 @@ +From 597c56e372dab2c7f79b8d700aad3a5deebf9d1b Mon Sep 17 00:00:00 2001 +From: Henry Lin +Date: Wed, 22 May 2019 14:33:57 +0300 +Subject: xhci: update bounce buffer with correct sg num + +From: Henry Lin + +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: # v4.8+ +Signed-off-by: Henry Lin +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -667,6 +667,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; +@@ -677,11 +678,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; + } +@@ -3186,6 +3190,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; +@@ -3216,8 +3221,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.14/xhci-use-zu-for-printing-size_t-type.patch b/queue-4.14/xhci-use-zu-for-printing-size_t-type.patch new file mode 100644 index 00000000000..4737c683986 --- /dev/null +++ b/queue-4.14/xhci-use-zu-for-printing-size_t-type.patch @@ -0,0 +1,47 @@ +From c1a145a3ed9a40f3b6145feb97789e8eb49c5566 Mon Sep 17 00:00:00 2001 +From: Fabio Estevam +Date: Wed, 22 May 2019 10:35:29 -0300 +Subject: xhci: Use %zu for printing size_t type + +From: Fabio Estevam + +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 +Signed-off-by: Fabio Estevam +Cc: stable +Acked-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -684,7 +684,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; +@@ -3225,7 +3225,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);