[ Upstream commit 3124d320c2 ]
syzbot is reporting NULL pointer dereference at hci_uart_tty_close() [1],
for rcu_sync_enter() is called without rcu_sync_init() due to
hci_uart_tty_open() ignoring percpu_init_rwsem() failure.
While we are at it, fix that hci_uart_register_device() ignores
percpu_init_rwsem() failure and hci_uart_unregister_device() does not
call percpu_free_rwsem().
Link: https://syzkaller.appspot.com/bug?extid=576dfca25381fb6fbc5f [1]
Reported-by: syzbot <syzbot+576dfca25381fb6fbc5f@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Fixes: 67d2f8781b ("Bluetooth: hci_ldisc: Allow sleeping while proto locks are held.")
Fixes: d73e172816 ("Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 9d7cbe2b9c ]
kvartet reported, that hci_uart_tx_wakeup() uses uninitialized rwsem.
The problem was in wrong place for percpu_init_rwsem() call.
hci_uart_proto::open() may register a timer whose callback may call
hci_uart_tx_wakeup(). There is a chance, that hci_uart_register_device()
thread won't be fast enough to call percpu_init_rwsem().
Fix it my moving percpu_init_rwsem() call before p->open().
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe
you didn't initialize this object before use?
turning off the locking correctness validator.
CPU: 2 PID: 18524 Comm: syz-executor.5 Not tainted 5.16.0-rc6 #9
...
Call Trace:
<IRQ>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
assign_lock_key kernel/locking/lockdep.c:951 [inline]
register_lock_class+0x148d/0x1950 kernel/locking/lockdep.c:1263
__lock_acquire+0x106/0x57e0 kernel/locking/lockdep.c:4906
lock_acquire kernel/locking/lockdep.c:5637 [inline]
lock_acquire+0x1ab/0x520 kernel/locking/lockdep.c:5602
percpu_down_read_trylock include/linux/percpu-rwsem.h:92 [inline]
hci_uart_tx_wakeup+0x12e/0x490 drivers/bluetooth/hci_ldisc.c:124
h5_timed_event+0x32f/0x6a0 drivers/bluetooth/hci_h5.c:188
call_timer_fn+0x1a5/0x6b0 kernel/time/timer.c:1421
Fixes: d73e172816 ("Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops")
Reported-by: Yiru Xu <xyru1999@gmail.com>
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
The hci_suspend_notifier which was introduced last year, is causing
problems for uart attached btrtl devices. These devices may loose their
firmware and their baudrate setting over a suspend/resume.
Since we don't even know the baudrate after a suspend/resume recovering
from this is tricky. The driver solves this by treating these devices
the same as USB BT HCIs which drop of the bus during suspend.
Specifically the driver:
1. Simply unconditionally turns the device fully off during
system-suspend to save maximum power.
2. Calls device_reprobe() from a workqueue to fully re-init the device
from scratch on system-resume (unregistering the old HCI and
registering a new HCI).
This means that these devices do not benefit from the suspend / resume
handling work done by the hci_suspend_notifier. At best this unnecessarily
adds some time to the suspend/resume time.
But in practice this is actually causing problems:
1. These btrtl devices seem to not like the HCI_OP_WRITE_SCAN_ENABLE(
SCAN_DISABLED) request being send to them when entering the
BT_SUSPEND_CONFIGURE_WAKE state. The same request send on
BT_SUSPEND_DISCONNECT works fine, but the second one send (unnecessarily?)
from the BT_SUSPEND_CONFIGURE_WAKE transition causes the device to hang:
[ 573.497754] PM: suspend entry (s2idle)
[ 573.554615] Filesystems sync: 0.056 seconds
[ 575.837753] Bluetooth: hci0: Timed out waiting for suspend events
[ 575.837801] Bluetooth: hci0: Suspend timeout bit: 4
[ 575.837925] Bluetooth: hci0: Suspend notifier action (3) failed: -110
2. The PM_POST_SUSPEND / BT_RUNNING transition races with the
driver-unbinding done by the device_reprobe() work.
If the hci_suspend_notifier wins the race it is talking to a dead
device leading to the following errors being logged:
[ 598.686060] Bluetooth: hci0: Timed out waiting for suspend events
[ 598.686124] Bluetooth: hci0: Suspend timeout bit: 5
[ 598.686237] Bluetooth: hci0: Suspend notifier action (4) failed: -110
In both cases things still work, but the suspend-notifier is causing
these ugly errors getting logged and ut increase both the suspend- and
the resume-time by 2 seconds.
This commit avoids these problems by disabling the hci_suspend_notifier.
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: Vasily Khoruzhick <anarsoul@gmail.com>
Cc: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
In hci_uart_write_work, there is a loop/goto checking the value of
HCI_UART_TX_WAKEUP. If HCI_UART_TX_WAKEUP is set again, it keeps trying
hci_uart_dequeue; otherwise, it clears HCI_UART_SENDING and returns.
In hci_uart_tx_wakeup, if HCI_UART_SENDING is already set, it sets
HCI_UART_TX_WAKEUP, skips schedule_work and assumes the running/pending
hci_uart_write_work worker will do hci_uart_dequeue properly.
However, if the HCI_UART_SENDING check in hci_uart_tx_wakeup is done after
the loop breaks, but before HCI_UART_SENDING is cleared in
hci_uart_write_work, the schedule_work is skipped incorrectly.
Fix this race by changing the order of HCI_UART_SENDING and
HCI_UART_TX_WAKEUP modification.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Fixes: 82f5169bf3 ("Bluetooth: hci_uart: add serdev driver support library")
Signed-off-by: Claire Chang <tientzu@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
When HCI_QUIRK_NON_PERSISTENT_SETUP is set by drivers,
it indicates that BT SoC will be completely powered OFF
during BT OFF. On next BT ON firmware must be downloaded
again. Holding UART port open during BT OFF is draining
the battery. Now during BT OFF, UART port is closed if
qurik HCI_QUIRK_NON_PERSISTENT_SETUP is set by clearing
HCI_UART_PROTO_READY proto flag. On next BT ON, UART
port is opened if HCI_UART_PROTO_READY proto flag is cleared.
Signed-off-by: Venkata Lakshmi Narayana Gubba <gubbaven@codeaurora.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
If hci_uart_tty_close() or hci_uart_unregister_device() is called while
hu->init_ready is scheduled, hci_register_dev() could be called after
the hci_uart is torn down. Avoid this by ensuring the work is complete
or canceled before checking the HCI_UART_REGISTERED flag.
Fixes: 9f2aee848f ("Bluetooth: Add delayed init sequence support for UART controllers")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
We should not call hci_unregister_dev if the device was not
successfully registered.
Fixes: c34dc3bfa7 ("Bluetooth: hci_serdev: Introduce hci_uart_unregister_device()")
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
serdev_device_ops is not modified and can be const. Also, remove the
unneeded declaration of it.
Output from the file command before and after:
Before:
text data bss dec hex filename
7192 2408 192 9792 2640 drivers/bluetooth/hci_serdev.o
After:
text data bss dec hex filename
7256 2344 192 9792 2640 drivers/bluetooth/hci_serdev.o
Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Based on 3 normalized pattern(s):
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license as published by
the free software foundation either version 2 of the license or at
your option any later version this program is distributed in the
hope that it will be useful but without any warranty without even
the implied warranty of merchantability or fitness for a particular
purpose see the gnu general public license for more details
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license as published by
the free software foundation either version 2 of the license or at
your option any later version [author] [kishon] [vijay] [abraham]
[i] [kishon]@[ti] [com] this program is distributed in the hope that
it will be useful but without any warranty without even the implied
warranty of merchantability or fitness for a particular purpose see
the gnu general public license for more details
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license as published by
the free software foundation either version 2 of the license or at
your option any later version [author] [graeme] [gregory]
[gg]@[slimlogic] [co] [uk] [author] [kishon] [vijay] [abraham] [i]
[kishon]@[ti] [com] [based] [on] [twl6030]_[usb] [c] [author] [hema]
[hk] [hemahk]@[ti] [com] this program is distributed in the hope
that it will be useful but without any warranty without even the
implied warranty of merchantability or fitness for a particular
purpose see the gnu general public license for more details
extracted by the scancode license scanner the SPDX license identifier
GPL-2.0-or-later
has been chosen to replace the boilerplate/reference in 1105 file(s).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Richard Fontana <rfontana@redhat.com>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070033.202006027@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
HCI_QUIRK_RESET_ON_CLOSE quirk is required for BT v1.0 based devices,
to send a reset command to the chip during hci device close. Serdev
architecture is used for the latest BT chips, which doesn't require to
send the reset command during close. If still chips required reset
command during close, it would be better enabling it in the vendor
probes or in proto setup.
Signed-off-by: Balakrishna Godavarthi <bgodavar@codeaurora.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Fixed error in space required before paranthesis
in drivers/bluetooth/hci_serdev.c
Signed-off-by: Jagdish Tirumala <t.jag587@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This will help to check the status of protocol while dequeuing an
skb packet. In some instaces we will end up kernel crash,
where proto close is called and we trying to dequeue an packet.
[ 500.142902] [<ffffff80080f9ce4>] do_raw_spin_lock+0x1c/0xe0
[ 500.148643] [<ffffff80088f1c7c>] _raw_spin_lock_irqsave+0x38/0x48
[ 500.154917] [<ffffff8008780ce8>] skb_dequeue+0x28/0x84
[ 500.160209] [<ffffff8000ad6f48>] 0xffffff8000ad6f48
[ 500.165230] [<ffffff8000ad6610>] 0xffffff8000ad6610
[ 500.170257] [<ffffff80080c7ce8>] process_one_work+0x238/0x3e4
[ 500.176174] [<ffffff80080c8330>] worker_thread+0x2bc/0x3d4
[ 500.181821] [<ffffff80080cdabc>] kthread+0x138/0x140
[ 500.186945] [<ffffff80080844e0>] ret_from_fork+0x10/0x18
Signed-off-by: Balakrishna Godavarthi <bgodavar@codeaurora.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Clearing HCI_UART_PROTO_READY will avoid usage of proto function pointers
before running the proto close function pointer. There is chance of kernel
crash, due to usage of non proto close function pointers after proto close.
Signed-off-by: Balakrishna Godavarthi <bgodavar@codeaurora.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Init hci_uart->init_ready so that hci_uart_init_ready() works properly.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Make hci_uart_register_device() and hci_uart_unregister_device() call
serdev_device_close()/open() themselves instead of relying on the various
hci_uart drivers to do this for them.
Besides reducing code complexity, this also ensures correct error checking
of serdev_device_open(), which was missing in a few drivers.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
For reasons explained in detail in commit 3611f4d2a5 ("hci_ldisc:
fix null pointer deref") the hci_uart_close() functions sets
hci_dev->flush to NULL.
But the device may be re-opened after a close, this commit restores the
hci_dev->flush callback on open().
Note this commit also moves the nearly empty defition of hci_uart_open()
a bit down in the file to avoid the need for forward declaring
hci_uart_flush().
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
checkpatch.pl shows a warning for these unnecessary curly braces.
so just removed those curly braces.
Signed-off-by: Vaibhav Murkute <vaibhavmurkute88@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
John Stultz reports a boot time crash with the HiKey board (which uses
hci_serdev) occurring in hci_uart_tx_wakeup(). That function is
contained in hci_ldisc.c, but also called from the newer hci_serdev.c.
It acquires the proto_lock in struct hci_uart and it turns out that we
forgot to init the lock in the serdev code path, thus causing the crash.
John bisected the crash to commit 67d2f8781b ("Bluetooth: hci_ldisc:
Allow sleeping while proto locks are held"), but the issue was present
before and the commit merely exposed it. (Perhaps by luck, the crash
did not occur with rwlocks.)
Init the proto_lock in the serdev code path to avoid the oops.
Stack trace for posterity:
Unable to handle kernel read from unreadable memory at 406f127000
[000000406f127000] user address but active_mm is swapper
Internal error: Oops: 96000005 [#1] PREEMPT SMP
Hardware name: HiKey Development Board (DT)
Call trace:
hci_uart_tx_wakeup+0x38/0x148
hci_uart_send_frame+0x28/0x38
hci_send_frame+0x64/0xc0
hci_cmd_work+0x98/0x110
process_one_work+0x134/0x330
worker_thread+0x130/0x468
kthread+0xf8/0x128
ret_from_fork+0x10/0x18
Link: https://lkml.org/lkml/2017/11/15/908
Reported-and-tested-by: John Stultz <john.stultz@linaro.org>
Cc: Ronald Tschalär <ronald@innovation.ch>
Cc: Rob Herring <rob.herring@linaro.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
In case of using BT_ERR and BT_INFO, convert to bt_dev_err and
bt_dev_info when possible. This allows for controller specific
reporting.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Several drivers have the same (and incorrect) code in their
_remove() handler.
Coalesce this into a shared function.
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The structure hci_serdev_client_ops does not need to be in global scope
and is not modified, so make it static.
Cleans up sparse warning:
"symbol 'hci_serdev_client_ops' was not declared. Should it be static?"
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
For bluetooth protocol driver only supporting serdev it makes
sense to follow common practice and built them into their own
module.
Such modules need access to hci_uart_register_device and
hci_uart_tx_wakeup for using the common protocol helpers.
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The device driver may need to communicate with the UART
device while the Bluetooth device is closed (e.g. due
to interrupts).
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This adds library functions for serdev based BT drivers. This is largely
copied from hci_ldisc.c and modified to use serdev calls. There's a little
bit of duplication, but I avoided intermixing this as the ldisc code should
eventually go away.
Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Cc: linux-bluetooth@vger.kernel.org
Acked-by: Pavel Machek <pavel@ucw.cz>
[Fix style issues reported by Pavel]
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>