From: Borislav Petkov In commit acd2a847e7fee7df11817f67dba75a2802793e5d usb_serial_generic_write() disables interrupts when taking &port->lock which is also taken in usb_serial_generic_read_bulk_callback() resulting in an inconsistent lock state due to the latter not disabling interrupts on the local cpu. Fix that by disabling interrupts in the latter call site also. Signed-off-by: Borislav Petkov Acked-by: Jiri Kosina Cc: Greg KH Signed-off-by: Andrew Morton --- drivers/usb/serial/generic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff -puN drivers/usb/serial/generic.c~usbserial-fix-inconsistent-lock-state drivers/usb/serial/generic.c --- a/drivers/usb/serial/generic.c~usbserial-fix-inconsistent-lock-state +++ a/drivers/usb/serial/generic.c @@ -327,6 +327,7 @@ void usb_serial_generic_read_bulk_callba struct usb_serial_port *port = (struct usb_serial_port *)urb->context; unsigned char *data = urb->transfer_buffer; int status = urb->status; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); @@ -339,11 +340,11 @@ void usb_serial_generic_read_bulk_callba usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); /* Throttle the device if requested by tty */ - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); if (!(port->throttled = port->throttle_req)) /* Handle data and continue reading from device */ flush_and_resubmit_read_urb(port); - spin_unlock(&port->lock); + spin_unlock_irqrestore(&port->lock, flags); } EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); _