]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.29/vsock-virtio-fix-kernel-panic-after-device-hot-unplu.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.19.29 / vsock-virtio-fix-kernel-panic-after-device-hot-unplu.patch
1 From abb026a3646e2be78d055389eeff6f8b1c20faec Mon Sep 17 00:00:00 2001
2 From: Stefano Garzarella <sgarzare@redhat.com>
3 Date: Fri, 1 Feb 2019 12:42:06 +0100
4 Subject: vsock/virtio: fix kernel panic after device hot-unplug
5
6 [ Upstream commit 22b5c0b63f32568e130fa2df4ba23efce3eb495b ]
7
8 virtio_vsock_remove() invokes the vsock_core_exit() also if there
9 are opened sockets for the AF_VSOCK protocol family. In this way
10 the vsock "transport" pointer is set to NULL, triggering the
11 kernel panic at the first socket activity.
12
13 This patch move the vsock_core_init()/vsock_core_exit() in the
14 virtio_vsock respectively in module_init and module_exit functions,
15 that cannot be invoked until there are open sockets.
16
17 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1609699
18 Reported-by: Yan Fu <yafu@redhat.com>
19 Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
20 Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
21 Signed-off-by: David S. Miller <davem@davemloft.net>
22 Signed-off-by: Sasha Levin <sashal@kernel.org>
23 ---
24 net/vmw_vsock/virtio_transport.c | 26 ++++++++++++++++++--------
25 1 file changed, 18 insertions(+), 8 deletions(-)
26
27 diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
28 index 5d3cce9e8744..9dae54698737 100644
29 --- a/net/vmw_vsock/virtio_transport.c
30 +++ b/net/vmw_vsock/virtio_transport.c
31 @@ -75,6 +75,9 @@ static u32 virtio_transport_get_local_cid(void)
32 {
33 struct virtio_vsock *vsock = virtio_vsock_get();
34
35 + if (!vsock)
36 + return VMADDR_CID_ANY;
37 +
38 return vsock->guest_cid;
39 }
40
41 @@ -584,10 +587,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev)
42
43 virtio_vsock_update_guest_cid(vsock);
44
45 - ret = vsock_core_init(&virtio_transport.transport);
46 - if (ret < 0)
47 - goto out_vqs;
48 -
49 vsock->rx_buf_nr = 0;
50 vsock->rx_buf_max_nr = 0;
51 atomic_set(&vsock->queued_replies, 0);
52 @@ -618,8 +617,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev)
53 mutex_unlock(&the_virtio_vsock_mutex);
54 return 0;
55
56 -out_vqs:
57 - vsock->vdev->config->del_vqs(vsock->vdev);
58 out:
59 kfree(vsock);
60 mutex_unlock(&the_virtio_vsock_mutex);
61 @@ -669,7 +666,6 @@ static void virtio_vsock_remove(struct virtio_device *vdev)
62
63 mutex_lock(&the_virtio_vsock_mutex);
64 the_virtio_vsock = NULL;
65 - vsock_core_exit();
66 mutex_unlock(&the_virtio_vsock_mutex);
67
68 vdev->config->del_vqs(vdev);
69 @@ -702,14 +698,28 @@ static int __init virtio_vsock_init(void)
70 virtio_vsock_workqueue = alloc_workqueue("virtio_vsock", 0, 0);
71 if (!virtio_vsock_workqueue)
72 return -ENOMEM;
73 +
74 ret = register_virtio_driver(&virtio_vsock_driver);
75 if (ret)
76 - destroy_workqueue(virtio_vsock_workqueue);
77 + goto out_wq;
78 +
79 + ret = vsock_core_init(&virtio_transport.transport);
80 + if (ret)
81 + goto out_vdr;
82 +
83 + return 0;
84 +
85 +out_vdr:
86 + unregister_virtio_driver(&virtio_vsock_driver);
87 +out_wq:
88 + destroy_workqueue(virtio_vsock_workqueue);
89 return ret;
90 +
91 }
92
93 static void __exit virtio_vsock_exit(void)
94 {
95 + vsock_core_exit();
96 unregister_virtio_driver(&virtio_vsock_driver);
97 destroy_workqueue(virtio_vsock_workqueue);
98 }
99 --
100 2.19.1
101