Commit 1890296c authored by Bart Westgeest's avatar Bart Westgeest Committed by Greg Kroah-Hartman

staging: usbip: bugfix for deadlock

commit 438957f8 upstream.

Interrupts must be disabled prior to calling usb_hcd_unlink_urb_from_ep.
If interrupts are not disabled, it can potentially lead to a deadlock.
The deadlock is readily reproduceable on a slower (ARM based) device
such as the TI Pandaboard.
Signed-off-by: default avatarBart Westgeest <bart@elbrys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5aff28ab
...@@ -67,6 +67,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, ...@@ -67,6 +67,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
{ {
struct usbip_device *ud = &vdev->ud; struct usbip_device *ud = &vdev->ud;
struct urb *urb; struct urb *urb;
unsigned long flags;
spin_lock(&vdev->priv_lock); spin_lock(&vdev->priv_lock);
...@@ -107,9 +108,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, ...@@ -107,9 +108,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
usbip_dbg_vhci_rx("now giveback urb %p\n", urb); usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
spin_lock(&the_controller->lock); spin_lock_irqsave(&the_controller->lock, flags);
usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
spin_unlock(&the_controller->lock); spin_unlock_irqrestore(&the_controller->lock, flags);
usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
...@@ -150,6 +151,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, ...@@ -150,6 +151,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
{ {
struct vhci_unlink *unlink; struct vhci_unlink *unlink;
struct urb *urb; struct urb *urb;
unsigned long flags;
usbip_dump_header(pdu); usbip_dump_header(pdu);
...@@ -181,9 +183,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, ...@@ -181,9 +183,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
urb->status = pdu->u.ret_unlink.status; urb->status = pdu->u.ret_unlink.status;
usbip_uinfo("%d\n", urb->status); usbip_uinfo("%d\n", urb->status);
spin_lock(&the_controller->lock); spin_lock_irqsave(&the_controller->lock, flags);
usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
spin_unlock(&the_controller->lock); spin_unlock_irqrestore(&the_controller->lock, flags);
usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
urb->status); urb->status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment