Message ID | 20211115220021.v3.1.I2a8b2f2e52d05ae9ead3f3dcc1dd90ef47a7acd7@changeid (mailing list archive) |
---|---|
State | Awaiting Upstream |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [v3] Bluetooth: Don't initialize msft/aosp when using user channel | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Guessing tree name failed - patch did not apply |
Hi Jesse, > A race condition is triggered when usermode control is given to > userspace before the kernel's MSFT query responds, resulting in an > unexpected response to userspace's reset command. > > Issue can be observed in btmon: > < HCI Command: Vendor (0x3f|0x001e) plen 2 #3 [hci0] > 05 01 .. > @ USER Open: bt_stack_manage (privileged) version 2.22 {0x0002} [hci0] > < HCI Command: Reset (0x03|0x0003) plen 0 #4 [hci0] >> HCI Event: Command Complete (0x0e) plen 5 #5 [hci0] > Vendor (0x3f|0x001e) ncmd 1 > Status: Command Disallowed (0x0c) > 05 . >> HCI Event: Command Complete (0x0e) plen 4 #6 [hci0] > Reset (0x03|0x0003) ncmd 2 > Status: Success (0x00) > Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> > Reviewed-by: Sonny Sasaka <sonnysasaka@chromium.org> > Signed-off-by: Jesse Melhuish <melhuishj@chromium.org> > --- > > Changes in v3: > - Added guard around *_close calls as well. > > Changes in v2: > - Moved guard to the new home for this code. > > net/bluetooth/hci_sync.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) patch has been applied to bluetooth-next tree. Regards Marcel
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index b794605dc882..06d08dc6ad22 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -3887,8 +3887,10 @@ int hci_dev_open_sync(struct hci_dev *hdev) hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) ret = hdev->set_diag(hdev, true); - msft_do_open(hdev); - aosp_do_open(hdev); + if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { + msft_do_open(hdev); + aosp_do_open(hdev); + } clear_bit(HCI_INIT, &hdev->flags); @@ -4031,8 +4033,10 @@ int hci_dev_close_sync(struct hci_dev *hdev) hci_sock_dev_event(hdev, HCI_DEV_DOWN); - aosp_do_close(hdev); - msft_do_close(hdev); + if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { + aosp_do_close(hdev); + msft_do_close(hdev); + } if (hdev->flush) hdev->flush(hdev);