From: Greg Kroah-Hartman Date: Tue, 4 Jun 2019 08:20:23 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v5.1.8~51 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=96b0405887d94fa2268acac774b33c1d5caf34db;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: btrfs-fix-race-updating-log-root-item-during-fsync.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 xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch --- diff --git a/queue-4.4/btrfs-fix-race-updating-log-root-item-during-fsync.patch b/queue-4.4/btrfs-fix-race-updating-log-root-item-during-fsync.patch new file mode 100644 index 0000000000..e637515bf1 --- /dev/null +++ b/queue-4.4/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 +@@ -2809,6 +2809,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. +@@ -2827,8 +2833,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.4/include-linux-bitops.h-sanitize-rotate-primitives.patch b/queue-4.4/include-linux-bitops.h-sanitize-rotate-primitives.patch new file mode 100644 index 0000000000..4aa1c6ed6e --- /dev/null +++ b/queue-4.4/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 +@@ -68,7 +68,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)); + } + + /** +@@ -78,7 +78,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)); + } + + /** +@@ -88,7 +88,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)); + } + + /** +@@ -98,7 +98,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)); + } + + /** +@@ -108,7 +108,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)); + } + + /** +@@ -118,7 +118,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)); + } + + /** +@@ -128,7 +128,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)); + } + + /** +@@ -138,7 +138,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.4/media-smsusb-better-handle-optional-alignment.patch b/queue-4.4/media-smsusb-better-handle-optional-alignment.patch new file mode 100644 index 0000000000..410fd3dc75 --- /dev/null +++ b/queue-4.4/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 +@@ -391,7 +391,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); +@@ -409,14 +409,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; + } +@@ -435,7 +435,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.4/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch b/queue-4.4/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch new file mode 100644 index 0000000000..f9ebae21ec --- /dev/null +++ b/queue-4.4/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 +@@ -391,7 +391,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.4/media-usb-siano-fix-general-protection-fault-in-smsusb.patch b/queue-4.4/media-usb-siano-fix-general-protection-fault-in-smsusb.patch new file mode 100644 index 0000000000..74f31dacee --- /dev/null +++ b/queue-4.4/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 +@@ -391,6 +391,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); +@@ -402,6 +403,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) { +@@ -416,24 +435,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.4/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch b/queue-4.4/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch new file mode 100644 index 0000000000..bc1d9ac64f --- /dev/null +++ b/queue-4.4/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 +@@ -263,6 +263,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.4/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch b/queue-4.4/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch new file mode 100644 index 0000000000..79d613b3de --- /dev/null +++ b/queue-4.4/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 +@@ -124,6 +124,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 +@@ -237,6 +237,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) +@@ -259,16 +306,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 +@@ -122,7 +122,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; +@@ -166,8 +166,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.4/series b/queue-4.4/series index d67b6193c9..2193f1ccf9 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -189,3 +189,18 @@ 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-v2.patch +sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch +include-linux-bitops.h-sanitize-rotate-primitives.patch +xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch +usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.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-race-updating-log-root-item-during-fsync.patch diff --git a/queue-4.4/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch b/queue-4.4/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch new file mode 100644 index 0000000000..6eedac2b9e --- /dev/null +++ b/queue-4.4/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 +@@ -586,7 +586,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 +@@ -750,7 +750,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.4/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch b/queue-4.4/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch new file mode 100644 index 0000000000..bb5cd0ef01 --- /dev/null +++ b/queue-4.4/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.4/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch b/queue-4.4/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch new file mode 100644 index 0000000000..55e56243e1 --- /dev/null +++ b/queue-4.4/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 +@@ -902,8 +902,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.4/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch b/queue-4.4/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch new file mode 100644 index 0000000000..ac32e9d423 --- /dev/null +++ b/queue-4.4/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 +@@ -103,9 +103,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.4/usb-rio500-refuse-more-than-one-device-at-a-time.patch b/queue-4.4/usb-rio500-refuse-more-than-one-device-at-a-time.patch new file mode 100644 index 0000000000..eec3f33e4b --- /dev/null +++ b/queue-4.4/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 +@@ -464,15 +464,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; +@@ -481,7 +489,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); + +@@ -490,7 +499,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); + +@@ -498,8 +508,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.4/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch b/queue-4.4/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch new file mode 100644 index 0000000000..22cbc117a0 --- /dev/null +++ b/queue-4.4/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 +@@ -3103,6 +3103,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) { +@@ -3112,13 +3119,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.4/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch b/queue-4.4/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch new file mode 100644 index 0000000000..200e75c8d2 --- /dev/null +++ b/queue-4.4/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 +@@ -4191,7 +4191,6 @@ int xhci_set_usb2_hardware_lpm(struct us + 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); +@@ -4203,6 +4202,7 @@ int xhci_set_usb2_hardware_lpm(struct us + * 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.4/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch b/queue-4.4/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch new file mode 100644 index 0000000000..ff9ff1ad79 --- /dev/null +++ b/queue-4.4/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 +@@ -46,7 +47,6 @@ static unsigned int quirks; + module_param(quirks, uint, S_IRUGO); + MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); + +-/* 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 +@@ -63,18 +63,16 @@ MODULE_PARM_DESC(quirks, "Bit flags for + 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; + } + + /*