Playing audio through a Bluetooth headset and then suspending the machine on Hardy, Intrepid and Jaunty causes a kernel panic. I've captured the location of the panic below in hci_usb_tx_complete.
The panic occurs when hci_usb_tx_complete() calls _urb_unlink() on an _urb which has been previously been removed from a list - basically _urb->list.prev and _urb->list.next are invalid pointers at this point and this causes a panic on the _urb_unlink().
It seems to me that the bug occurs because hci_usb_suspend() dequeues the _urb and then calls usb_kill_urb() - I believe it should put the _urb on the killed list first before killing the urb.
My testing confirms this fix works fine every time (and I've checked the _urb activity throughout the stack to verify that this is the root cause of the panic).
Playing audio through a Bluetooth headset and then suspending the machine on Hardy, Intrepid and Jaunty causes a kernel panic. I've captured the location of the panic below in hci_usb_ tx_complete.
00000750 <hci_usb_ tx_complete> : tx_complete+ 0x35> tx_complete+ 0xe4> tx_complete+ 0xf8> tx_complete+ 0x5f> tx_complete+ 0x9d> tx_complete+ 0x70>
750: 83 ec 14 sub $0x14,%esp
753: 89 5c 24 04 mov %ebx,0x4(%esp)
757: 89 c3 mov %eax,%ebx
759: 89 74 24 08 mov %esi,0x8(%esp)
75d: 89 6c 24 10 mov %ebp,0x10(%esp)
761: 8d 68 ec lea -0x14(%eax),%ebp
764: 89 7c 24 0c mov %edi,0xc(%esp)
768: 8b 78 64 mov 0x64(%eax),%edi
76b: 8b 07 mov (%edi),%eax
76d: 8d 77 68 lea 0x68(%edi),%esi
770: 89 04 24 mov %eax,(%esp)
773: 8b 45 0c mov 0xc(%ebp),%eax
776: f0 ff 0c 86 lock decl (%esi,%eax,4)
77a: c7 43 3c 00 00 00 00 movl $0x0,0x3c(%ebx)
781: 8b 45 10 mov 0x10(%ebp),%eax
784: e8 fc ff ff ff call 785 <hci_usb_
789: 8b 14 24 mov (%esp),%edx
78c: 8b 42 18 mov 0x18(%edx),%eax
78f: a8 04 test $0x4,%al
791: 0f 84 9d 00 00 00 je 834 <hci_usb_
797: 8b 4b 34 mov 0x34(%ebx),%ecx
79a: 85 c9 test %ecx,%ecx
79c: 0f 84 a6 00 00 00 je 848 <hci_usb_
7a2: 8b 04 24 mov (%esp),%eax
7a5: 83 80 74 02 00 00 01 addl $0x1,0x274(%eax)
7ac: 89 f0 mov %esi,%eax
7ae: e8 fc ff ff ff call 7af <hci_usb_
7b3: 8b 45 08 mov 0x8(%ebp),%eax
7b6: 85 c0 test %eax,%eax
7b8: 74 33 je 7ed <hci_usb_
7ba: 8d 58 08 lea 0x8(%eax),%ebx
7bd: 89 d8 mov %ebx,%eax
7bf: e8 fc ff ff ff call 7c0 <hci_usb_
7c4: 8b 55 04 mov 0x4(%ebp),%edx
7c7: 8b 4d 00 mov 0x0(%ebp),%ecx
7ca: 89 51 04 mov %edx,0x4(%ecx) <-- panic occurs here
The panic occurs when hci_usb_ tx_complete( ) calls _urb_unlink() on an _urb which has been previously been removed from a list - basically _urb->list.prev and _urb->list.next are invalid pointers at this point and this causes a panic on the _urb_unlink().
It seems to me that the bug occurs because hci_usb_suspend() dequeues the _urb and then calls usb_kill_urb() - I believe it should put the _urb on the killed list first before killing the urb.
My testing confirms this fix works fine every time (and I've checked the _urb activity throughout the stack to verify that this is the root cause of the panic).
Attached - the patch