1 From b26cba86bfa2f29841279d7d3950cf1d4db0e6af Mon Sep 17 00:00:00 2001
2 From: "Michael S. Tsirkin" <mst@redhat.com>
3 Date: Thu, 25 Nov 2021 12:44:48 -0500
4 Subject: [PATCH] Bluetooth: virtio_bt: fix device removal
6 Device removal is clearly out of virtio spec: it attempts to remove
7 unused buffers from a VQ before invoking device reset. To fix, make
8 open/close NOPs and do all cleanup/setup in probe/remove.
10 The cost here is a single skb wasted on an unused bt device - which
13 NB: with this fix in place driver still suffers from a race condition if
14 an interrupt triggers while device is being reset. Work on a fix for
15 that issue is in progress.
17 Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
18 Upstream-Status: Submitted [https://lore.kernel.org/all/20211125174200.133230-1-mst@redhat.com/]
20 drivers/bluetooth/virtio_bt.c | 18 ++++++++++++++++--
21 1 file changed, 16 insertions(+), 2 deletions(-)
23 diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
24 index 67c21263f9e0..1dd734aef87b 100644
25 --- a/drivers/bluetooth/virtio_bt.c
26 +++ b/drivers/bluetooth/virtio_bt.c
27 @@ -50,8 +50,11 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt)
29 static int virtbt_open(struct hci_dev *hdev)
31 - struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
35 +static int virtbt_open_vdev(struct virtio_bluetooth *vbt)
37 if (virtbt_add_inbuf(vbt) < 0)
40 @@ -61,7 +64,11 @@ static int virtbt_open(struct hci_dev *hdev)
42 static int virtbt_close(struct hci_dev *hdev)
44 - struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
48 +static int virtbt_close_vdev(struct virtio_bluetooth *vbt)
52 cancel_work_sync(&vbt->rx);
53 @@ -354,8 +361,14 @@ static int virtbt_probe(struct virtio_device *vdev)
57 + virtio_device_ready(vdev);
58 + if (virtbt_open_vdev(vbt))
66 vdev->config->del_vqs(vdev);
68 @@ -368,6 +381,7 @@ static void virtbt_remove(struct virtio_device *vdev)
70 hci_unregister_dev(hdev);
71 virtio_reset_device(vdev);
72 + virtbt_close_vdev(vbt);