1. 31 8月, 2016 1 次提交
  2. 09 8月, 2016 3 次提交
    • A
      USB: hub: change the locking in hub_activate · 07d316a2
      Alan Stern 提交于
      The locking in hub_activate() is not adequate to provide full mutual
      exclusion with hub_quiesce().  The subroutine locks the hub's
      usb_interface, but the callers of hub_quiesce() (such as
      hub_pre_reset() and hub_event()) hold the lock to the hub's
      usb_device.
      
      This patch changes hub_activate() to make it acquire the same lock as
      those other routines.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: <stable@vger.kernel.org> #4.4+
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      07d316a2
    • A
      USB: hub: fix up early-exit pathway in hub_activate · ca5cbc8b
      Alan Stern 提交于
      The early-exit pathway in hub_activate, added by commit e50293ef
      ("USB: fix invalid memory access in hub_activate()") needs
      improvement.  It duplicates code that is already present at the end of
      the subroutine, and it neglects to undo the effect of a
      usb_autopm_get_interface_no_resume() call.
      
      This patch fixes both problems by making the early-exit pathway jump
      directly to the end of the subroutine.  It simplifies the code at the
      end by merging two conditionals that actually test the same condition
      although they appear different: If type < HUB_INIT3 then type must be
      either HUB_INIT2 or HUB_INIT, and it can't be HUB_INIT because in that
      case the subroutine would have exited earlier.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: <stable@vger.kernel.org> #4.4+
      Reviewed-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ca5cbc8b
    • V
      usb: hub: Fix unbalanced reference count/memory leak/deadlocks · 6bb47e8a
      Viresh Kumar 提交于
      Memory leak and unbalanced reference count:
      
      If the hub gets disconnected while the core is still activating it, this
      can result in leaking memory of few USB structures.
      
      This will happen if we have done a kref_get() from hub_activate() and
      scheduled a delayed work item for HUB_INIT2/3. Now if hub_disconnect()
      gets called before the delayed work expires, then we will cancel the
      work from hub_quiesce(), but wouldn't do a kref_put(). And so the
      unbalance.
      
      kmemleak reports this as (with the commit e50293ef backported to
      3.10 kernel with other changes, though the same is true for mainline as
      well):
      
      unreferenced object 0xffffffc08af5b800 (size 1024):
        comm "khubd", pid 73, jiffies 4295051211 (age 6482.350s)
        hex dump (first 32 bytes):
          30 68 f3 8c c0 ff ff ff 00 a0 b2 2e c0 ff ff ff  0h..............
          01 00 00 00 00 00 00 00 00 94 7d 40 c0 ff ff ff  ..........}@....
        backtrace:
          [<ffffffc0003079ec>] create_object+0x148/0x2a0
          [<ffffffc000cc150c>] kmemleak_alloc+0x80/0xbc
          [<ffffffc000303a7c>] kmem_cache_alloc_trace+0x120/0x1ac
          [<ffffffc0006fa610>] hub_probe+0x120/0xb84
          [<ffffffc000702b20>] usb_probe_interface+0x1ec/0x298
          [<ffffffc0005d50cc>] driver_probe_device+0x160/0x374
          [<ffffffc0005d5308>] __device_attach+0x28/0x4c
          [<ffffffc0005d3164>] bus_for_each_drv+0x78/0xac
          [<ffffffc0005d4ee0>] device_attach+0x6c/0x9c
          [<ffffffc0005d42b8>] bus_probe_device+0x28/0xa0
          [<ffffffc0005d23a4>] device_add+0x324/0x604
          [<ffffffc000700fcc>] usb_set_configuration+0x660/0x6cc
          [<ffffffc00070a350>] generic_probe+0x44/0x84
          [<ffffffc000702914>] usb_probe_device+0x54/0x74
          [<ffffffc0005d50cc>] driver_probe_device+0x160/0x374
          [<ffffffc0005d5308>] __device_attach+0x28/0x4c
      
      Deadlocks:
      
      If the hub gets disconnected early enough (i.e. before INIT2/INIT3 are
      finished and the init_work is still queued), the core may call
      hub_quiesce() after acquiring interface device locks and it will wait
      for the work to be cancelled synchronously. But if the work handler is
      already running in parallel, it may try to acquire the same interface
      device lock and this may result in deadlock.
      
      Fix both the issues by removing the call to cancel_delayed_work_sync().
      
      CC: <stable@vger.kernel.org> #4.4+
      Fixes: e50293ef ("USB: fix invalid memory access in hub_activate()")
      Reported-by: NManu Gautam <mgautam@codeaurora.org>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      6bb47e8a
  3. 29 4月, 2016 1 次提交
    • C
      usb: core: hub: hub_port_init lock controller instead of bus · feb26ac3
      Chris Bainbridge 提交于
      The XHCI controller presents two USB buses to the system - one for USB2
      and one for USB3. The hub init code (hub_port_init) is reentrant but
      only locks one bus per thread, leading to a race condition failure when
      two threads attempt to simultaneously initialise a USB2 and USB3 device:
      
      [    8.034843] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
      [   13.183701] usb 3-3: device descriptor read/all, error -110
      
      On a test system this failure occurred on 6% of all boots.
      
      The call traces at the point of failure are:
      
      Call Trace:
       [<ffffffff81b9bab7>] schedule+0x37/0x90
       [<ffffffff817da7cd>] usb_kill_urb+0x8d/0xd0
       [<ffffffff8111e5e0>] ? wake_up_atomic_t+0x30/0x30
       [<ffffffff817dafbe>] usb_start_wait_urb+0xbe/0x150
       [<ffffffff817db10c>] usb_control_msg+0xbc/0xf0
       [<ffffffff817d07de>] hub_port_init+0x51e/0xb70
       [<ffffffff817d4697>] hub_event+0x817/0x1570
       [<ffffffff810f3e6f>] process_one_work+0x1ff/0x620
       [<ffffffff810f3dcf>] ? process_one_work+0x15f/0x620
       [<ffffffff810f4684>] worker_thread+0x64/0x4b0
       [<ffffffff810f4620>] ? rescuer_thread+0x390/0x390
       [<ffffffff810fa7f5>] kthread+0x105/0x120
       [<ffffffff810fa6f0>] ? kthread_create_on_node+0x200/0x200
       [<ffffffff81ba183f>] ret_from_fork+0x3f/0x70
       [<ffffffff810fa6f0>] ? kthread_create_on_node+0x200/0x200
      
      Call Trace:
       [<ffffffff817fd36d>] xhci_setup_device+0x53d/0xa40
       [<ffffffff817fd87e>] xhci_address_device+0xe/0x10
       [<ffffffff817d047f>] hub_port_init+0x1bf/0xb70
       [<ffffffff811247ed>] ? trace_hardirqs_on+0xd/0x10
       [<ffffffff817d4697>] hub_event+0x817/0x1570
       [<ffffffff810f3e6f>] process_one_work+0x1ff/0x620
       [<ffffffff810f3dcf>] ? process_one_work+0x15f/0x620
       [<ffffffff810f4684>] worker_thread+0x64/0x4b0
       [<ffffffff810f4620>] ? rescuer_thread+0x390/0x390
       [<ffffffff810fa7f5>] kthread+0x105/0x120
       [<ffffffff810fa6f0>] ? kthread_create_on_node+0x200/0x200
       [<ffffffff81ba183f>] ret_from_fork+0x3f/0x70
       [<ffffffff810fa6f0>] ? kthread_create_on_node+0x200/0x200
      
      Which results from the two call chains:
      
      hub_port_init
       usb_get_device_descriptor
        usb_get_descriptor
         usb_control_msg
          usb_internal_control_msg
           usb_start_wait_urb
            usb_submit_urb / wait_for_completion_timeout / usb_kill_urb
      
      hub_port_init
       hub_set_address
        xhci_address_device
         xhci_setup_device
      
      Mathias Nyman explains the current behaviour violates the XHCI spec:
      
       hub_port_reset() will end up moving the corresponding xhci device slot
       to default state.
      
       As hub_port_reset() is called several times in hub_port_init() it
       sounds reasonable that we could end up with two threads having their
       xhci device slots in default state at the same time, which according to
       xhci 4.5.3 specs still is a big no no:
      
       "Note: Software shall not transition more than one Device Slot to the
        Default State at a time"
      
       So both threads fail at their next task after this.
       One fails to read the descriptor, and the other fails addressing the
       device.
      
      Fix this in hub_port_init by locking the USB controller (instead of an
      individual bus) to prevent simultaneous initialisation of both buses.
      
      Fixes: 638139eb ("usb: hub: allow to process more usb hub events in parallel")
      Link: https://lkml.org/lkml/2016/2/8/312
      Link: https://lkml.org/lkml/2016/2/4/748Signed-off-by: NChris Bainbridge <chris.bainbridge@gmail.com>
      Cc: stable <stable@vger.kernel.org>
      Acked-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      feb26ac3
  4. 27 4月, 2016 1 次提交
  5. 04 3月, 2016 1 次提交
  6. 21 2月, 2016 1 次提交
    • G
      Revert "usb: hub: do not clear BOS field during reset device" · e5bdfd50
      Greg Kroah-Hartman 提交于
      This reverts commit d8f00cd6.
      
      Tony writes:
      
      This upstream commit is causing an oops:
      d8f00cd6 ("usb: hub: do not clear BOS field during reset device")
      
      This patch has already been included in several -stable kernels.  Here
      are the affected kernels:
      4.5.0-rc4 (current git)
      4.4.2
      4.3.6 (currently in review)
      4.1.18
      3.18.27
      3.14.61
      
      How to reproduce the problem:
      Boot kernel with slub debugging enabled (otherwise memory corruption
      will cause random oopses later instead of immediately)
      Plug in USB 3.0 disk to xhci USB 3.0 port
      dd if=/dev/sdc of=/dev/null bs=65536
      (where /dev/sdc is the USB 3.0 disk)
      Unplug USB cable while dd is still going
      Oops is immediate:
      Reported-by: NTony Battersby <tonyb@cybernetics.com>
      Cc: Du, Changbin <changbin.du@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e5bdfd50
  7. 15 2月, 2016 1 次提交
  8. 10 2月, 2016 1 次提交
  9. 07 2月, 2016 1 次提交
  10. 25 1月, 2016 4 次提交
  11. 19 12月, 2015 1 次提交
    • A
      USB: fix invalid memory access in hub_activate() · e50293ef
      Alan Stern 提交于
      Commit 8520f380 ("USB: change hub initialization sleeps to
      delayed_work") changed the hub_activate() routine to make part of it
      run in a workqueue.  However, the commit failed to take a reference to
      the usb_hub structure or to lock the hub interface while doing so.  As
      a result, if a hub is plugged in and quickly unplugged before the work
      routine can run, the routine will try to access memory that has been
      deallocated.  Or, if the hub is unplugged while the routine is
      running, the memory may be deallocated while it is in active use.
      
      This patch fixes the problem by taking a reference to the usb_hub at
      the start of hub_activate() and releasing it at the end (when the work
      is finished), and by locking the hub interface while the work routine
      is running.  It also adds a check at the start of the routine to see
      if the hub has already been disconnected, in which nothing should be
      done.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Reported-by: NAlexandru Cornea <alexandru.cornea@intel.com>
      Tested-by: NAlexandru Cornea <alexandru.cornea@intel.com>
      Fixes: 8520f380 ("USB: change hub initialization sleeps to delayed_work")
      CC: <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e50293ef
  12. 12 12月, 2015 1 次提交
  13. 05 12月, 2015 1 次提交
  14. 02 12月, 2015 3 次提交
    • L
      usb: core: lpm: add sysfs node for usb3 lpm permit · 513072d9
      Lu Baolu 提交于
      USB3 LPM is default on in Linux kernel if both xHCI host controller
      and the USB devices declare to be LPM-capable. Unfortunately, some
      devices are known to work well with LPM disabled, but to be broken
      if LPM is enabled, although it declares the LPM capability.  Users
      won't be able to use this kind of devices, until someone puts them
      in the kernel blacklist and gets the kernel upgraded.
      
      This patch adds a sysfs node to permit or forbit USB3 LPM U1 or U2
      entry for a port. The settings apply to both before and after device
      enumeration. Supported values are "0" - neither u1 nor u2 permitted,
      "u1" - only u1 is permitted, "u2" - only u2 is permitted, "u1_u2" -
      both u1 and u2 are permitted. With this interface, users can use an
      LPM-unfriendly USB device on a released Linux kernel.
      Signed-off-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NZhuang Jin Can <jin.can.zhuang@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      513072d9
    • L
      usb: core: lpm: fix usb3_hardware_lpm sysfs node · bf5ce5bf
      Lu Baolu 提交于
      Commit 655fe4ef ("usbcore: add sysfs support to xHCI usb3
      hardware LPM") introduced usb3_hardware_lpm sysfs node. This
      doesn't show the correct status of USB3 U1 and U2 LPM status.
      
      This patch fixes this by replacing usb3_hardware_lpm with two
      nodes, usb3_hardware_lpm_u1 (for U1) and usb3_hardware_lpm_u2
      (for U2), and recording the U1/U2 LPM status in right places.
      
      This patch should be back-ported to kernels as old as 4.3,
      that contains Commit 655fe4ef ("usbcore: add sysfs support
      to xHCI usb3 hardware LPM").
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bf5ce5bf
    • H
      usb: core : hub: Fix BOS 'NULL pointer' kernel panic · 464ad8c4
      Hans Yang 提交于
      When a USB 3.0 mass storage device is disconnected in transporting
      state, storage device driver may handle it as a transport error and
      reset the device by invoking usb_reset_and_verify_device()
      and following could happen:
      
      in usb_reset_and_verify_device():
         udev->bos = NULL;
      
      For U1/U2 enabled devices, driver will disable LPM, and in some
      conditions:
         from usb_unlocked_disable_lpm()
          --> usb_disable_lpm()
          --> usb_enable_lpm()
              udev->bos->ss_cap->bU1devExitLat;
      
      And it causes 'NULL pointer' and 'kernel panic':
      
      [  157.976257] Unable to handle kernel NULL pointer dereference
      at virtual address 00000010
      ...
      [  158.026400] PC is at usb_enable_link_state+0x34/0x2e0
      [  158.031442] LR is at usb_enable_lpm+0x98/0xac
      ...
      [  158.137368] [<ffffffc0006a1cac>] usb_enable_link_state+0x34/0x2e0
      [  158.143451] [<ffffffc0006a1fec>] usb_enable_lpm+0x94/0xac
      [  158.148840] [<ffffffc0006a20e8>] usb_disable_lpm+0xa8/0xb4
      ...
      [  158.214954] Kernel panic - not syncing: Fatal exception
      
      This commit moves 'udev->bos = NULL' behind usb_unlocked_disable_lpm()
      to prevent from NULL pointer access.
      
      Issue can be reproduced by following setup:
      1) A SS pen drive behind a SS hub connected to the host.
      2) Transporting data between the pen drive and the host.
      3) Abruptly disconnect hub and pen drive from host.
      4) With a chance it crashes.
      Signed-off-by: NHans Yang <hansy@nvidia.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      464ad8c4
  15. 04 10月, 2015 3 次提交
  16. 15 8月, 2015 2 次提交
  17. 09 8月, 2015 1 次提交
  18. 23 7月, 2015 2 次提交
  19. 31 5月, 2015 1 次提交
    • R
      usb: core: Fix USB 3.0 devices lost in NOTATTACHED state after a hub port reset · fb6d1f7d
      Robert Schlabbach 提交于
      Fix USB 3.0 devices lost in NOTATTACHED state after a hub port reset.
      
      Dissolve the function hub_port_finish_reset() completely and divide the
      actions to be taken into those which need to be done after each reset
      attempt and those which need to be done after the full procedure is
      complete, and place them in the appropriate places in hub_port_reset().
      Also, remove an unneeded forward declaration of hub_port_reset().
      
      Verbose Problem Description:
      
      USB 3.0 devices may be "lost for good" during a hub port reset.
      This makes Linux unable to boot from USB 3.0 devices in certain
      constellations of host controllers and devices, because the USB device is
      lost during initialization, preventing the rootfs from being mounted.
      
      The underlying problem is that in the affected constellations, during the
      processing inside hub_port_reset(), the hub link state goes from 0 to
      SS.inactive after the initial reset, and back to 0 again only after the
      following "warm" reset.
      
      However, hub_port_finish_reset() is called after each reset attempt and
      sets the state the connected USB device based on the "preliminary" status
      of the hot reset to USB_STATE_NOTATTACHED due to SS.inactive, yet when
      the following warm reset is complete and hub_port_finish_reset() is
      called again, its call to set the device to USB_STATE_DEFAULT is blocked
      by usb_set_device_state() which does not allow taking USB devices out of
      USB_STATE_NOTATTACHED state.
      
      Thanks to Alan Stern for guiding me to the proper solution and how to
      submit it.
      
      Link: http://lkml.kernel.org/r/trinity-25981484-72a9-4d46-bf17-9c1cf9301a31-1432073240136%20()%203capp-gmx-bs27Signed-off-by: NRobert Schlabbach <robert_s@gmx.net>
      Cc: stable <stable@vger.kernel.org>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      fb6d1f7d
  20. 10 5月, 2015 1 次提交
  21. 08 5月, 2015 3 次提交
  22. 08 4月, 2015 1 次提交
  23. 09 2月, 2015 1 次提交
  24. 04 2月, 2015 2 次提交
  25. 25 1月, 2015 2 次提交
    • D
      usb: core: hub: modify hub reset logic in hub driver · fbaecff0
      Deepak Das 提交于
      Currently if port power is turned off by user on hub port
      using USBDEVFS then port power is turned back ON
      by hub driver.
      This commit modifies hub reset logic in hub_port_connect() to prevent
      hub driver from turning back the port power ON if port is not owned
      by kernel.
      Signed-off-by: NDeepak Das <deepakdas.linux@gmail.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      fbaecff0
    • A
      USB: don't cancel queued resets when unbinding drivers · 524134d4
      Alan Stern 提交于
      The USB stack provides a mechanism for drivers to request an
      asynchronous device reset (usb_queue_reset_device()).  The mechanism
      uses a work item (reset_ws) embedded in the usb_interface structure
      used by the driver, and the reset is carried out by a work queue
      routine.
      
      The asynchronous reset can race with driver unbinding.  When this
      happens, we try to cancel the queued reset before unbinding the
      driver, on the theory that the driver won't care about any resets once
      it is unbound.
      
      However, thanks to the fact that lockdep now tracks work queue
      accesses, this can provoke a lockdep warning in situations where the
      device reset causes another interface's driver to be unbound; see
      
      	http://marc.info/?l=linux-usb&m=141893165203776&w=2
      
      for an example.  The reason is that the work routine for reset_ws in
      one interface calls cancel_queued_work() for the reset_ws in another
      interface.  Lockdep thinks this might lead to a work routine trying to
      cancel itself.  The simplest solution is not to cancel queued resets
      when unbinding drivers.
      
      This means we now need to acquire a reference to the usb_interface
      when queuing a reset_ws work item and to drop the reference when the
      work routine finishes.  We also need to make sure that the
      usb_interface structure doesn't outlive its parent usb_device; this
      means acquiring and dropping a reference when the interface is created
      and destroyed.
      
      In addition, cancelling a queued reset can fail (if the device is in
      the middle of an earlier reset), and this can cause usb_reset_device()
      to try to rebind an interface that has been deallocated (see
      http://marc.info/?l=linux-usb&m=142175717016628&w=2 for details).
      Acquiring the extra references prevents this failure.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Reported-by: NRussell King - ARM Linux <linux@arm.linux.org.uk>
      Reported-by: NOlivier Sobrie <olivier@sobrie.be>
      Tested-by: NOlivier Sobrie <olivier@sobrie.be>
      Cc: stable <stable@vger.kernel.org> # 3.19
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      524134d4