Re: [PATCH v4] Bluetooth: virtio: Fix virtbt_probe() init and cleanup

From: Igor Skalkin

Date: Fri Aug 07 2026 - 11:31:19 EST


I tested this against real hardware (not just QEMU-internal loopback):
a MediaTek USB Bluetooth controller on the host, exposed to a guest
kernel through QEMU's virtio-bt-pci device via HCI_CHANNEL_USER. This
exercises the actual virtio transport and the real HCI core, not a
mock. No other local changes to drivers/bluetooth/virtio_bt.c were
present; this v4 patch was applied alone on top of plain v7.2-rc4.

Test setup:
- Host: Linux with a MediaTek USB BT controller (hci0), bluetooth.service
stopped/masked and the adapter taken down for the duration of the test
so QEMU could bind HCI_CHANNEL_USER exclusively.
- Guest: v7.2-rc4 kernel with CONFIG_DEBUG_KMEMLEAK=y, booted via QEMU's
virtio-bt-pci device pointed at the host adapter.
- This patch (v4) applied alone, on top of plain v7.2-rc4, nothing else
changed in virtio_bt.c; built as a loadable module for repeated
bind/unbind testing.
- A module parameter (test-only, not part of this patch) let me force
a failure at each of the four points virtbt_probe() can now fail at,
to drive every branch of the new unwind ladder without needing to
fault-inject the real kernel functions.

Cases run, each followed by an explicit kmemleak scan:

1. Happy path: probe succeeds, hci0 appears under
/sys/class/bluetooth, remove() runs cleanly.
2. Five back-to-back insmod/rmmod cycles on the happy path, to catch
leaks or use-after-free that only show up cumulatively.
3. Forced failure at virtio_find_vqs() -> err_free_vbt path.
4. Forced failure at hci_alloc_dev() -> err_del_vqs path.
5. Forced failure at virtbt_open_vdev(), i.e. after
virtio_device_ready() (post-DRIVER_OK) -> err_close_vdev path.
6. Forced failure at hci_register_dev(), also post-DRIVER_OK and
post-open -> err_close_vdev path.

Results for all six: no Oops/BUG, no lockdep or RCU-stall warnings,
rmmod always succeeded, hci0 was present under
/sys/class/bluetooth only when probe actually succeeded (cases 1-2),
and kmemleak reported zero unreferenced objects after every case and
in a final aggregate scan at the end of the run.

This covers the ordering fix Sashiko flagged (hci_register_dev()
moved after virtio_device_ready()/virtbt_open_vdev(), so no buffers
are kicked before DRIVER_OK) and the vbt-leak/priv-cleanup fix on the
virtio_find_vqs() failure path, both under a real transport rather
than a stub.

Tested-by: Igor Skalkin <igor.skalkin@xxxxxxxxxxxxxxxx>

Happy to share the QEMU/kernel config and the fault-injection harness
if useful for other reviewers.