Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* loopback transport for vsock using virtio_transport_common APIs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2013-2019 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Authors: Asias He <asias@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *          Stefan Hajnoczi <stefanha@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *          Stefano Garzarella <sgarzare@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/virtio_vsock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) struct vsock_loopback {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	struct workqueue_struct *workqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	spinlock_t pkt_list_lock; /* protects pkt_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	struct list_head pkt_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	struct work_struct pkt_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static struct vsock_loopback the_vsock_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static u32 vsock_loopback_get_local_cid(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	return VMADDR_CID_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static int vsock_loopback_send_pkt(struct virtio_vsock_pkt *pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct vsock_loopback *vsock = &the_vsock_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	int len = pkt->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	spin_lock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	list_add_tail(&pkt->list, &vsock->pkt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	spin_unlock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	queue_work(vsock->workqueue, &vsock->pkt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static int vsock_loopback_cancel_pkt(struct vsock_sock *vsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct vsock_loopback *vsock = &the_vsock_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct virtio_vsock_pkt *pkt, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	LIST_HEAD(freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	spin_lock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	list_for_each_entry_safe(pkt, n, &vsock->pkt_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		if (pkt->vsk != vsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		list_move(&pkt->list, &freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	spin_unlock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	list_for_each_entry_safe(pkt, n, &freeme, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		list_del(&pkt->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		virtio_transport_free_pkt(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static struct virtio_transport loopback_transport = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	.transport = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		.module                   = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		.get_local_cid            = vsock_loopback_get_local_cid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		.init                     = virtio_transport_do_socket_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		.destruct                 = virtio_transport_destruct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		.release                  = virtio_transport_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		.connect                  = virtio_transport_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		.shutdown                 = virtio_transport_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		.cancel_pkt               = vsock_loopback_cancel_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		.dgram_bind               = virtio_transport_dgram_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		.dgram_dequeue            = virtio_transport_dgram_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		.dgram_enqueue            = virtio_transport_dgram_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		.dgram_allow              = virtio_transport_dgram_allow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		.stream_dequeue           = virtio_transport_stream_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		.stream_enqueue           = virtio_transport_stream_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		.stream_has_data          = virtio_transport_stream_has_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		.stream_has_space         = virtio_transport_stream_has_space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		.stream_rcvhiwat          = virtio_transport_stream_rcvhiwat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		.stream_is_active         = virtio_transport_stream_is_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		.stream_allow             = virtio_transport_stream_allow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		.notify_poll_in           = virtio_transport_notify_poll_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		.notify_poll_out          = virtio_transport_notify_poll_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		.notify_recv_init         = virtio_transport_notify_recv_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		.notify_recv_pre_block    = virtio_transport_notify_recv_pre_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		.notify_recv_pre_dequeue  = virtio_transport_notify_recv_pre_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.notify_recv_post_dequeue = virtio_transport_notify_recv_post_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		.notify_send_init         = virtio_transport_notify_send_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		.notify_send_pre_block    = virtio_transport_notify_send_pre_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		.notify_send_pre_enqueue  = virtio_transport_notify_send_pre_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		.notify_buffer_size       = virtio_transport_notify_buffer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	.send_pkt = vsock_loopback_send_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void vsock_loopback_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct vsock_loopback *vsock =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		container_of(work, struct vsock_loopback, pkt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	LIST_HEAD(pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	spin_lock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	list_splice_init(&vsock->pkt_list, &pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	spin_unlock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	while (!list_empty(&pkts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		struct virtio_vsock_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		pkt = list_first_entry(&pkts, struct virtio_vsock_pkt, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		list_del_init(&pkt->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		virtio_transport_deliver_tap_pkt(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		virtio_transport_recv_pkt(&loopback_transport, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int __init vsock_loopback_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	struct vsock_loopback *vsock = &the_vsock_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	vsock->workqueue = alloc_workqueue("vsock-loopback", 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (!vsock->workqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	spin_lock_init(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	INIT_LIST_HEAD(&vsock->pkt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	INIT_WORK(&vsock->pkt_work, vsock_loopback_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	ret = vsock_core_register(&loopback_transport.transport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 				  VSOCK_TRANSPORT_F_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		goto out_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) out_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	destroy_workqueue(vsock->workqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void __exit vsock_loopback_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct vsock_loopback *vsock = &the_vsock_loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct virtio_vsock_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	vsock_core_unregister(&loopback_transport.transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	flush_work(&vsock->pkt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	spin_lock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	while (!list_empty(&vsock->pkt_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		pkt = list_first_entry(&vsock->pkt_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				       struct virtio_vsock_pkt, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		list_del(&pkt->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		virtio_transport_free_pkt(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	spin_unlock_bh(&vsock->pkt_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	destroy_workqueue(vsock->workqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) module_init(vsock_loopback_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) module_exit(vsock_loopback_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) MODULE_AUTHOR("Stefano Garzarella <sgarzare@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) MODULE_DESCRIPTION("loopback transport for vsock");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) MODULE_ALIAS_NETPROTO(PF_VSOCK);