| From b4b44e51b64dbfe7209c3694168138ad35acd880 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 30 Jan 2025 21:43:26 +0300 |
| Subject: Bluetooth: hci_uart: fix race during initialization |
| |
| From: Arseniy Krasnov <avkrasnov@salutedevices.com> |
| |
| [ Upstream commit 366ceff495f902182d42b6f41525c2474caf3f9a ] |
| |
| 'hci_register_dev()' calls power up function, which is executed by |
| kworker - 'hci_power_on()'. This function does access to bluetooth chip |
| using callbacks from 'hci_ldisc.c', for example 'hci_uart_send_frame()'. |
| Now 'hci_uart_send_frame()' checks 'HCI_UART_PROTO_READY' bit set, and |
| if not - it fails. Problem is that 'HCI_UART_PROTO_READY' is set after |
| 'hci_register_dev()', and there is tiny chance that 'hci_power_on()' will |
| be executed before setting this bit. In that case HCI init logic fails. |
| |
| Patch moves setting of 'HCI_UART_PROTO_READY' before calling function |
| 'hci_uart_register_dev()'. |
| |
| Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com> |
| Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/bluetooth/hci_ldisc.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c |
| index 395d66e32a2ea..2651e2e33f2a1 100644 |
| --- a/drivers/bluetooth/hci_ldisc.c |
| +++ b/drivers/bluetooth/hci_ldisc.c |
| @@ -707,12 +707,13 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) |
| |
| hu->proto = p; |
| |
| + set_bit(HCI_UART_PROTO_READY, &hu->flags); |
| + |
| err = hci_uart_register_dev(hu); |
| if (err) { |
| return err; |
| } |
| |
| - set_bit(HCI_UART_PROTO_READY, &hu->flags); |
| return 0; |
| } |
| |
| -- |
| 2.39.5 |
| |