From: Greg Kroah-Hartman Date: Mon, 9 Oct 2017 12:04:32 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.75~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d740be00f8cc9532e3bed1aad68c7b8c093155d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch usb-core-harden-cdc_parse_cdc_header.patch usb-fix-out-of-bounds-in-usb_set_configuration.patch usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch usb-increase-quirk-delay-for-usb-devices.patch usb-uas-fix-bug-in-handling-of-alternate-settings.patch xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch --- diff --git a/queue-4.9/iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch b/queue-4.9/iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch new file mode 100644 index 00000000000..8f0a3c784e1 --- /dev/null +++ b/queue-4.9/iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch @@ -0,0 +1,42 @@ +From 7f70be6e4025db0551e6863e7eb9cca07122695c Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 23 Sep 2017 08:06:19 +0200 +Subject: iio: adc: twl4030: Disable the vusb3v1 rugulator in the error handling path of 'twl4030_madc_probe()' + +From: Christophe JAILLET + +commit 7f70be6e4025db0551e6863e7eb9cca07122695c upstream. + +Commit 7cc97d77ee8a has introduced a call to 'regulator_disable()' in the +.remove function. +So we should also have such a call in the .probe function in case of +error after a successful 'regulator_enable()' call. + +Add a new label for that and use it. + +Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings") +Signed-off-by: Christophe JAILLET +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/twl4030-madc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/iio/adc/twl4030-madc.c ++++ b/drivers/iio/adc/twl4030-madc.c +@@ -878,11 +878,13 @@ static int twl4030_madc_probe(struct pla + ret = iio_device_register(iio_dev); + if (ret) { + dev_err(&pdev->dev, "could not register iio device\n"); +- goto err_i2c; ++ goto err_usb3v1; + } + + return 0; + ++err_usb3v1: ++ regulator_disable(madc->usb3v1); + err_i2c: + twl4030_madc_set_current_generator(madc, 0, 0); + err_current_generator: diff --git a/queue-4.9/iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch b/queue-4.9/iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch new file mode 100644 index 00000000000..96422a20505 --- /dev/null +++ b/queue-4.9/iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch @@ -0,0 +1,37 @@ +From 245a396a9b1a67ac5c3228737c261b3e48708a2a Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 23 Sep 2017 08:06:18 +0200 +Subject: iio: adc: twl4030: Fix an error handling path in 'twl4030_madc_probe()' + +From: Christophe JAILLET + +commit 245a396a9b1a67ac5c3228737c261b3e48708a2a upstream. + +If 'devm_regulator_get()' fails, we should go through the existing error +handling path instead of returning directly, as done is all the other +error handling paths in this function. + +Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings") +Signed-off-by: Christophe JAILLET +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/twl4030-madc.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/iio/adc/twl4030-madc.c ++++ b/drivers/iio/adc/twl4030-madc.c +@@ -866,8 +866,10 @@ static int twl4030_madc_probe(struct pla + + /* Enable 3v1 bias regulator for MADC[3:6] */ + madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1"); +- if (IS_ERR(madc->usb3v1)) +- return -ENODEV; ++ if (IS_ERR(madc->usb3v1)) { ++ ret = -ENODEV; ++ goto err_i2c; ++ } + + ret = regulator_enable(madc->usb3v1); + if (ret) diff --git a/queue-4.9/revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch b/queue-4.9/revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch new file mode 100644 index 00000000000..f1acd2cbceb --- /dev/null +++ b/queue-4.9/revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch @@ -0,0 +1,81 @@ +From bcd6a7aa13800afc1418e6b29d944d882214939a Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Mon, 18 Sep 2017 17:39:19 +0300 +Subject: Revert "xhci: Limit USB2 port wake support for AMD Promontory hosts" + +From: Kai-Heng Feng + +commit bcd6a7aa13800afc1418e6b29d944d882214939a upstream. + +This reverts commit dec08194ffeccfa1cf085906b53d301930eae18f. + +Commit dec08194ffec ("xhci: Limit USB2 port wake support for AMD Promontory +hosts") makes all high speed USB ports on ASUS PRIME B350M-A cease to +function after enabling runtime PM. + +All boards with this chipsets will be affected, so revert the commit. + +The original patch was added to stable 4.9, 4.11 and 4.12 and needs +to reverted from there as well + +Signed-off-by: Kai-Heng Feng +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 3 --- + drivers/usb/host/xhci-pci.c | 12 ------------ + drivers/usb/host/xhci.h | 2 +- + 3 files changed, 1 insertion(+), 16 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1360,9 +1360,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd + t2 |= PORT_WKOC_E | PORT_WKCONN_E; + t2 &= ~PORT_WKDISC_E; + } +- if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && +- (hcd->speed < HCD_USB3)) +- t2 &= ~PORT_WAKE_BITS; + } else + t2 &= ~PORT_WAKE_BITS; + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -54,11 +54,6 @@ + #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 + #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 + +-#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 +-#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba +-#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb +-#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc +- + #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 + + static const char hcd_name[] = "xhci_hcd"; +@@ -142,13 +137,6 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_AMD) + xhci->quirks |= XHCI_TRUST_TX_LENGTH; + +- if ((pdev->vendor == PCI_VENDOR_ID_AMD) && +- ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || +- (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) || +- (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) || +- (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) +- xhci->quirks |= XHCI_U2_DISABLE_WAKE; +- + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + xhci->quirks |= XHCI_LPM_SUPPORT; + xhci->quirks |= XHCI_INTEL_HOST; +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1660,7 +1660,7 @@ struct xhci_hcd { + /* For controller with a broken Port Disable implementation */ + #define XHCI_BROKEN_PORT_PED (1 << 25) + #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) +-#define XHCI_U2_DISABLE_WAKE (1 << 27) ++/* Reserved. It was XHCI_U2_DISABLE_WAKE */ + #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) + + unsigned int num_active_eps; diff --git a/queue-4.9/series b/queue-4.9/series index 6200f58b5b2..05fe3354ad6 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -15,3 +15,14 @@ usb-dummy-hcd-fix-connection-failures-wrong-speed.patch usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch usb-dummy-hcd-fix-erroneous-synchronization-change.patch usb-devio-don-t-corrupt-user-memory.patch +usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch +usb-uas-fix-bug-in-handling-of-alternate-settings.patch +usb-core-harden-cdc_parse_cdc_header.patch +usb-increase-quirk-delay-for-usb-devices.patch +usb-fix-out-of-bounds-in-usb_set_configuration.patch +xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch +xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch +xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch +revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch +iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch +iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch diff --git a/queue-4.9/usb-core-harden-cdc_parse_cdc_header.patch b/queue-4.9/usb-core-harden-cdc_parse_cdc_header.patch new file mode 100644 index 00000000000..571dd1c1c26 --- /dev/null +++ b/queue-4.9/usb-core-harden-cdc_parse_cdc_header.patch @@ -0,0 +1,39 @@ +From 2e1c42391ff2556387b3cb6308b24f6f65619feb Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 21 Sep 2017 16:58:48 +0200 +Subject: USB: core: harden cdc_parse_cdc_header + +From: Greg Kroah-Hartman + +commit 2e1c42391ff2556387b3cb6308b24f6f65619feb upstream. + +Andrey Konovalov reported a possible out-of-bounds problem for the +cdc_parse_cdc_header function. He writes: + It looks like cdc_parse_cdc_header() doesn't validate buflen + before accessing buffer[1], buffer[2] and so on. The only check + present is while (buflen > 0). + +So fix this issue up by properly validating the buffer length matches +what the descriptor says it is. + +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/message.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2068,6 +2068,10 @@ int cdc_parse_cdc_header(struct usb_cdc_ + elength = 1; + goto next_desc; + } ++ if ((buflen < elength) || (elength < 3)) { ++ dev_err(&intf->dev, "invalid descriptor buffer length\n"); ++ break; ++ } + if (buffer[1] != USB_DT_CS_INTERFACE) { + dev_err(&intf->dev, "skipping garbage\n"); + goto next_desc; diff --git a/queue-4.9/usb-fix-out-of-bounds-in-usb_set_configuration.patch b/queue-4.9/usb-fix-out-of-bounds-in-usb_set_configuration.patch new file mode 100644 index 00000000000..6b660084930 --- /dev/null +++ b/queue-4.9/usb-fix-out-of-bounds-in-usb_set_configuration.patch @@ -0,0 +1,67 @@ +From bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Tue, 19 Sep 2017 15:07:17 +0200 +Subject: USB: fix out-of-bounds in usb_set_configuration + +From: Greg Kroah-Hartman + +commit bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb upstream. + +Andrey Konovalov reported a possible out-of-bounds problem for a USB interface +association descriptor. He writes: + It seems there's no proper size check of a USB_DT_INTERFACE_ASSOCIATION + descriptor. It's only checked that the size is >= 2 in + usb_parse_configuration(), so find_iad() might do out-of-bounds access + to intf_assoc->bInterfaceCount. + +And he's right, we don't check for crazy descriptors of this type very well, so +resolve this problem. Yet another issue found by syzkaller... + +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 14 +++++++++++--- + include/uapi/linux/usb/ch9.h | 1 + + 2 files changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -638,15 +638,23 @@ static int usb_parse_configuration(struc + + } else if (header->bDescriptorType == + USB_DT_INTERFACE_ASSOCIATION) { ++ struct usb_interface_assoc_descriptor *d; ++ ++ d = (struct usb_interface_assoc_descriptor *)header; ++ if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { ++ dev_warn(ddev, ++ "config %d has an invalid interface association descriptor of length %d, skipping\n", ++ cfgno, d->bLength); ++ continue; ++ } ++ + if (iad_num == USB_MAXIADS) { + dev_warn(ddev, "found more Interface " + "Association Descriptors " + "than allocated for in " + "configuration %d\n", cfgno); + } else { +- config->intf_assoc[iad_num] = +- (struct usb_interface_assoc_descriptor +- *)header; ++ config->intf_assoc[iad_num] = d; + iad_num++; + } + +--- a/include/uapi/linux/usb/ch9.h ++++ b/include/uapi/linux/usb/ch9.h +@@ -759,6 +759,7 @@ struct usb_interface_assoc_descriptor { + __u8 iFunction; + } __attribute__ ((packed)); + ++#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8 + + /*-------------------------------------------------------------------------*/ + diff --git a/queue-4.9/usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch b/queue-4.9/usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch new file mode 100644 index 00000000000..760c4f808d1 --- /dev/null +++ b/queue-4.9/usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch @@ -0,0 +1,261 @@ +From 1fbbb78f25d1291274f320462bf6908906f538db Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 21 Sep 2017 13:22:00 -0400 +Subject: USB: g_mass_storage: Fix deadlock when driver is unbound + +From: Alan Stern + +commit 1fbbb78f25d1291274f320462bf6908906f538db upstream. + +As a holdover from the old g_file_storage gadget, the g_mass_storage +legacy gadget driver attempts to unregister itself when its main +operating thread terminates (if it hasn't been unregistered already). +This is not strictly necessary; it was never more than an attempt to +have the gadget fail cleanly if something went wrong and the main +thread was killed. + +However, now that the UDC core manages gadget drivers independently of +UDC drivers, this scheme doesn't work any more. A simple test: + + modprobe dummy-hcd + modprobe g-mass-storage file=... + rmmod dummy-hcd + +ends up in a deadlock with the following backtrace: + + sysrq: SysRq : Show Blocked State + task PC stack pid father + file-storage D 0 1130 2 0x00000000 + Call Trace: + __schedule+0x53e/0x58c + schedule+0x6e/0x77 + schedule_preempt_disabled+0xd/0xf + __mutex_lock.isra.1+0x129/0x224 + ? _raw_spin_unlock_irqrestore+0x12/0x14 + __mutex_lock_slowpath+0x12/0x14 + mutex_lock+0x28/0x2b + usb_gadget_unregister_driver+0x29/0x9b [udc_core] + usb_composite_unregister+0x10/0x12 [libcomposite] + msg_cleanup+0x1d/0x20 [g_mass_storage] + msg_thread_exits+0xd/0xdd7 [g_mass_storage] + fsg_main_thread+0x1395/0x13d6 [usb_f_mass_storage] + ? __schedule+0x573/0x58c + kthread+0xd9/0xdb + ? do_set_interface+0x25c/0x25c [usb_f_mass_storage] + ? init_completion+0x1e/0x1e + ret_from_fork+0x19/0x24 + rmmod D 0 1155 683 0x00000000 + Call Trace: + __schedule+0x53e/0x58c + schedule+0x6e/0x77 + schedule_timeout+0x26/0xbc + ? __schedule+0x573/0x58c + do_wait_for_common+0xb3/0x128 + ? usleep_range+0x81/0x81 + ? wake_up_q+0x3f/0x3f + wait_for_common+0x2e/0x45 + wait_for_completion+0x17/0x19 + fsg_common_put+0x34/0x81 [usb_f_mass_storage] + fsg_free_inst+0x13/0x1e [usb_f_mass_storage] + usb_put_function_instance+0x1a/0x25 [libcomposite] + msg_unbind+0x2a/0x42 [g_mass_storage] + __composite_unbind+0x4a/0x6f [libcomposite] + composite_unbind+0x12/0x14 [libcomposite] + usb_gadget_remove_driver+0x4f/0x77 [udc_core] + usb_del_gadget_udc+0x52/0xcc [udc_core] + dummy_udc_remove+0x27/0x2c [dummy_hcd] + platform_drv_remove+0x1d/0x31 + device_release_driver_internal+0xe9/0x16d + device_release_driver+0x11/0x13 + bus_remove_device+0xd2/0xe2 + device_del+0x19f/0x221 + ? selinux_capable+0x22/0x27 + platform_device_del+0x21/0x63 + platform_device_unregister+0x10/0x1a + cleanup+0x20/0x817 [dummy_hcd] + SyS_delete_module+0x10c/0x197 + ? ____fput+0xd/0xf + ? task_work_run+0x55/0x62 + ? prepare_exit_to_usermode+0x65/0x75 + do_fast_syscall_32+0x86/0xc3 + entry_SYSENTER_32+0x4e/0x7c + +What happens is that removing the dummy-hcd driver causes the UDC core +to unbind the gadget driver, which it does while holding the udc_lock +mutex. The unbind routine in g_mass_storage tells the main thread to +exit and waits for it to terminate. + +But as mentioned above, when the main thread exits it tries to +unregister the mass-storage function driver. Via the composite +framework this ends up calling usb_gadget_unregister_driver(), which +tries to acquire the udc_lock mutex. The result is deadlock. + +The simplest way to fix the problem is not to be so clever: The main +thread doesn't have to unregister the function driver. The side +effects won't be so terrible; if the gadget is still attached to a USB +host when the main thread is killed, it will appear to the host as +though the gadget's firmware has crashed -- a reasonably accurate +interpretation, and an all-too-common occurrence for USB mass-storage +devices. + +In fact, the code to unregister the driver when the main thread exits +is specific to g-mass-storage; it is not used when f-mass-storage is +included as a function in a larger composite device. Therefore the +entire mechanism responsible for this (the fsg_operations structure +with its ->thread_exits method, the fsg_common_set_ops() routine, and +the msg_thread_exits() callback routine) can all be eliminated. Even +the msg_registered bitflag can be removed, because now the driver is +unregistered in only one place rather than in two places. + +Signed-off-by: Alan Stern +Acked-by: Felipe Balbi +Acked-by: Michal Nazarewicz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_mass_storage.c | 29 +++++++-------------------- + drivers/usb/gadget/function/f_mass_storage.h | 14 ------------- + drivers/usb/gadget/legacy/mass_storage.c | 19 +---------------- + 3 files changed, 10 insertions(+), 52 deletions(-) + +--- a/drivers/usb/gadget/function/f_mass_storage.c ++++ b/drivers/usb/gadget/function/f_mass_storage.c +@@ -306,8 +306,6 @@ struct fsg_common { + struct completion thread_notifier; + struct task_struct *thread_task; + +- /* Callback functions. */ +- const struct fsg_operations *ops; + /* Gadget's private data. */ + void *private_data; + +@@ -2505,6 +2503,7 @@ static void handle_exception(struct fsg_ + static int fsg_main_thread(void *common_) + { + struct fsg_common *common = common_; ++ int i; + + /* + * Allow the thread to be killed by a signal, but set the signal mask +@@ -2566,21 +2565,16 @@ static int fsg_main_thread(void *common_ + common->thread_task = NULL; + spin_unlock_irq(&common->lock); + +- if (!common->ops || !common->ops->thread_exits +- || common->ops->thread_exits(common) < 0) { +- int i; +- +- down_write(&common->filesem); +- for (i = 0; i < ARRAY_SIZE(common->luns); --i) { +- struct fsg_lun *curlun = common->luns[i]; +- if (!curlun || !fsg_lun_is_open(curlun)) +- continue; ++ /* Eject media from all LUNs */ + ++ down_write(&common->filesem); ++ for (i = 0; i < ARRAY_SIZE(common->luns); i++) { ++ struct fsg_lun *curlun = common->luns[i]; ++ ++ if (curlun && fsg_lun_is_open(curlun)) + fsg_lun_close(curlun); +- curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; +- } +- up_write(&common->filesem); + } ++ up_write(&common->filesem); + + /* Let fsg_unbind() know the thread has exited */ + complete_and_exit(&common->thread_notifier, 0); +@@ -2770,13 +2764,6 @@ void fsg_common_remove_luns(struct fsg_c + } + EXPORT_SYMBOL_GPL(fsg_common_remove_luns); + +-void fsg_common_set_ops(struct fsg_common *common, +- const struct fsg_operations *ops) +-{ +- common->ops = ops; +-} +-EXPORT_SYMBOL_GPL(fsg_common_set_ops); +- + void fsg_common_free_buffers(struct fsg_common *common) + { + _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); +--- a/drivers/usb/gadget/function/f_mass_storage.h ++++ b/drivers/usb/gadget/function/f_mass_storage.h +@@ -60,17 +60,6 @@ struct fsg_module_parameters { + struct fsg_common; + + /* FSF callback functions */ +-struct fsg_operations { +- /* +- * Callback function to call when thread exits. If no +- * callback is set or it returns value lower then zero MSF +- * will force eject all LUNs it operates on (including those +- * marked as non-removable or with prevent_medium_removal flag +- * set). +- */ +- int (*thread_exits)(struct fsg_common *common); +-}; +- + struct fsg_lun_opts { + struct config_group group; + struct fsg_lun *lun; +@@ -142,9 +131,6 @@ void fsg_common_remove_lun(struct fsg_lu + + void fsg_common_remove_luns(struct fsg_common *common); + +-void fsg_common_set_ops(struct fsg_common *common, +- const struct fsg_operations *ops); +- + int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, + unsigned int id, const char *name, + const char **name_pfx); +--- a/drivers/usb/gadget/legacy/mass_storage.c ++++ b/drivers/usb/gadget/legacy/mass_storage.c +@@ -107,15 +107,6 @@ static unsigned int fsg_num_buffers = CO + + FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); + +-static unsigned long msg_registered; +-static void msg_cleanup(void); +- +-static int msg_thread_exits(struct fsg_common *common) +-{ +- msg_cleanup(); +- return 0; +-} +- + static int msg_do_config(struct usb_configuration *c) + { + struct fsg_opts *opts; +@@ -154,9 +145,6 @@ static struct usb_configuration msg_conf + + static int msg_bind(struct usb_composite_dev *cdev) + { +- static const struct fsg_operations ops = { +- .thread_exits = msg_thread_exits, +- }; + struct fsg_opts *opts; + struct fsg_config config; + int status; +@@ -173,8 +161,6 @@ static int msg_bind(struct usb_composite + if (status) + goto fail; + +- fsg_common_set_ops(opts->common, &ops); +- + status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); + if (status) + goto fail_set_cdev; +@@ -261,9 +247,8 @@ static int __init msg_init(void) + } + module_init(msg_init); + +-static void msg_cleanup(void) ++static void __exit msg_cleanup(void) + { +- if (test_and_clear_bit(0, &msg_registered)) +- usb_composite_unregister(&msg_driver); ++ usb_composite_unregister(&msg_driver); + } + module_exit(msg_cleanup); diff --git a/queue-4.9/usb-increase-quirk-delay-for-usb-devices.patch b/queue-4.9/usb-increase-quirk-delay-for-usb-devices.patch new file mode 100644 index 00000000000..c0bcfe9f002 --- /dev/null +++ b/queue-4.9/usb-increase-quirk-delay-for-usb-devices.patch @@ -0,0 +1,52 @@ +From b2a542bbb3081dbd64acc8929c140d196664c406 Mon Sep 17 00:00:00 2001 +From: Dmitry Fleytman +Date: Tue, 5 Sep 2017 11:40:56 +0300 +Subject: usb: Increase quirk delay for USB devices + +From: Dmitry Fleytman + +commit b2a542bbb3081dbd64acc8929c140d196664c406 upstream. + +Commit e0429362ab15 +("usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e") +introduced quirk to workaround an issue with some Logitech webcams. + +The workaround is introducing delay for some USB operations. + +According to our testing, delay introduced by original commit +is not long enough and in rare cases we still see issues described +by the aforementioned commit. + +This patch increases delays introduced by original commit. +Having this patch applied we do not see those problems anymore. + +Signed-off-by: Dmitry Fleytman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 2 +- + drivers/usb/core/hub.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -847,7 +847,7 @@ int usb_get_configuration(struct usb_dev + } + + if (dev->quirks & USB_QUIRK_DELAY_INIT) +- msleep(100); ++ msleep(200); + + result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, + bigbuffer, length); +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4828,7 +4828,7 @@ static void hub_port_connect(struct usb_ + goto loop; + + if (udev->quirks & USB_QUIRK_DELAY_INIT) +- msleep(1000); ++ msleep(2000); + + /* consecutive bus-powered hubs aren't reliable; they can + * violate the voltage drop budget. if the new child has diff --git a/queue-4.9/usb-uas-fix-bug-in-handling-of-alternate-settings.patch b/queue-4.9/usb-uas-fix-bug-in-handling-of-alternate-settings.patch new file mode 100644 index 00000000000..01e2b3ffd0d --- /dev/null +++ b/queue-4.9/usb-uas-fix-bug-in-handling-of-alternate-settings.patch @@ -0,0 +1,103 @@ +From 786de92b3cb26012d3d0f00ee37adf14527f35c4 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 22 Sep 2017 11:56:49 -0400 +Subject: USB: uas: fix bug in handling of alternate settings + +From: Alan Stern + +commit 786de92b3cb26012d3d0f00ee37adf14527f35c4 upstream. + +The uas driver has a subtle bug in the way it handles alternate +settings. The uas_find_uas_alt_setting() routine returns an +altsetting value (the bAlternateSetting number in the descriptor), but +uas_use_uas_driver() then treats that value as an index to the +intf->altsetting array, which it isn't. + +Normally this doesn't cause any problems because the various +alternate settings have bAlternateSetting values 0, 1, 2, ..., so the +value is equal to the index in the array. But this is not guaranteed, +and Andrey Konovalov used the syzkaller fuzzer with KASAN to get a +slab-out-of-bounds error by violating this assumption. + +This patch fixes the bug by making uas_find_uas_alt_setting() return a +pointer to the altsetting entry rather than either the value or the +index. Pointers are less subject to misinterpretation. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas-detect.h | 15 ++++++++------- + drivers/usb/storage/uas.c | 10 +++++----- + 2 files changed, 13 insertions(+), 12 deletions(-) + +--- a/drivers/usb/storage/uas-detect.h ++++ b/drivers/usb/storage/uas-detect.h +@@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_h + intf->desc.bInterfaceProtocol == USB_PR_UAS); + } + +-static int uas_find_uas_alt_setting(struct usb_interface *intf) ++static struct usb_host_interface *uas_find_uas_alt_setting( ++ struct usb_interface *intf) + { + int i; + +@@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(stru + struct usb_host_interface *alt = &intf->altsetting[i]; + + if (uas_is_interface(alt)) +- return alt->desc.bAlternateSetting; ++ return alt; + } + +- return -ENODEV; ++ return NULL; + } + + static int uas_find_endpoints(struct usb_host_interface *alt, +@@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + unsigned long flags = id->driver_info; +- int r, alt; +- ++ struct usb_host_interface *alt; ++ int r; + + alt = uas_find_uas_alt_setting(intf); +- if (alt < 0) ++ if (!alt) + return 0; + +- r = uas_find_endpoints(&intf->altsetting[alt], eps); ++ r = uas_find_endpoints(alt, eps); + if (r < 0) + return 0; + +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -873,14 +873,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids); + static int uas_switch_interface(struct usb_device *udev, + struct usb_interface *intf) + { +- int alt; ++ struct usb_host_interface *alt; + + alt = uas_find_uas_alt_setting(intf); +- if (alt < 0) +- return alt; ++ if (!alt) ++ return -ENODEV; + +- return usb_set_interface(udev, +- intf->altsetting[0].desc.bInterfaceNumber, alt); ++ return usb_set_interface(udev, alt->desc.bInterfaceNumber, ++ alt->desc.bAlternateSetting); + } + + static int uas_configure_endpoints(struct uas_dev_info *devinfo) diff --git a/queue-4.9/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch b/queue-4.9/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch new file mode 100644 index 00000000000..e568b61fbef --- /dev/null +++ b/queue-4.9/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch @@ -0,0 +1,34 @@ +From 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 18 Sep 2017 17:39:13 +0300 +Subject: xhci: fix finding correct bus_state structure for USB 3.1 hosts + +From: Mathias Nyman + +commit 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c upstream. + +xhci driver keeps a bus_state structure for each hcd (usb2 and usb3) + +The structure is picked based on hcd speed, but driver only compared +for HCD_USB3 speed, returning the wrong bus_state for HCD_USB31 hosts. + +This caused null pointer dereference errors in bus_resume function. + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1509,7 +1509,7 @@ struct xhci_bus_state { + + static inline unsigned int hcd_index(struct usb_hcd *hcd) + { +- if (hcd->speed == HCD_USB3) ++ if (hcd->speed >= HCD_USB3) + return 0; + else + return 1; diff --git a/queue-4.9/xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch b/queue-4.9/xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch new file mode 100644 index 00000000000..c7aef2a6766 --- /dev/null +++ b/queue-4.9/xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch @@ -0,0 +1,42 @@ +From 4ec1cd3eeeee7ccc35681270da028dbc29ca7bbd Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 18 Sep 2017 17:39:17 +0300 +Subject: xhci: Fix sleeping with spin_lock_irq() held in ASmedia 1042A workaround + +From: Mathias Nyman + +commit 4ec1cd3eeeee7ccc35681270da028dbc29ca7bbd upstream. + +The flow control workaround for ASM1042A xHC hosts sleeps between +register polling. The workaround gets called in several places, among +them with spin_lock_irq() held when xHC host is resumed or hoplug removed. + +This was noticed as kernel panics at resume on a Dell XPS15 9550 with +TB16 thunderbolt dock. + +Avoid sleeping with spin_lock_irq() held, use udelay() instead + +The original workaround was added to 4.9 and 4.12 stable releases, +this patch needs to be applied to those as well. + +Fixes: 9da5a1092b13 ("xhci: Bad Ethernet performance plugged in ASM1042A host") +Reported-by: Jose Marino +Tested-by: Jose Marino +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/pci-quirks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -447,7 +447,7 @@ static int usb_asmedia_wait_write(struct + if ((value & ASMT_CONTROL_WRITE_BIT) == 0) + return 0; + +- usleep_range(40, 60); ++ udelay(50); + } + + dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); diff --git a/queue-4.9/xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch b/queue-4.9/xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch new file mode 100644 index 00000000000..e1536656437 --- /dev/null +++ b/queue-4.9/xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch @@ -0,0 +1,57 @@ +From 7bea22b124d77845c85a62eaa29a85ba6cc2f899 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 18 Sep 2017 17:39:18 +0300 +Subject: xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor + +From: Mathias Nyman + +commit 7bea22b124d77845c85a62eaa29a85ba6cc2f899 upstream. + +A SuperSpeedPlus roothub needs to have the Link Protocol (LP) bit set in +the bmSublinkSpeedAttr[] entry of a SuperSpeedPlus descriptor. + +If the xhci controller has an optional Protocol Speed ID (PSI) table then +that will be used as a base to create the roothub SuperSpeedPlus +descriptor. +The PSI table does not however necessary contain the LP bit so we need +to set it manually. + +Check the psi speed and set LP bit if speed is 10Gbps or higher. +We're not setting it for 5 to 10Gbps as USB 3.1 specification always +mention SuperSpeedPlus for 10Gbps or higher, and some SSIC USB 3.0 speeds +can be over 5Gbps, such as SSIC-G3B-L1 at 5830 Mbps + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -112,7 +112,7 @@ static int xhci_create_usb3_bos_desc(str + + /* If PSI table exists, add the custom speed attributes from it */ + if (usb3_1 && xhci->usb3_rhub.psi_count) { +- u32 ssp_cap_base, bm_attrib, psi; ++ u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp; + int offset; + + ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE; +@@ -139,6 +139,15 @@ static int xhci_create_usb3_bos_desc(str + for (i = 0; i < xhci->usb3_rhub.psi_count; i++) { + psi = xhci->usb3_rhub.psi[i]; + psi &= ~USB_SSP_SUBLINK_SPEED_RSVD; ++ psi_exp = XHCI_EXT_PORT_PSIE(psi); ++ psi_mant = XHCI_EXT_PORT_PSIM(psi); ++ ++ /* Shift to Gbps and set SSP Link BIT(14) if 10Gpbs */ ++ for (; psi_exp < 3; psi_exp++) ++ psi_mant /= 1000; ++ if (psi_mant >= 10) ++ psi |= BIT(14); ++ + if ((psi & PLT_MASK) == PLT_SYM) { + /* Symmetric, create SSA RX and TX from one PSI entry */ + put_unaligned_le32(psi, &buf[offset]);