• Yake Yang's avatar
    Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt · b062a0b9
    Yake Yang authored
    Fix the following kernel oops in btmtksdio_interrrupt
    
    [   14.339134]  btmtksdio_interrupt+0x28/0x54
    [   14.339139]  process_sdio_pending_irqs+0x68/0x1a0
    [   14.339144]  sdio_irq_work+0x40/0x70
    [   14.339154]  process_one_work+0x184/0x39c
    [   14.339160]  worker_thread+0x228/0x3e8
    [   14.339168]  kthread+0x148/0x3ac
    [   14.339176]  ret_from_fork+0x10/0x30
    
    That happened because hdev->power_on is already called before
    sdio_set_drvdata which btmtksdio_interrupt handler relies on is not
    properly set up.
    
    The details are shown as the below: hci_register_dev would run
    queue_work(hdev->req_workqueue, &hdev->power_on) as WQ_HIGHPRI
    workqueue_struct to complete the power-on sequeunce and thus hci_power_on
    may run before sdio_set_drvdata is done in btmtksdio_probe.
    
    The hci_dev_do_open in hci_power_on would initialize the device and enable
    the interrupt and thus it is possible that btmtksdio_interrupt is being
    called right before sdio_set_drvdata is filled out.
    
    When btmtksdio_interrupt is being called and sdio_set_drvdata is not filled
    , the kernel oops is going to happen because btmtksdio_interrupt access an
    uninitialized pointer.
    
    Fixes: 9aebfd4a ("Bluetooth: mediatek: add support for MediaTek MT7663S and MT7668S SDIO devices")
    Reviewed-by: default avatarMark Chen <markyawenchen@gmail.com>
    Co-developed-by: default avatarSean Wang <sean.wang@mediatek.com>
    Signed-off-by: default avatarSean Wang <sean.wang@mediatek.com>
    Signed-off-by: default avatarYake Yang <yake.yang@mediatek.com>
    Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
    b062a0b9
btmtksdio.c 33.1 KB