hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/vmw_vsock/virtio_transport.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * virtio transport for vsock
34 *
....@@ -7,8 +8,6 @@
78 *
89 * Some of the code is take from Gerd Hoffmann <kraxel@redhat.com>'s
910 * early virtio-vsock proof-of-concept bits.
10
- *
11
- * This work is licensed under the terms of the GNU GPL, version 2.
1211 */
1312 #include <linux/spinlock.h>
1413 #include <linux/module.h>
....@@ -23,7 +22,7 @@
2322 #include <net/af_vsock.h>
2423
2524 static struct workqueue_struct *virtio_vsock_workqueue;
26
-static struct virtio_vsock *the_virtio_vsock;
25
+static struct virtio_vsock __rcu *the_virtio_vsock;
2726 static DEFINE_MUTEX(the_virtio_vsock_mutex); /* protects the_virtio_vsock */
2827
2928 struct virtio_vsock {
....@@ -44,10 +43,6 @@
4443 struct work_struct send_pkt_work;
4544 spinlock_t send_pkt_list_lock;
4645 struct list_head send_pkt_list;
47
-
48
- struct work_struct loopback_work;
49
- spinlock_t loopback_list_lock; /* protects loopback_list */
50
- struct list_head loopback_list;
5146
5247 atomic_t queued_replies;
5348
....@@ -85,20 +80,6 @@
8580 out_rcu:
8681 rcu_read_unlock();
8782 return ret;
88
-}
89
-
90
-static int virtio_transport_send_pkt_loopback(struct virtio_vsock *vsock,
91
- struct virtio_vsock_pkt *pkt)
92
-{
93
- int len = pkt->len;
94
-
95
- spin_lock_bh(&vsock->loopback_list_lock);
96
- list_add_tail(&pkt->list, &vsock->loopback_list);
97
- spin_unlock_bh(&vsock->loopback_list_lock);
98
-
99
- queue_work(virtio_vsock_workqueue, &vsock->loopback_work);
100
-
101
- return len;
10283 }
10384
10485 static void
....@@ -195,7 +176,8 @@
195176 }
196177
197178 if (le64_to_cpu(pkt->hdr.dst_cid) == vsock->guest_cid) {
198
- len = virtio_transport_send_pkt_loopback(vsock, pkt);
179
+ virtio_transport_free_pkt(pkt);
180
+ len = -ENODEV;
199181 goto out_rcu;
200182 }
201183
....@@ -281,6 +263,7 @@
281263 break;
282264 }
283265
266
+ pkt->buf_len = buf_len;
284267 pkt->len = buf_len;
285268
286269 sg_init_one(&hdr, &pkt->hdr, sizeof(pkt->hdr));
....@@ -465,6 +448,8 @@
465448
466449 static struct virtio_transport virtio_transport = {
467450 .transport = {
451
+ .module = THIS_MODULE,
452
+
468453 .get_local_cid = virtio_transport_get_local_cid,
469454
470455 .init = virtio_transport_do_socket_init,
....@@ -497,44 +482,11 @@
497482 .notify_send_pre_block = virtio_transport_notify_send_pre_block,
498483 .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue,
499484 .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
500
-
501
- .set_buffer_size = virtio_transport_set_buffer_size,
502
- .set_min_buffer_size = virtio_transport_set_min_buffer_size,
503
- .set_max_buffer_size = virtio_transport_set_max_buffer_size,
504
- .get_buffer_size = virtio_transport_get_buffer_size,
505
- .get_min_buffer_size = virtio_transport_get_min_buffer_size,
506
- .get_max_buffer_size = virtio_transport_get_max_buffer_size,
485
+ .notify_buffer_size = virtio_transport_notify_buffer_size,
507486 },
508487
509488 .send_pkt = virtio_transport_send_pkt,
510489 };
511
-
512
-static void virtio_transport_loopback_work(struct work_struct *work)
513
-{
514
- struct virtio_vsock *vsock =
515
- container_of(work, struct virtio_vsock, loopback_work);
516
- LIST_HEAD(pkts);
517
-
518
- spin_lock_bh(&vsock->loopback_list_lock);
519
- list_splice_init(&vsock->loopback_list, &pkts);
520
- spin_unlock_bh(&vsock->loopback_list_lock);
521
-
522
- mutex_lock(&vsock->rx_lock);
523
-
524
- if (!vsock->rx_run)
525
- goto out;
526
-
527
- while (!list_empty(&pkts)) {
528
- struct virtio_vsock_pkt *pkt;
529
-
530
- pkt = list_first_entry(&pkts, struct virtio_vsock_pkt, list);
531
- list_del_init(&pkt->list);
532
-
533
- virtio_transport_recv_pkt(&virtio_transport, pkt);
534
- }
535
-out:
536
- mutex_unlock(&vsock->rx_lock);
537
-}
538490
539491 static void virtio_transport_rx_work(struct work_struct *work)
540492 {
....@@ -640,13 +592,10 @@
640592 mutex_init(&vsock->event_lock);
641593 spin_lock_init(&vsock->send_pkt_list_lock);
642594 INIT_LIST_HEAD(&vsock->send_pkt_list);
643
- spin_lock_init(&vsock->loopback_list_lock);
644
- INIT_LIST_HEAD(&vsock->loopback_list);
645595 INIT_WORK(&vsock->rx_work, virtio_transport_rx_work);
646596 INIT_WORK(&vsock->tx_work, virtio_transport_tx_work);
647597 INIT_WORK(&vsock->event_work, virtio_transport_event_work);
648598 INIT_WORK(&vsock->send_pkt_work, virtio_transport_send_pkt_work);
649
- INIT_WORK(&vsock->loopback_work, virtio_transport_loopback_work);
650599
651600 mutex_lock(&vsock->tx_lock);
652601 vsock->tx_run = true;
....@@ -684,12 +633,6 @@
684633 vdev->priv = NULL;
685634 rcu_assign_pointer(the_virtio_vsock, NULL);
686635 synchronize_rcu();
687
-
688
- flush_work(&vsock->loopback_work);
689
- flush_work(&vsock->rx_work);
690
- flush_work(&vsock->tx_work);
691
- flush_work(&vsock->event_work);
692
- flush_work(&vsock->send_pkt_work);
693636
694637 /* Reset all connected sockets when the device disappear */
695638 vsock_for_each_connected_socket(virtio_vsock_reset_sock);
....@@ -733,17 +676,16 @@
733676 }
734677 spin_unlock_bh(&vsock->send_pkt_list_lock);
735678
736
- spin_lock_bh(&vsock->loopback_list_lock);
737
- while (!list_empty(&vsock->loopback_list)) {
738
- pkt = list_first_entry(&vsock->loopback_list,
739
- struct virtio_vsock_pkt, list);
740
- list_del(&pkt->list);
741
- virtio_transport_free_pkt(pkt);
742
- }
743
- spin_unlock_bh(&vsock->loopback_list_lock);
744
-
745679 /* Delete virtqueues and flush outstanding callbacks if any */
746680 vdev->config->del_vqs(vdev);
681
+
682
+ /* Other works can be queued before 'config->del_vqs()', so we flush
683
+ * all works before to free the vsock object to avoid use after free.
684
+ */
685
+ flush_work(&vsock->rx_work);
686
+ flush_work(&vsock->tx_work);
687
+ flush_work(&vsock->event_work);
688
+ flush_work(&vsock->send_pkt_work);
747689
748690 mutex_unlock(&the_virtio_vsock_mutex);
749691
....@@ -776,7 +718,8 @@
776718 if (!virtio_vsock_workqueue)
777719 return -ENOMEM;
778720
779
- ret = vsock_core_init(&virtio_transport.transport);
721
+ ret = vsock_core_register(&virtio_transport.transport,
722
+ VSOCK_TRANSPORT_F_G2H);
780723 if (ret)
781724 goto out_wq;
782725
....@@ -787,7 +730,7 @@
787730 return 0;
788731
789732 out_vci:
790
- vsock_core_exit();
733
+ vsock_core_unregister(&virtio_transport.transport);
791734 out_wq:
792735 destroy_workqueue(virtio_vsock_workqueue);
793736 return ret;
....@@ -796,7 +739,7 @@
796739 static void __exit virtio_vsock_exit(void)
797740 {
798741 unregister_virtio_driver(&virtio_vsock_driver);
799
- vsock_core_exit();
742
+ vsock_core_unregister(&virtio_transport.transport);
800743 destroy_workqueue(virtio_vsock_workqueue);
801744 }
802745