Bug fixes for qualcomm BT chip wcn3990.
cover Bug fixes for qualcomm BT chip wcn3990.
When we set an KASAN flags, we are seeing an crash while removing module hci_uart. This is due to dereference of hdev. As in module deinit we are calling function hci_free_dev() to free hdev.
Changes in v1:
* removed dereference of hdev in qca_power_shutdown i.e. qca_close.
* moved serdev open & close call from qca_open & qca_close.
Balakrishna Godavarthi (2):
Bluetooth: hci_qca: Remove serdev_device_open/close function calls
Bluetooth: hci_qca: Remove hdev dereference in qca_close().
drivers/bluetooth/hci_qca.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 1/2 Bluetooth: hci_qca: Remove serdev_device_open/close function calls
Removed serdev_device_open/close functions from qca_open/close as they are called in hci_uart_register_device() and hci_uart_unregister_device() functions.
--- drivers/bluetooth/hci_qca.c | 2 -- 1 file changed, 2 deletions(-)
drivers/bluetooth/hci_qca.c +0 -2
@@ -499,7 +499,6 @@ static int qca_open(struct hci_uart *hu) hu->priv = qca;if (hu->serdev) { -serdev_device_open (hu->serdev); qcadev =serdev_device_get_drvdata (hu->serdev);if (qcadev->btsoc_type !=QCA_WCN3990 ) {
@@ -613,7 +612,6 @@ static int qca_close(struct hci_uart *hu)else gpiod_set_value_cansleep (qcadev->bt_en,0 ); -serdev_device_close (hu->serdev); }kfree_skb (qca->rx_skb);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 2/2 Bluetooth: hci_qca: Remove hdev dereference in qca_close().
In reply to Balakrishna GodavarthiWhen flag KASAN is set, we are seeing an following crash while removing hci_uart module.
[ 50.589909] Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b73 [ 50.597902] Mem abort info: [ 50.600846] Exception class = DABT (current EL), IL = 32 bits [ 50.606959] SET = 0, FnV = 0 [ 50.610142] EA = 0, S1PTW = 0 [ 50.613396] Data abort info: [ 50.616401] ISV = 0, ISS = 0x00000004 [ 50.620373] CM = 0, WnR = 0 [ 50.623466] [006b6b6b6b6b6b73] address between user and kernel address ranges [ 50.630818] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[ 50.671670] PC is at qca_power_shutdown+0x28/0x100 [hci_uart] [ 50.677593] LR is at qca_close+0x74/0xb0 [hci_uart] [ 50.775689] Process rmmod (pid: 2144, stack limit = 0xffffff801ba90000) [ 50.782493] Call trace:
[ 50.872150] [<ffffff8000c3c81c>] qca_power_shutdown+0x28/0x100 [hci_uart] [ 50.879138] [<ffffff8000c3c968>] qca_close+0x74/0xb0 [hci_uart] [ 50.885238] [<ffffff8000c3a71c>] hci_uart_unregister_device+0x44/0x50 [hci_uart] [ 50.892846] [<ffffff8000c3c9f4>] qca_serdev_remove+0x50/0x5c [hci_uart] [ 50.899654] [<ffffff800844f630>] serdev_drv_remove+0x28/0x38 [ 50.905489] [<ffffff800850fc44>] device_release_driver_internal+0x140/0x1e4 [ 50.912653] [<ffffff800850fd94>] driver_detach+0x78/0x84 [ 50.918121] [<ffffff800850edac>] bus_remove_driver+0x80/0xa8 [ 50.923942] [<ffffff80085107dc>] driver_unregister+0x4c/0x58 [ 50.929768] [<ffffff8000c3ca8c>] qca_deinit+0x24/0x598 [hci_uart] [ 50.936045] [<ffffff8000c3ca10>] hci_uart_exit+0x10/0x48 [hci_uart] [ 50.942495] [<ffffff8008136630>] SyS_delete_module+0x17c/0x224
This crash is due to dereference of hdev, after freeing it.
--- drivers/bluetooth/hci_qca.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/bluetooth/hci_qca.c +9 -6
@@ -167,7 +167,7 @@ struct qca_serdev { };static int qca_power_setup (struct hci_uart *hu,bool on); -static void qca_power_shutdown (struct hci_dev *hdev); +static void qca_power_shutdown (struct hci_uart *hu);static void __serial_clock_on (struct tty_struct *tty) {
@@ -608,7 +608,7 @@ static int qca_close(struct hci_uart *hu)if (hu->serdev) { qcadev =serdev_device_get_drvdata (hu->serdev);if (qcadev->btsoc_type ==QCA_WCN3990 ) -qca_power_shutdown (hu->hdev); +qca_power_shutdown (hu);else gpiod_set_value_cansleep (qcadev->bt_en,0 );
@@ -1230,12 +1230,15 @@ static const struct qca_vreg_data qca_soc_data = { .num_vregs = 4, }; -static void qca_power_shutdown (struct hci_dev *hdev) +static void qca_power_shutdown (struct hci_uart *hu) { -struct hci_uart *hu =hci_get_drvdata (hdev); +struct serdev_device *serdev = hu->serdev; +unsigned char cmd =QCA_WCN3990_POWEROFF_PULSE ;host_set_baudrate (hu,2400 ); -qca_send_power_pulse (hdev,QCA_WCN3990_POWEROFF_PULSE ); +hci_uart_set_flow_control (hu, true); +serdev_device_write_buf (serdev, &cmd,sizeof (cmd)); +hci_uart_set_flow_control (hu, false);qca_power_setup (hu, false); }
@@ -1411,7 +1414,7 @@ static void qca_serdev_remove(struct serdev_device *serdev)struct qca_serdev *qcadev =serdev_device_get_drvdata (serdev);if (qcadev->btsoc_type ==QCA_WCN3990 ) -qca_power_shutdown (qcadev->serdev_hu.hdev); +qca_power_shutdown (&qcadev->serdev_hu);else clk_disable_unprepare (qcadev->susclk);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Marcel Holtmann
maintainerHi Balakrishna,
Quoted 10 lines
When we set an KASAN flags, we are seeing an crash while removing module
hci_uart. This is due to dereference of hdev. As in module deinit we are calling functionhci_free_dev()to free hdev.Changes in v1:
* removed dereference of hdev in
qca_power_shutdowni.e.qca_close.
* moved serdev open & close call fromqca_open&qca_close.
Quoted 6 lines
Balakrishna Godavarthi (2):
Bluetooth:hci_qca: Remove serdev_device_open/close function calls
Bluetooth:hci_qca: Remove hdev dereference inqca_close().
drivers/bluetooth/hci_qca.c| 17 +++++++++--------1 file changed, 9 insertions(+), 8 deletions(-)
both patches haven been applied to bluetooth-next tree.
Regards
Marcel