diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-06-04 16:49:14 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-06-04 16:49:14 +0200 |
commit | 4cc7a25b8e2a0da7967c567bc80f1b3c8520f5bf (patch) | |
tree | b237a13b1973245ef32a5dd6772a096f6d8b26f6 | |
parent | 05713e1337ed9909737e55d97d94777209a71658 (diff) | |
download | queue-3.18-4cc7a25b8e2a0da7967c567bc80f1b3c8520f5bf.tar.gz |
3.18 patches
15 files changed, 978 insertions, 0 deletions
diff --git a/btrfs-fix-race-updating-log-root-item-during-fsync.patch b/btrfs-fix-race-updating-log-root-item-during-fsync.patch new file mode 100644 index 0000000..77e2e83 --- /dev/null +++ b/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 <fdmanana@suse.com> +Date: Wed, 15 May 2019 16:03:17 +0100 +Subject: Btrfs: fix race updating log root item during fsync + +From: Filipe Manana <fdmanana@suse.com> + +commit 06989c799f04810f6876900d4760c0edda369cf7 upstream. + +When syncing the log, the final phase of a fsync operation, we need to +either create a log root's item or update the existing item in the log +tree of log roots, and that depends on the current value of the log +root's log_transid - if it's 1 we need to create the log root item, +otherwise it must exist already and we update it. Since there is no +synchronization between updating the log_transid and checking it for +deciding whether the log root's item needs to be created or updated, we +end up with a tiny race window that results in attempts to update the +item to fail because the item was not yet created: + + CPU 1 CPU 2 + + btrfs_sync_log() + + lock root->log_mutex + + set log root's log_transid to 1 + + unlock root->log_mutex + + btrfs_sync_log() + + lock root->log_mutex + + sets log root's + log_transid to 2 + + unlock root->log_mutex + + update_log_root() + + sees log root's log_transid + with a value of 2 + + calls btrfs_update_root(), + which fails with -EUCLEAN + and causes transaction abort + +Until recently the race lead to a BUG_ON at btrfs_update_root(), but after +the recent commit 7ac1e464c4d47 ("btrfs: Don't panic when we can't find a +root key") we just abort the current transaction. + +A sample trace of the BUG_ON() on a SLE12 kernel: + + ------------[ cut here ]------------ + kernel BUG at ../fs/btrfs/root-tree.c:157! + Oops: Exception in kernel mode, sig: 5 [#1] + SMP NR_CPUS=2048 NUMA pSeries + (...) + Supported: Yes, External + CPU: 78 PID: 76303 Comm: rtas_errd Tainted: G X 4.4.156-94.57-default #1 + task: c00000ffa906d010 ti: c00000ff42b08000 task.ti: c00000ff42b08000 + NIP: d000000036ae5cdc LR: d000000036ae5cd8 CTR: 0000000000000000 + REGS: c00000ff42b0b860 TRAP: 0700 Tainted: G X (4.4.156-94.57-default) + MSR: 8000000002029033 <SF,VEC,EE,ME,IR,DR,RI,LE> CR: 22444484 XER: 20000000 + CFAR: d000000036aba66c SOFTE: 1 + GPR00: d000000036ae5cd8 c00000ff42b0bae0 d000000036bda220 0000000000000054 + GPR04: 0000000000000001 0000000000000000 c00007ffff8d37c8 0000000000000000 + GPR08: c000000000e19c00 0000000000000000 0000000000000000 3736343438312079 + GPR12: 3930373337303434 c000000007a3a800 00000000007fffff 0000000000000023 + GPR16: c00000ffa9d26028 c00000ffa9d261f8 0000000000000010 c00000ffa9d2ab28 + GPR20: c00000ff42b0bc48 0000000000000001 c00000ff9f0d9888 0000000000000001 + GPR24: c00000ffa9d26000 c00000ffa9d261e8 c00000ffa9d2a800 c00000ff9f0d9888 + GPR28: c00000ffa9d26028 c00000ffa9d2aa98 0000000000000001 c00000ffa98f5b20 + NIP [d000000036ae5cdc] btrfs_update_root+0x25c/0x4e0 [btrfs] + LR [d000000036ae5cd8] btrfs_update_root+0x258/0x4e0 [btrfs] + Call Trace: + [c00000ff42b0bae0] [d000000036ae5cd8] btrfs_update_root+0x258/0x4e0 [btrfs] (unreliable) + [c00000ff42b0bba0] [d000000036b53610] btrfs_sync_log+0x2d0/0xc60 [btrfs] + [c00000ff42b0bce0] [d000000036b1785c] btrfs_sync_file+0x44c/0x4e0 [btrfs] + [c00000ff42b0bd80] [c00000000032e300] vfs_fsync_range+0x70/0x120 + [c00000ff42b0bdd0] [c00000000032e44c] do_fsync+0x5c/0xb0 + [c00000ff42b0be10] [c00000000032e8dc] SyS_fdatasync+0x2c/0x40 + [c00000ff42b0be30] [c000000000009488] system_call+0x3c/0x100 + Instruction dump: + 7f43d378 4bffebb9 60000000 88d90008 3d220000 e8b90000 3b390009 e87a01f0 + e8898e08 e8f90000 4bfd48e5 60000000 <0fe00000> e95b0060 39200004 394a0ea0 + ---[ end trace 8f2dc8f919cabab8 ]--- + +So fix this by doing the check of log_transid and updating or creating the +log root's item while holding the root's log_mutex. + +Fixes: 7237f1833601d ("Btrfs: fix tree logs parallel sync") +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Filipe Manana <fdmanana@suse.com> +Signed-off-by: David Sterba <dsterba@suse.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + fs/btrfs/tree-log.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -2565,6 +2565,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. +@@ -2583,8 +2589,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)) { + smp_mb(); diff --git a/cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch b/cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch new file mode 100644 index 0000000..eab5190 --- /dev/null +++ b/cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch @@ -0,0 +1,37 @@ +From 31fad7d41e73731f05b8053d17078638cf850fa6 Mon Sep 17 00:00:00 2001 +From: Roberto Bergantinos Corpas <rbergant@redhat.com> +Date: Tue, 28 May 2019 09:38:14 +0200 +Subject: CIFS: cifs_read_allocate_pages: don't iterate through whole page array on ENOMEM + +From: Roberto Bergantinos Corpas <rbergant@redhat.com> + +commit 31fad7d41e73731f05b8053d17078638cf850fa6 upstream. + + In cifs_read_allocate_pages, in case of ENOMEM, we go through +whole rdata->pages array but we have failed the allocation before +nr_pages, therefore we may end up calling put_page with NULL +pointer, causing oops + +Signed-off-by: Roberto Bergantinos Corpas <rbergant@redhat.com> +Acked-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + fs/cifs/file.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -2836,7 +2836,9 @@ cifs_read_allocate_pages(struct cifs_rea + } + + if (rc) { +- for (i = 0; i < nr_pages; i++) { ++ unsigned int nr_page_failed = i; ++ ++ for (i = 0; i < nr_page_failed; i++) { + put_page(rdata->pages[i]); + rdata->pages[i] = NULL; + } diff --git a/kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch b/kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch new file mode 100644 index 0000000..2475872 --- /dev/null +++ b/kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch @@ -0,0 +1,50 @@ +From 98af37d624ed8c83f1953b1b6b2f6866011fc064 Mon Sep 17 00:00:00 2001 +From: Zhenliang Wei <weizhenliang@huawei.com> +Date: Fri, 31 May 2019 22:30:52 -0700 +Subject: kernel/signal.c: trace_signal_deliver when signal_group_exit + +From: Zhenliang Wei <weizhenliang@huawei.com> + +commit 98af37d624ed8c83f1953b1b6b2f6866011fc064 upstream. + +In the fixes commit, removing SIGKILL from each thread signal mask and +executing "goto fatal" directly will skip the call to +"trace_signal_deliver". At this point, the delivery tracking of the +SIGKILL signal will be inaccurate. + +Therefore, we need to add trace_signal_deliver before "goto fatal" after +executing sigdelset. + +Note: SEND_SIG_NOINFO matches the fact that SIGKILL doesn't have any info. + +Link: http://lkml.kernel.org/r/20190425025812.91424-1-weizhenliang@huawei.com +Fixes: cf43a757fd4944 ("signal: Restore the stop PTRACE_EVENT_EXIT") +Signed-off-by: Zhenliang Wei <weizhenliang@huawei.com> +Reviewed-by: Christian Brauner <christian@brauner.io> +Reviewed-by: Oleg Nesterov <oleg@redhat.com> +Cc: Eric W. Biederman <ebiederm@xmission.com> +Cc: Ivan Delalande <colona@arista.com> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Deepa Dinamani <deepa.kernel@gmail.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + kernel/signal.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2287,6 +2287,8 @@ relock: + if (signal_group_exit(signal)) { + ksig->info.si_signo = signr = SIGKILL; + sigdelset(¤t->pending.signal, SIGKILL); ++ trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, ++ &sighand->action[SIGKILL - 1]); + recalc_sigpending(); + goto fatal; + } diff --git a/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch b/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch new file mode 100644 index 0000000..6584a07 --- /dev/null +++ b/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 <stern@rowland.harvard.edu> +Date: Tue, 21 May 2019 11:38:07 -0400 +Subject: media: usb: siano: Fix false-positive "uninitialized variable" warning + +From: Alan Stern <stern@rowland.harvard.edu> + +commit 45457c01171fd1488a7000d1751c06ed8560ee38 upstream. + +GCC complains about an apparently uninitialized variable recently +added to smsusb_init_device(). It's a false positive, but to silence +the warning this patch adds a trivial initialization. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Reported-by: kbuild test robot <lkp@intel.com> +CC: <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/media/usb/siano/smsusb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/usb/siano/smsusb.c ++++ b/drivers/media/usb/siano/smsusb.c +@@ -351,7 +351,7 @@ static int smsusb_init_device(struct usb + struct smsdevice_params_t params; + struct smsusb_device_t *dev; + 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/media-usb-siano-fix-general-protection-fault-in-smsusb.patch b/media-usb-siano-fix-general-protection-fault-in-smsusb.patch new file mode 100644 index 0000000..879a3a2 --- /dev/null +++ b/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 <stern@rowland.harvard.edu> +Date: Tue, 7 May 2019 12:39:47 -0400 +Subject: media: usb: siano: Fix general protection fault in smsusb + +From: Alan Stern <stern@rowland.harvard.edu> + +commit 31e0456de5be379b10fea0fa94a681057114a96e upstream. + +The syzkaller USB fuzzer found a general-protection-fault bug in the +smsusb part of the Siano DVB driver. The fault occurs during probe +because the driver assumes without checking that the device has both +IN and OUT endpoints and the IN endpoint is ep1. + +By slightly rearranging the driver's initialization code, we can make +the appropriate checks early on and thus avoid the problem. If the +expected endpoints aren't present, the new code safely returns -ENODEV +from the probe routine. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Reported-and-tested-by: syzbot+53f029db71c19a47325a@syzkaller.appspotmail.com +CC: <stable@vger.kernel.org> +Reviewed-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/media/usb/siano/smsusb.c | 33 ++++++++++++++++++++------------- + 1 file changed, 20 insertions(+), 13 deletions(-) + +--- a/drivers/media/usb/siano/smsusb.c ++++ b/drivers/media/usb/siano/smsusb.c +@@ -351,6 +351,7 @@ static int smsusb_init_device(struct usb + struct smsdevice_params_t params; + struct smsusb_device_t *dev; + int i, rc; ++ int in_maxp; + + /* create device object */ + dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); +@@ -364,6 +365,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; ++ } ++ } ++ ++ sms_info("in_ep = %02x, out_ep = %02x", 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) { +@@ -378,24 +397,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; +- } +- +- sms_info("in_ep = %02x, out_ep = %02x", +- 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/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch b/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch new file mode 100644 index 0000000..b2d4d46 --- /dev/null +++ b/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 <maier@linux.ibm.com> +Date: Thu, 23 May 2019 15:23:45 +0200 +Subject: scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove + +From: Steffen Maier <maier@linux.ibm.com> + +commit d27e5e07f9c49bf2a6a4ef254ce531c1b4fb5a38 upstream. + +With this early return due to zfcp_unit child(ren), we don't use the +zfcp_port reference from the earlier zfcp_get_port_by_wwpn() anymore and +need to put it. + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Fixes: d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove") +Cc: <stable@vger.kernel.org> #3.7+ +Reviewed-by: Jens Remus <jremus@linux.ibm.com> +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/s390/scsi/zfcp_sysfs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/s390/scsi/zfcp_sysfs.c ++++ b/drivers/s390/scsi/zfcp_sysfs.c +@@ -261,6 +261,7 @@ static ssize_t zfcp_sysfs_port_remove_st + if (atomic_read(&port->units) > 0) { + retval = -EBUSY; + mutex_unlock(&zfcp_sysfs_port_units_mutex); ++ put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */ + goto out; + } + /* port is about to be removed, so no more unit_add */ diff --git a/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch b/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch new file mode 100644 index 0000000..ab9934e --- /dev/null +++ b/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 <maier@linux.ibm.com> +Date: Thu, 23 May 2019 15:23:46 +0200 +Subject: scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) + +From: Steffen Maier <maier@linux.ibm.com> + +commit ef4021fe5fd77ced0323cede27979d80a56211ca upstream. + +When the user tries to remove a zfcp port via sysfs, we only rejected it if +there are zfcp unit children under the port. With purely automatically +scanned LUNs there are no zfcp units but only SCSI devices. In such cases, +the port_remove erroneously continued. We close the port and this +implicitly closes all LUNs under the port. The SCSI devices survive with +their private zfcp_scsi_dev still holding a reference to the "removed" +zfcp_port (still allocated but invisible in sysfs) [zfcp_get_port_by_wwpn +in zfcp_scsi_slave_alloc]. This is not a problem as long as the fc_rport +stays blocked. Once (auto) port scan brings back the removed port, we +unblock its fc_rport again by design. However, there is no mechanism that +would recover (open) the LUNs under the port (no "ersfs_3" without +zfcp_unit [zfcp_erp_strategy_followup_success]). Any pending or new I/O to +such LUN leads to repeated: + + Done: NEEDS_RETRY Result: hostbyte=DID_IMM_RETRY driverbyte=DRIVER_OK + +See also v4.10 commit 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race +with LUN recovery"). Even a manual LUN recovery +(echo 0 > /sys/bus/scsi/devices/H:C:T:L/zfcp_failed) +does not help, as the LUN links to the old "removed" port which remains +to lack ZFCP_STATUS_COMMON_RUNNING [zfcp_erp_required_act]. +The only workaround is to first ensure that the fc_rport is blocked +(e.g. port_remove again in case it was re-discovered by (auto) port scan), +then delete the SCSI devices, and finally re-discover by (auto) port scan. +The port scan includes an fc_rport unblock, which in turn triggers +a new scan on the scsi target to freshly get new pure auto scan LUNs. + +Fix this by rejecting port_remove also if there are SCSI devices +(even without any zfcp_unit) under this port. Re-use mechanics from v3.7 +commit d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove"). +However, we have to give up zfcp_sysfs_port_units_mutex earlier in unit_add +to prevent a deadlock with scsi_host scan taking shost->scan_mutex first +and then zfcp_sysfs_port_units_mutex now in our zfcp_scsi_slave_alloc(). + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Fixes: b62a8d9b45b9 ("[SCSI] zfcp: Use SCSI device data zfcp scsi dev instead of zfcp unit") +Fixes: f8210e34887e ("[SCSI] zfcp: Allow midlayer to scan for LUNs when running in NPIV mode") +Cc: <stable@vger.kernel.org> #2.6.37+ +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/s390/scsi/zfcp_ext.h | 1 + drivers/s390/scsi/zfcp_scsi.c | 9 ++++++ + drivers/s390/scsi/zfcp_sysfs.c | 54 ++++++++++++++++++++++++++++++++++++----- + drivers/s390/scsi/zfcp_unit.c | 8 +++++- + 4 files changed, 65 insertions(+), 7 deletions(-) + +--- a/drivers/s390/scsi/zfcp_ext.h ++++ b/drivers/s390/scsi/zfcp_ext.h +@@ -148,6 +148,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 +@@ -147,6 +147,15 @@ static int zfcp_scsi_slave_alloc(struct + + zfcp_sdev->erp_action.port = port; + ++ mutex_lock(&zfcp_sysfs_port_units_mutex); ++ if (zfcp_sysfs_port_is_removing(port)) { ++ /* port is already gone */ ++ mutex_unlock(&zfcp_sysfs_port_units_mutex); ++ put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */ ++ return -ENXIO; ++ } ++ mutex_unlock(&zfcp_sysfs_port_units_mutex); ++ + unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); + if (unit) + put_device(&unit->dev); +--- a/drivers/s390/scsi/zfcp_sysfs.c ++++ b/drivers/s390/scsi/zfcp_sysfs.c +@@ -235,6 +235,53 @@ static ZFCP_DEV_ATTR(adapter, port_resca + + DEFINE_MUTEX(zfcp_sysfs_port_units_mutex); + ++static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port) ++{ ++ lockdep_assert_held(&zfcp_sysfs_port_units_mutex); ++ atomic_set(&port->units, -1); ++} ++ ++bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port) ++{ ++ lockdep_assert_held(&zfcp_sysfs_port_units_mutex); ++ return atomic_read(&port->units) == -1; ++} ++ ++static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port) ++{ ++ struct zfcp_adapter *const adapter = port->adapter; ++ unsigned long flags; ++ struct scsi_device *sdev; ++ bool in_use = true; ++ ++ mutex_lock(&zfcp_sysfs_port_units_mutex); ++ if (atomic_read(&port->units) > 0) ++ goto unlock_port_units_mutex; /* zfcp_unit(s) under port */ ++ ++ spin_lock_irqsave(adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, adapter->scsi_host) { ++ const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev); ++ ++ if (sdev->sdev_state == SDEV_DEL || ++ sdev->sdev_state == SDEV_CANCEL) ++ continue; ++ if (zsdev->port != port) ++ continue; ++ /* alive scsi_device under port of interest */ ++ goto unlock_host_lock; ++ } ++ ++ /* port is about to be removed, so no more unit_add or slave_alloc */ ++ zfcp_sysfs_port_set_removing(port); ++ in_use = false; ++ ++unlock_host_lock: ++ spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); ++unlock_port_units_mutex: ++ mutex_unlock(&zfcp_sysfs_port_units_mutex); ++ return in_use; ++} ++ + static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +@@ -257,16 +304,11 @@ static ssize_t zfcp_sysfs_port_remove_st + else + retval = 0; + +- mutex_lock(&zfcp_sysfs_port_units_mutex); +- if (atomic_read(&port->units) > 0) { ++ if (zfcp_sysfs_port_in_use(port)) { + retval = -EBUSY; +- mutex_unlock(&zfcp_sysfs_port_units_mutex); + put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */ + goto out; + } +- /* port is about to be removed, so no more unit_add */ +- atomic_set(&port->units, -1); +- mutex_unlock(&zfcp_sysfs_port_units_mutex); + + write_lock_irq(&adapter->port_list_lock); + list_del(&port->list); +--- a/drivers/s390/scsi/zfcp_unit.c ++++ b/drivers/s390/scsi/zfcp_unit.c +@@ -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); @@ -48,5 +48,19 @@ usbnet-fix-kernel-crash-after-disconnect.patch tipc-avoid-copying-bytes-beyond-the-supplied-data.patch net-stmmac-fix-reset-gpio-free-missing.patch net-mvpp2-fix-bad-mvpp2_txq_sched_token_cntr_reg-queue-value.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 +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 +tty-max310x-fix-external-crystal-register-setup.patch +kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch +cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch crypto-gcm-fix-error-return-code-in-crypto_gcm_create_common.patch crypto-gcm-fix-incompatibility-between-gcm-and-gcm_base.patch diff --git a/tty-max310x-fix-external-crystal-register-setup.patch b/tty-max310x-fix-external-crystal-register-setup.patch new file mode 100644 index 0000000..5f46c3a --- /dev/null +++ b/tty-max310x-fix-external-crystal-register-setup.patch @@ -0,0 +1,42 @@ +From 5d24f455c182d5116dd5db8e1dc501115ecc9c2c Mon Sep 17 00:00:00 2001 +From: Joe Burmeister <joe.burmeister@devtank.co.uk> +Date: Mon, 13 May 2019 11:23:57 +0100 +Subject: tty: max310x: Fix external crystal register setup + +From: Joe Burmeister <joe.burmeister@devtank.co.uk> + +commit 5d24f455c182d5116dd5db8e1dc501115ecc9c2c upstream. + +The datasheet states: + + Bit 4: ClockEnSet the ClockEn bit high to enable an external clocking +(crystal or clock generator at XIN). Set the ClockEn bit to 0 to disable +clocking + Bit 1: CrystalEnSet the CrystalEn bit high to enable the crystal +oscillator. When using an external clock source at XIN, CrystalEn must +be set low. + +The bit 4, MAX310X_CLKSRC_EXTCLK_BIT, should be set and was not. + +This was required to make the MAX3107 with an external crystal on our +board able to send or receive data. + +Signed-off-by: Joe Burmeister <joe.burmeister@devtank.co.uk> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/tty/serial/max310x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/max310x.c ++++ b/drivers/tty/serial/max310x.c +@@ -568,7 +568,7 @@ static int max310x_set_ref_clk(struct ma + } + + /* Configure clock source */ +- clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT; ++ clksrc = MAX310X_CLKSRC_EXTCLK_BIT | (xtal ? MAX310X_CLKSRC_CRYST_BIT : 0); + + /* Configure PLL */ + if (pllcfg) { diff --git a/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch b/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch new file mode 100644 index 0000000..5cd85b5 --- /dev/null +++ b/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 <luzmaximilian@gmail.com> +Date: Thu, 16 May 2019 17:08:31 +0200 +Subject: USB: Add LPM quirk for Surface Dock GigE adapter + +From: Maximilian Luz <luzmaximilian@gmail.com> + +commit ea261113385ac0a71c2838185f39e8452d54b152 upstream. + +Without USB_QUIRK_NO_LPM ethernet will not work and rtl8152 will +complain with + + r8152 <device...>: Stop submitting intr, status -71 + +Adding the quirk resolves this. As the dock is externally powered, this +should not have any drawbacks. + +Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -56,6 +56,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/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch b/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch new file mode 100644 index 0000000..376197a --- /dev/null +++ b/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 <stern@rowland.harvard.edu> +Date: Mon, 13 May 2019 13:14:29 -0400 +Subject: USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor + +From: Alan Stern <stern@rowland.harvard.edu> + +commit a03ff54460817c76105f81f3aa8ef655759ccc9a upstream. + +The syzkaller USB fuzzer found a slab-out-of-bounds write bug in the +USB core, caused by a failure to check the actual size of a BOS +descriptor. This patch adds a check to make sure the descriptor is at +least as large as it is supposed to be, so that the code doesn't +inadvertently access memory beyond the end of the allocated region +when assigning to dev->bos->desc->bNumDeviceCaps later on. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Reported-and-tested-by: syzbot+71f1e64501a309fcc012@syzkaller.appspotmail.com +CC: <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/core/config.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -818,8 +818,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/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch b/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch new file mode 100644 index 0000000..ac32e9d --- /dev/null +++ b/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 <oneukum@suse.com> +Date: Thu, 9 May 2019 11:30:59 +0200 +Subject: USB: rio500: fix memory leak in close after disconnect + +From: Oliver Neukum <oneukum@suse.com> + +commit e0feb73428b69322dd5caae90b0207de369b5575 upstream. + +If a disconnected device is closed, rio_close() must free +the buffers. + +Signed-off-by: Oliver Neukum <oneukum@suse.com> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/misc/rio500.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/rio500.c ++++ b/drivers/usb/misc/rio500.c +@@ -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/usb-rio500-refuse-more-than-one-device-at-a-time.patch b/usb-rio500-refuse-more-than-one-device-at-a-time.patch new file mode 100644 index 0000000..eec3f33 --- /dev/null +++ b/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 <oneukum@suse.com> +Date: Thu, 9 May 2019 11:30:58 +0200 +Subject: USB: rio500: refuse more than one device at a time + +From: Oliver Neukum <oneukum@suse.com> + +commit 3864d33943b4a76c6e64616280e98d2410b1190f upstream. + +This driver is using a global variable. It cannot handle more than +one device at a time. The issue has been existing since the dawn +of the driver. + +Signed-off-by: Oliver Neukum <oneukum@suse.com> +Reported-by: syzbot+35f04d136fc975a70da4@syzkaller.appspotmail.com +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/misc/rio500.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +--- a/drivers/usb/misc/rio500.c ++++ b/drivers/usb/misc/rio500.c +@@ -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/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch b/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch new file mode 100644 index 0000000..93ec2c7 --- /dev/null +++ b/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 <oneukum@suse.com> +Date: Thu, 9 May 2019 14:41:50 +0200 +Subject: USB: sisusbvga: fix oops in error path of sisusb_probe + +From: Oliver Neukum <oneukum@suse.com> + +commit 9a5729f68d3a82786aea110b1bfe610be318f80a upstream. + +The pointer used to log a failure of usb_register_dev() must +be set before the error is logged. + +v2: fix that minor is not available before registration + +Signed-off-by: oliver Neukum <oneukum@suse.com> +Reported-by: syzbot+a0cbdbd6d169020c8959@syzkaller.appspotmail.com +Fixes: 7b5cd5fefbe02 ("USB: SisUSB2VGA: Convert printk to dev_* macros") +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/misc/sisusbvga/sisusb.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/drivers/usb/misc/sisusbvga/sisusb.c ++++ b/drivers/usb/misc/sisusbvga/sisusb.c +@@ -3093,6 +3093,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 */ + if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { + dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n", +@@ -3101,13 +3108,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/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch b/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch new file mode 100644 index 0000000..d1d6e23 --- /dev/null +++ b/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 <carsten_schmid@mentor.com> +Date: Wed, 22 May 2019 14:33:59 +0300 +Subject: usb: xhci: avoid null pointer deref when bos field is NULL + +From: Carsten Schmid <carsten_schmid@mentor.com> + +commit 7aa1bb2ffd84d6b9b5f546b079bb15cd0ab6e76e upstream. + +With defective USB sticks we see the following error happen: +usb 1-3: new high-speed USB device number 6 using xhci_hcd +usb 1-3: device descriptor read/64, error -71 +usb 1-3: device descriptor read/64, error -71 +usb 1-3: new high-speed USB device number 7 using xhci_hcd +usb 1-3: device descriptor read/64, error -71 +usb 1-3: unable to get BOS descriptor set +usb 1-3: New USB device found, idVendor=0781, idProduct=5581 +usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +... +BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 + +This comes from the following place: +[ 1660.215380] IP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd] +[ 1660.222092] PGD 0 P4D 0 +[ 1660.224918] Oops: 0000 [#1] PREEMPT SMP NOPTI +[ 1660.425520] CPU: 1 PID: 38 Comm: kworker/1:1 Tainted: P U W O 4.14.67-apl #1 +[ 1660.434277] Workqueue: usb_hub_wq hub_event [usbcore] +[ 1660.439918] task: ffffa295b6ae4c80 task.stack: ffffad4580150000 +[ 1660.446532] RIP: 0010:xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd] +[ 1660.453821] RSP: 0018:ffffad4580153c70 EFLAGS: 00010046 +[ 1660.459655] RAX: 0000000000000000 RBX: ffffa295b4d7c000 RCX: 0000000000000002 +[ 1660.467625] RDX: 0000000000000002 RSI: ffffffff984a55b2 RDI: ffffffff984a55b2 +[ 1660.475586] RBP: ffffad4580153cc8 R08: 0000000000d6520a R09: 0000000000000001 +[ 1660.483556] R10: ffffad4580a004a0 R11: 0000000000000286 R12: ffffa295b4d7c000 +[ 1660.491525] R13: 0000000000010648 R14: ffffa295a84e1800 R15: 0000000000000000 +[ 1660.499494] FS: 0000000000000000(0000) GS:ffffa295bfc80000(0000) knlGS:0000000000000000 +[ 1660.508530] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 1660.514947] CR2: 0000000000000008 CR3: 000000025a114000 CR4: 00000000003406a0 +[ 1660.522917] Call Trace: +[ 1660.525657] usb_set_usb2_hardware_lpm+0x3d/0x70 [usbcore] +[ 1660.531792] usb_disable_device+0x242/0x260 [usbcore] +[ 1660.537439] usb_disconnect+0xc1/0x2b0 [usbcore] +[ 1660.542600] hub_event+0x596/0x18f0 [usbcore] +[ 1660.547467] ? trace_preempt_on+0xdf/0x100 +[ 1660.552040] ? process_one_work+0x1c1/0x410 +[ 1660.556708] process_one_work+0x1d2/0x410 +[ 1660.561184] ? preempt_count_add.part.3+0x21/0x60 +[ 1660.566436] worker_thread+0x2d/0x3f0 +[ 1660.570522] kthread+0x122/0x140 +[ 1660.574123] ? process_one_work+0x410/0x410 +[ 1660.578792] ? kthread_create_on_node+0x60/0x60 +[ 1660.583849] ret_from_fork+0x3a/0x50 +[ 1660.587839] Code: 00 49 89 c3 49 8b 84 24 50 16 00 00 8d 4a ff 48 8d 04 c8 48 89 ca 4c 8b 10 45 8b 6a 04 48 8b 00 48 89 45 c0 49 8b 86 80 03 00 00 <48> 8b 40 08 8b 40 03 0f 1f 44 00 00 45 85 ff 0f 84 81 01 00 00 +[ 1660.608980] RIP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd] RSP: ffffad4580153c70 +[ 1660.617921] CR2: 0000000000000008 + +Tracking this down shows that udev->bos is NULL in the following code: +(xhci.c, in xhci_set_usb2_hardware_lpm) + field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); <<<<<<< here + + xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", + enable ? "enable" : "disable", port_num + 1); + + if (enable) { + /* Host supports BESL timeout instead of HIRD */ + if (udev->usb2_hw_lpm_besl_capable) { + /* if device doesn't have a preferred BESL value use a + * default one which works with mixed HIRD and BESL + * systems. See XHCI_DEFAULT_BESL definition in xhci.h + */ + if ((field & USB_BESL_SUPPORT) && + (field & USB_BESL_BASELINE_VALID)) + hird = USB_GET_BESL_BASELINE(field); + else + hird = udev->l1_params.besl; + +The failing case is when disabling LPM. So it is sufficient to avoid +access to udev->bos by moving the instruction into the "enable" clause. + +Cc: Stable <stable@vger.kernel.org> +Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/host/xhci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4137,7 +4137,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); +@@ -4149,6 +4148,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); |