Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

VSOCK: Introduce virtio_vsock_common.ko

This module contains the common code and header files for the following
virtio_transporto and vhost_vsock kernel modules.

Signed-off-by: Asias He <asias@redhat.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Asias He and committed by
Michael S. Tsirkin
06a8fc78 6773b7dc

+1398
+10
MAINTAINERS
··· 12138 12138 F: drivers/media/v4l2-core/videobuf2-* 12139 12139 F: include/media/videobuf2-* 12140 12140 12141 + VIRTIO AND VHOST VSOCK DRIVER 12142 + M: Stefan Hajnoczi <stefanha@redhat.com> 12143 + L: kvm@vger.kernel.org 12144 + L: virtualization@lists.linux-foundation.org 12145 + L: netdev@vger.kernel.org 12146 + S: Maintained 12147 + F: include/linux/virtio_vsock.h 12148 + F: include/uapi/linux/virtio_vsock.h 12149 + F: net/vmw_vsock/virtio_transport_common.c 12150 + 12141 12151 VIRTUAL SERIO DEVICE DRIVER 12142 12152 M: Stephen Chandler Paul <thatslyude@gmail.com> 12143 12153 S: Maintained
+154
include/linux/virtio_vsock.h
··· 1 + #ifndef _LINUX_VIRTIO_VSOCK_H 2 + #define _LINUX_VIRTIO_VSOCK_H 3 + 4 + #include <uapi/linux/virtio_vsock.h> 5 + #include <linux/socket.h> 6 + #include <net/sock.h> 7 + #include <net/af_vsock.h> 8 + 9 + #define VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE 128 10 + #define VIRTIO_VSOCK_DEFAULT_BUF_SIZE (1024 * 256) 11 + #define VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE (1024 * 256) 12 + #define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE (1024 * 4) 13 + #define VIRTIO_VSOCK_MAX_BUF_SIZE 0xFFFFFFFFUL 14 + #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64) 15 + 16 + enum { 17 + VSOCK_VQ_RX = 0, /* for host to guest data */ 18 + VSOCK_VQ_TX = 1, /* for guest to host data */ 19 + VSOCK_VQ_EVENT = 2, 20 + VSOCK_VQ_MAX = 3, 21 + }; 22 + 23 + /* Per-socket state (accessed via vsk->trans) */ 24 + struct virtio_vsock_sock { 25 + struct vsock_sock *vsk; 26 + 27 + /* Protected by lock_sock(sk_vsock(trans->vsk)) */ 28 + u32 buf_size; 29 + u32 buf_size_min; 30 + u32 buf_size_max; 31 + 32 + spinlock_t tx_lock; 33 + spinlock_t rx_lock; 34 + 35 + /* Protected by tx_lock */ 36 + u32 tx_cnt; 37 + u32 buf_alloc; 38 + u32 peer_fwd_cnt; 39 + u32 peer_buf_alloc; 40 + 41 + /* Protected by rx_lock */ 42 + u32 fwd_cnt; 43 + u32 rx_bytes; 44 + struct list_head rx_queue; 45 + }; 46 + 47 + struct virtio_vsock_pkt { 48 + struct virtio_vsock_hdr hdr; 49 + struct work_struct work; 50 + struct list_head list; 51 + void *buf; 52 + u32 len; 53 + u32 off; 54 + bool reply; 55 + }; 56 + 57 + struct virtio_vsock_pkt_info { 58 + u32 remote_cid, remote_port; 59 + struct msghdr *msg; 60 + u32 pkt_len; 61 + u16 type; 62 + u16 op; 63 + u32 flags; 64 + bool reply; 65 + }; 66 + 67 + struct virtio_transport { 68 + /* This must be the first field */ 69 + struct vsock_transport transport; 70 + 71 + /* Takes ownership of the packet */ 72 + int (*send_pkt)(struct virtio_vsock_pkt *pkt); 73 + }; 74 + 75 + ssize_t 76 + virtio_transport_stream_dequeue(struct vsock_sock *vsk, 77 + struct msghdr *msg, 78 + size_t len, 79 + int type); 80 + int 81 + virtio_transport_dgram_dequeue(struct vsock_sock *vsk, 82 + struct msghdr *msg, 83 + size_t len, int flags); 84 + 85 + s64 virtio_transport_stream_has_data(struct vsock_sock *vsk); 86 + s64 virtio_transport_stream_has_space(struct vsock_sock *vsk); 87 + 88 + int virtio_transport_do_socket_init(struct vsock_sock *vsk, 89 + struct vsock_sock *psk); 90 + u64 virtio_transport_get_buffer_size(struct vsock_sock *vsk); 91 + u64 virtio_transport_get_min_buffer_size(struct vsock_sock *vsk); 92 + u64 virtio_transport_get_max_buffer_size(struct vsock_sock *vsk); 93 + void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val); 94 + void virtio_transport_set_min_buffer_size(struct vsock_sock *vsk, u64 val); 95 + void virtio_transport_set_max_buffer_size(struct vsock_sock *vs, u64 val); 96 + int 97 + virtio_transport_notify_poll_in(struct vsock_sock *vsk, 98 + size_t target, 99 + bool *data_ready_now); 100 + int 101 + virtio_transport_notify_poll_out(struct vsock_sock *vsk, 102 + size_t target, 103 + bool *space_available_now); 104 + 105 + int virtio_transport_notify_recv_init(struct vsock_sock *vsk, 106 + size_t target, struct vsock_transport_recv_notify_data *data); 107 + int virtio_transport_notify_recv_pre_block(struct vsock_sock *vsk, 108 + size_t target, struct vsock_transport_recv_notify_data *data); 109 + int virtio_transport_notify_recv_pre_dequeue(struct vsock_sock *vsk, 110 + size_t target, struct vsock_transport_recv_notify_data *data); 111 + int virtio_transport_notify_recv_post_dequeue(struct vsock_sock *vsk, 112 + size_t target, ssize_t copied, bool data_read, 113 + struct vsock_transport_recv_notify_data *data); 114 + int virtio_transport_notify_send_init(struct vsock_sock *vsk, 115 + struct vsock_transport_send_notify_data *data); 116 + int virtio_transport_notify_send_pre_block(struct vsock_sock *vsk, 117 + struct vsock_transport_send_notify_data *data); 118 + int virtio_transport_notify_send_pre_enqueue(struct vsock_sock *vsk, 119 + struct vsock_transport_send_notify_data *data); 120 + int virtio_transport_notify_send_post_enqueue(struct vsock_sock *vsk, 121 + ssize_t written, struct vsock_transport_send_notify_data *data); 122 + 123 + u64 virtio_transport_stream_rcvhiwat(struct vsock_sock *vsk); 124 + bool virtio_transport_stream_is_active(struct vsock_sock *vsk); 125 + bool virtio_transport_stream_allow(u32 cid, u32 port); 126 + int virtio_transport_dgram_bind(struct vsock_sock *vsk, 127 + struct sockaddr_vm *addr); 128 + bool virtio_transport_dgram_allow(u32 cid, u32 port); 129 + 130 + int virtio_transport_connect(struct vsock_sock *vsk); 131 + 132 + int virtio_transport_shutdown(struct vsock_sock *vsk, int mode); 133 + 134 + void virtio_transport_release(struct vsock_sock *vsk); 135 + 136 + ssize_t 137 + virtio_transport_stream_enqueue(struct vsock_sock *vsk, 138 + struct msghdr *msg, 139 + size_t len); 140 + int 141 + virtio_transport_dgram_enqueue(struct vsock_sock *vsk, 142 + struct sockaddr_vm *remote_addr, 143 + struct msghdr *msg, 144 + size_t len); 145 + 146 + void virtio_transport_destruct(struct vsock_sock *vsk); 147 + 148 + void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt); 149 + void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt); 150 + void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt); 151 + u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted); 152 + void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit); 153 + 154 + #endif /* _LINUX_VIRTIO_VSOCK_H */
+2
include/net/af_vsock.h
··· 63 63 struct list_head accept_queue; 64 64 bool rejected; 65 65 struct delayed_work dwork; 66 + struct delayed_work close_work; 67 + bool close_work_scheduled; 66 68 u32 peer_shutdown; 67 69 bool sent_request; 68 70 bool ignore_connecting_rst;
+144
include/trace/events/vsock_virtio_transport_common.h
··· 1 + #undef TRACE_SYSTEM 2 + #define TRACE_SYSTEM vsock 3 + 4 + #if !defined(_TRACE_VSOCK_VIRTIO_TRANSPORT_COMMON_H) || \ 5 + defined(TRACE_HEADER_MULTI_READ) 6 + #define _TRACE_VSOCK_VIRTIO_TRANSPORT_COMMON_H 7 + 8 + #include <linux/tracepoint.h> 9 + 10 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_TYPE_STREAM); 11 + 12 + #define show_type(val) \ 13 + __print_symbolic(val, { VIRTIO_VSOCK_TYPE_STREAM, "STREAM" }) 14 + 15 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_INVALID); 16 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_REQUEST); 17 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_RESPONSE); 18 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_RST); 19 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_SHUTDOWN); 20 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_RW); 21 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_CREDIT_UPDATE); 22 + TRACE_DEFINE_ENUM(VIRTIO_VSOCK_OP_CREDIT_REQUEST); 23 + 24 + #define show_op(val) \ 25 + __print_symbolic(val, \ 26 + { VIRTIO_VSOCK_OP_INVALID, "INVALID" }, \ 27 + { VIRTIO_VSOCK_OP_REQUEST, "REQUEST" }, \ 28 + { VIRTIO_VSOCK_OP_RESPONSE, "RESPONSE" }, \ 29 + { VIRTIO_VSOCK_OP_RST, "RST" }, \ 30 + { VIRTIO_VSOCK_OP_SHUTDOWN, "SHUTDOWN" }, \ 31 + { VIRTIO_VSOCK_OP_RW, "RW" }, \ 32 + { VIRTIO_VSOCK_OP_CREDIT_UPDATE, "CREDIT_UPDATE" }, \ 33 + { VIRTIO_VSOCK_OP_CREDIT_REQUEST, "CREDIT_REQUEST" }) 34 + 35 + TRACE_EVENT(virtio_transport_alloc_pkt, 36 + TP_PROTO( 37 + __u32 src_cid, __u32 src_port, 38 + __u32 dst_cid, __u32 dst_port, 39 + __u32 len, 40 + __u16 type, 41 + __u16 op, 42 + __u32 flags 43 + ), 44 + TP_ARGS( 45 + src_cid, src_port, 46 + dst_cid, dst_port, 47 + len, 48 + type, 49 + op, 50 + flags 51 + ), 52 + TP_STRUCT__entry( 53 + __field(__u32, src_cid) 54 + __field(__u32, src_port) 55 + __field(__u32, dst_cid) 56 + __field(__u32, dst_port) 57 + __field(__u32, len) 58 + __field(__u16, type) 59 + __field(__u16, op) 60 + __field(__u32, flags) 61 + ), 62 + TP_fast_assign( 63 + __entry->src_cid = src_cid; 64 + __entry->src_port = src_port; 65 + __entry->dst_cid = dst_cid; 66 + __entry->dst_port = dst_port; 67 + __entry->len = len; 68 + __entry->type = type; 69 + __entry->op = op; 70 + __entry->flags = flags; 71 + ), 72 + TP_printk("%u:%u -> %u:%u len=%u type=%s op=%s flags=%#x", 73 + __entry->src_cid, __entry->src_port, 74 + __entry->dst_cid, __entry->dst_port, 75 + __entry->len, 76 + show_type(__entry->type), 77 + show_op(__entry->op), 78 + __entry->flags) 79 + ); 80 + 81 + TRACE_EVENT(virtio_transport_recv_pkt, 82 + TP_PROTO( 83 + __u32 src_cid, __u32 src_port, 84 + __u32 dst_cid, __u32 dst_port, 85 + __u32 len, 86 + __u16 type, 87 + __u16 op, 88 + __u32 flags, 89 + __u32 buf_alloc, 90 + __u32 fwd_cnt 91 + ), 92 + TP_ARGS( 93 + src_cid, src_port, 94 + dst_cid, dst_port, 95 + len, 96 + type, 97 + op, 98 + flags, 99 + buf_alloc, 100 + fwd_cnt 101 + ), 102 + TP_STRUCT__entry( 103 + __field(__u32, src_cid) 104 + __field(__u32, src_port) 105 + __field(__u32, dst_cid) 106 + __field(__u32, dst_port) 107 + __field(__u32, len) 108 + __field(__u16, type) 109 + __field(__u16, op) 110 + __field(__u32, flags) 111 + __field(__u32, buf_alloc) 112 + __field(__u32, fwd_cnt) 113 + ), 114 + TP_fast_assign( 115 + __entry->src_cid = src_cid; 116 + __entry->src_port = src_port; 117 + __entry->dst_cid = dst_cid; 118 + __entry->dst_port = dst_port; 119 + __entry->len = len; 120 + __entry->type = type; 121 + __entry->op = op; 122 + __entry->flags = flags; 123 + __entry->buf_alloc = buf_alloc; 124 + __entry->fwd_cnt = fwd_cnt; 125 + ), 126 + TP_printk("%u:%u -> %u:%u len=%u type=%s op=%s flags=%#x " 127 + "buf_alloc=%u fwd_cnt=%u", 128 + __entry->src_cid, __entry->src_port, 129 + __entry->dst_cid, __entry->dst_port, 130 + __entry->len, 131 + show_type(__entry->type), 132 + show_op(__entry->op), 133 + __entry->flags, 134 + __entry->buf_alloc, 135 + __entry->fwd_cnt) 136 + ); 137 + 138 + #endif /* _TRACE_VSOCK_VIRTIO_TRANSPORT_COMMON_H */ 139 + 140 + #undef TRACE_INCLUDE_FILE 141 + #define TRACE_INCLUDE_FILE vsock_virtio_transport_common 142 + 143 + /* This part must be outside protection */ 144 + #include <trace/define_trace.h>
+1
include/uapi/linux/Kbuild
··· 453 453 header-y += virtio_rng.h 454 454 header-y += virtio_scsi.h 455 455 header-y += virtio_types.h 456 + header-y += virtio_vsock.h 456 457 header-y += vm_sockets.h 457 458 header-y += vt.h 458 459 header-y += wait.h
+1
include/uapi/linux/virtio_ids.h
··· 41 41 #define VIRTIO_ID_CAIF 12 /* Virtio caif */ 42 42 #define VIRTIO_ID_GPU 16 /* virtio GPU */ 43 43 #define VIRTIO_ID_INPUT 18 /* virtio input */ 44 + #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ 44 45 45 46 #endif /* _LINUX_VIRTIO_IDS_H */
+94
include/uapi/linux/virtio_vsock.h
··· 1 + /* 2 + * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so 3 + * anyone can use the definitions to implement compatible drivers/servers: 4 + * 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions 8 + * are met: 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the name of IBM nor the names of its contributors 15 + * may be used to endorse or promote products derived from this software 16 + * without specific prior written permission. 17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 + * SUCH DAMAGE. 28 + * 29 + * Copyright (C) Red Hat, Inc., 2013-2015 30 + * Copyright (C) Asias He <asias@redhat.com>, 2013 31 + * Copyright (C) Stefan Hajnoczi <stefanha@redhat.com>, 2015 32 + */ 33 + 34 + #ifndef _UAPI_LINUX_VIRTIO_VSOCK_H 35 + #define _UAPI_LINUX_VIRTIO_VOSCK_H 36 + 37 + #include <linux/types.h> 38 + #include <linux/virtio_ids.h> 39 + #include <linux/virtio_config.h> 40 + 41 + struct virtio_vsock_config { 42 + __le64 guest_cid; 43 + } __attribute__((packed)); 44 + 45 + enum virtio_vsock_event_id { 46 + VIRTIO_VSOCK_EVENT_TRANSPORT_RESET = 0, 47 + }; 48 + 49 + struct virtio_vsock_event { 50 + __le32 id; 51 + } __attribute__((packed)); 52 + 53 + struct virtio_vsock_hdr { 54 + __le64 src_cid; 55 + __le64 dst_cid; 56 + __le32 src_port; 57 + __le32 dst_port; 58 + __le32 len; 59 + __le16 type; /* enum virtio_vsock_type */ 60 + __le16 op; /* enum virtio_vsock_op */ 61 + __le32 flags; 62 + __le32 buf_alloc; 63 + __le32 fwd_cnt; 64 + } __attribute__((packed)); 65 + 66 + enum virtio_vsock_type { 67 + VIRTIO_VSOCK_TYPE_STREAM = 1, 68 + }; 69 + 70 + enum virtio_vsock_op { 71 + VIRTIO_VSOCK_OP_INVALID = 0, 72 + 73 + /* Connect operations */ 74 + VIRTIO_VSOCK_OP_REQUEST = 1, 75 + VIRTIO_VSOCK_OP_RESPONSE = 2, 76 + VIRTIO_VSOCK_OP_RST = 3, 77 + VIRTIO_VSOCK_OP_SHUTDOWN = 4, 78 + 79 + /* To send payload */ 80 + VIRTIO_VSOCK_OP_RW = 5, 81 + 82 + /* Tell the peer our credit info */ 83 + VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6, 84 + /* Request the peer to send the credit info to us */ 85 + VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7, 86 + }; 87 + 88 + /* VIRTIO_VSOCK_OP_SHUTDOWN flags values */ 89 + enum virtio_vsock_shutdown { 90 + VIRTIO_VSOCK_SHUTDOWN_RCV = 1, 91 + VIRTIO_VSOCK_SHUTDOWN_SEND = 2, 92 + }; 93 + 94 + #endif /* _UAPI_LINUX_VIRTIO_VSOCK_H */
+992
net/vmw_vsock/virtio_transport_common.c
··· 1 + /* 2 + * common code for virtio vsock 3 + * 4 + * Copyright (C) 2013-2015 Red Hat, Inc. 5 + * Author: Asias He <asias@redhat.com> 6 + * Stefan Hajnoczi <stefanha@redhat.com> 7 + * 8 + * This work is licensed under the terms of the GNU GPL, version 2. 9 + */ 10 + #include <linux/spinlock.h> 11 + #include <linux/module.h> 12 + #include <linux/ctype.h> 13 + #include <linux/list.h> 14 + #include <linux/virtio.h> 15 + #include <linux/virtio_ids.h> 16 + #include <linux/virtio_config.h> 17 + #include <linux/virtio_vsock.h> 18 + 19 + #include <net/sock.h> 20 + #include <net/af_vsock.h> 21 + 22 + #define CREATE_TRACE_POINTS 23 + #include <trace/events/vsock_virtio_transport_common.h> 24 + 25 + /* How long to wait for graceful shutdown of a connection */ 26 + #define VSOCK_CLOSE_TIMEOUT (8 * HZ) 27 + 28 + static const struct virtio_transport *virtio_transport_get_ops(void) 29 + { 30 + const struct vsock_transport *t = vsock_core_get_transport(); 31 + 32 + return container_of(t, struct virtio_transport, transport); 33 + } 34 + 35 + struct virtio_vsock_pkt * 36 + virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info, 37 + size_t len, 38 + u32 src_cid, 39 + u32 src_port, 40 + u32 dst_cid, 41 + u32 dst_port) 42 + { 43 + struct virtio_vsock_pkt *pkt; 44 + int err; 45 + 46 + pkt = kzalloc(sizeof(*pkt), GFP_KERNEL); 47 + if (!pkt) 48 + return NULL; 49 + 50 + pkt->hdr.type = cpu_to_le16(info->type); 51 + pkt->hdr.op = cpu_to_le16(info->op); 52 + pkt->hdr.src_cid = cpu_to_le64(src_cid); 53 + pkt->hdr.dst_cid = cpu_to_le64(dst_cid); 54 + pkt->hdr.src_port = cpu_to_le32(src_port); 55 + pkt->hdr.dst_port = cpu_to_le32(dst_port); 56 + pkt->hdr.flags = cpu_to_le32(info->flags); 57 + pkt->len = len; 58 + pkt->hdr.len = cpu_to_le32(len); 59 + pkt->reply = info->reply; 60 + 61 + if (info->msg && len > 0) { 62 + pkt->buf = kmalloc(len, GFP_KERNEL); 63 + if (!pkt->buf) 64 + goto out_pkt; 65 + err = memcpy_from_msg(pkt->buf, info->msg, len); 66 + if (err) 67 + goto out; 68 + } 69 + 70 + trace_virtio_transport_alloc_pkt(src_cid, src_port, 71 + dst_cid, dst_port, 72 + len, 73 + info->type, 74 + info->op, 75 + info->flags); 76 + 77 + return pkt; 78 + 79 + out: 80 + kfree(pkt->buf); 81 + out_pkt: 82 + kfree(pkt); 83 + return NULL; 84 + } 85 + EXPORT_SYMBOL_GPL(virtio_transport_alloc_pkt); 86 + 87 + static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, 88 + struct virtio_vsock_pkt_info *info) 89 + { 90 + u32 src_cid, src_port, dst_cid, dst_port; 91 + struct virtio_vsock_sock *vvs; 92 + struct virtio_vsock_pkt *pkt; 93 + u32 pkt_len = info->pkt_len; 94 + 95 + src_cid = vm_sockets_get_local_cid(); 96 + src_port = vsk->local_addr.svm_port; 97 + if (!info->remote_cid) { 98 + dst_cid = vsk->remote_addr.svm_cid; 99 + dst_port = vsk->remote_addr.svm_port; 100 + } else { 101 + dst_cid = info->remote_cid; 102 + dst_port = info->remote_port; 103 + } 104 + 105 + vvs = vsk->trans; 106 + 107 + /* we can send less than pkt_len bytes */ 108 + if (pkt_len > VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE) 109 + pkt_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE; 110 + 111 + /* virtio_transport_get_credit might return less than pkt_len credit */ 112 + pkt_len = virtio_transport_get_credit(vvs, pkt_len); 113 + 114 + /* Do not send zero length OP_RW pkt */ 115 + if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW) 116 + return pkt_len; 117 + 118 + pkt = virtio_transport_alloc_pkt(info, pkt_len, 119 + src_cid, src_port, 120 + dst_cid, dst_port); 121 + if (!pkt) { 122 + virtio_transport_put_credit(vvs, pkt_len); 123 + return -ENOMEM; 124 + } 125 + 126 + virtio_transport_inc_tx_pkt(vvs, pkt); 127 + 128 + return virtio_transport_get_ops()->send_pkt(pkt); 129 + } 130 + 131 + static void virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs, 132 + struct virtio_vsock_pkt *pkt) 133 + { 134 + vvs->rx_bytes += pkt->len; 135 + } 136 + 137 + static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs, 138 + struct virtio_vsock_pkt *pkt) 139 + { 140 + vvs->rx_bytes -= pkt->len; 141 + vvs->fwd_cnt += pkt->len; 142 + } 143 + 144 + void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt) 145 + { 146 + spin_lock_bh(&vvs->tx_lock); 147 + pkt->hdr.fwd_cnt = cpu_to_le32(vvs->fwd_cnt); 148 + pkt->hdr.buf_alloc = cpu_to_le32(vvs->buf_alloc); 149 + spin_unlock_bh(&vvs->tx_lock); 150 + } 151 + EXPORT_SYMBOL_GPL(virtio_transport_inc_tx_pkt); 152 + 153 + u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit) 154 + { 155 + u32 ret; 156 + 157 + spin_lock_bh(&vvs->tx_lock); 158 + ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); 159 + if (ret > credit) 160 + ret = credit; 161 + vvs->tx_cnt += ret; 162 + spin_unlock_bh(&vvs->tx_lock); 163 + 164 + return ret; 165 + } 166 + EXPORT_SYMBOL_GPL(virtio_transport_get_credit); 167 + 168 + void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit) 169 + { 170 + spin_lock_bh(&vvs->tx_lock); 171 + vvs->tx_cnt -= credit; 172 + spin_unlock_bh(&vvs->tx_lock); 173 + } 174 + EXPORT_SYMBOL_GPL(virtio_transport_put_credit); 175 + 176 + static int virtio_transport_send_credit_update(struct vsock_sock *vsk, 177 + int type, 178 + struct virtio_vsock_hdr *hdr) 179 + { 180 + struct virtio_vsock_pkt_info info = { 181 + .op = VIRTIO_VSOCK_OP_CREDIT_UPDATE, 182 + .type = type, 183 + }; 184 + 185 + return virtio_transport_send_pkt_info(vsk, &info); 186 + } 187 + 188 + static ssize_t 189 + virtio_transport_stream_do_dequeue(struct vsock_sock *vsk, 190 + struct msghdr *msg, 191 + size_t len) 192 + { 193 + struct virtio_vsock_sock *vvs = vsk->trans; 194 + struct virtio_vsock_pkt *pkt; 195 + size_t bytes, total = 0; 196 + int err = -EFAULT; 197 + 198 + spin_lock_bh(&vvs->rx_lock); 199 + while (total < len && !list_empty(&vvs->rx_queue)) { 200 + pkt = list_first_entry(&vvs->rx_queue, 201 + struct virtio_vsock_pkt, list); 202 + 203 + bytes = len - total; 204 + if (bytes > pkt->len - pkt->off) 205 + bytes = pkt->len - pkt->off; 206 + 207 + /* sk_lock is held by caller so no one else can dequeue. 208 + * Unlock rx_lock since memcpy_to_msg() may sleep. 209 + */ 210 + spin_unlock_bh(&vvs->rx_lock); 211 + 212 + err = memcpy_to_msg(msg, pkt->buf + pkt->off, bytes); 213 + if (err) 214 + goto out; 215 + 216 + spin_lock_bh(&vvs->rx_lock); 217 + 218 + total += bytes; 219 + pkt->off += bytes; 220 + if (pkt->off == pkt->len) { 221 + virtio_transport_dec_rx_pkt(vvs, pkt); 222 + list_del(&pkt->list); 223 + virtio_transport_free_pkt(pkt); 224 + } 225 + } 226 + spin_unlock_bh(&vvs->rx_lock); 227 + 228 + /* Send a credit pkt to peer */ 229 + virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM, 230 + NULL); 231 + 232 + return total; 233 + 234 + out: 235 + if (total) 236 + err = total; 237 + return err; 238 + } 239 + 240 + ssize_t 241 + virtio_transport_stream_dequeue(struct vsock_sock *vsk, 242 + struct msghdr *msg, 243 + size_t len, int flags) 244 + { 245 + if (flags & MSG_PEEK) 246 + return -EOPNOTSUPP; 247 + 248 + return virtio_transport_stream_do_dequeue(vsk, msg, len); 249 + } 250 + EXPORT_SYMBOL_GPL(virtio_transport_stream_dequeue); 251 + 252 + int 253 + virtio_transport_dgram_dequeue(struct vsock_sock *vsk, 254 + struct msghdr *msg, 255 + size_t len, int flags) 256 + { 257 + return -EOPNOTSUPP; 258 + } 259 + EXPORT_SYMBOL_GPL(virtio_transport_dgram_dequeue); 260 + 261 + s64 virtio_transport_stream_has_data(struct vsock_sock *vsk) 262 + { 263 + struct virtio_vsock_sock *vvs = vsk->trans; 264 + s64 bytes; 265 + 266 + spin_lock_bh(&vvs->rx_lock); 267 + bytes = vvs->rx_bytes; 268 + spin_unlock_bh(&vvs->rx_lock); 269 + 270 + return bytes; 271 + } 272 + EXPORT_SYMBOL_GPL(virtio_transport_stream_has_data); 273 + 274 + static s64 virtio_transport_has_space(struct vsock_sock *vsk) 275 + { 276 + struct virtio_vsock_sock *vvs = vsk->trans; 277 + s64 bytes; 278 + 279 + bytes = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); 280 + if (bytes < 0) 281 + bytes = 0; 282 + 283 + return bytes; 284 + } 285 + 286 + s64 virtio_transport_stream_has_space(struct vsock_sock *vsk) 287 + { 288 + struct virtio_vsock_sock *vvs = vsk->trans; 289 + s64 bytes; 290 + 291 + spin_lock_bh(&vvs->tx_lock); 292 + bytes = virtio_transport_has_space(vsk); 293 + spin_unlock_bh(&vvs->tx_lock); 294 + 295 + return bytes; 296 + } 297 + EXPORT_SYMBOL_GPL(virtio_transport_stream_has_space); 298 + 299 + int virtio_transport_do_socket_init(struct vsock_sock *vsk, 300 + struct vsock_sock *psk) 301 + { 302 + struct virtio_vsock_sock *vvs; 303 + 304 + vvs = kzalloc(sizeof(*vvs), GFP_KERNEL); 305 + if (!vvs) 306 + return -ENOMEM; 307 + 308 + vsk->trans = vvs; 309 + vvs->vsk = vsk; 310 + if (psk) { 311 + struct virtio_vsock_sock *ptrans = psk->trans; 312 + 313 + vvs->buf_size = ptrans->buf_size; 314 + vvs->buf_size_min = ptrans->buf_size_min; 315 + vvs->buf_size_max = ptrans->buf_size_max; 316 + vvs->peer_buf_alloc = ptrans->peer_buf_alloc; 317 + } else { 318 + vvs->buf_size = VIRTIO_VSOCK_DEFAULT_BUF_SIZE; 319 + vvs->buf_size_min = VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE; 320 + vvs->buf_size_max = VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE; 321 + } 322 + 323 + vvs->buf_alloc = vvs->buf_size; 324 + 325 + spin_lock_init(&vvs->rx_lock); 326 + spin_lock_init(&vvs->tx_lock); 327 + INIT_LIST_HEAD(&vvs->rx_queue); 328 + 329 + return 0; 330 + } 331 + EXPORT_SYMBOL_GPL(virtio_transport_do_socket_init); 332 + 333 + u64 virtio_transport_get_buffer_size(struct vsock_sock *vsk) 334 + { 335 + struct virtio_vsock_sock *vvs = vsk->trans; 336 + 337 + return vvs->buf_size; 338 + } 339 + EXPORT_SYMBOL_GPL(virtio_transport_get_buffer_size); 340 + 341 + u64 virtio_transport_get_min_buffer_size(struct vsock_sock *vsk) 342 + { 343 + struct virtio_vsock_sock *vvs = vsk->trans; 344 + 345 + return vvs->buf_size_min; 346 + } 347 + EXPORT_SYMBOL_GPL(virtio_transport_get_min_buffer_size); 348 + 349 + u64 virtio_transport_get_max_buffer_size(struct vsock_sock *vsk) 350 + { 351 + struct virtio_vsock_sock *vvs = vsk->trans; 352 + 353 + return vvs->buf_size_max; 354 + } 355 + EXPORT_SYMBOL_GPL(virtio_transport_get_max_buffer_size); 356 + 357 + void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val) 358 + { 359 + struct virtio_vsock_sock *vvs = vsk->trans; 360 + 361 + if (val > VIRTIO_VSOCK_MAX_BUF_SIZE) 362 + val = VIRTIO_VSOCK_MAX_BUF_SIZE; 363 + if (val < vvs->buf_size_min) 364 + vvs->buf_size_min = val; 365 + if (val > vvs->buf_size_max) 366 + vvs->buf_size_max = val; 367 + vvs->buf_size = val; 368 + vvs->buf_alloc = val; 369 + } 370 + EXPORT_SYMBOL_GPL(virtio_transport_set_buffer_size); 371 + 372 + void virtio_transport_set_min_buffer_size(struct vsock_sock *vsk, u64 val) 373 + { 374 + struct virtio_vsock_sock *vvs = vsk->trans; 375 + 376 + if (val > VIRTIO_VSOCK_MAX_BUF_SIZE) 377 + val = VIRTIO_VSOCK_MAX_BUF_SIZE; 378 + if (val > vvs->buf_size) 379 + vvs->buf_size = val; 380 + vvs->buf_size_min = val; 381 + } 382 + EXPORT_SYMBOL_GPL(virtio_transport_set_min_buffer_size); 383 + 384 + void virtio_transport_set_max_buffer_size(struct vsock_sock *vsk, u64 val) 385 + { 386 + struct virtio_vsock_sock *vvs = vsk->trans; 387 + 388 + if (val > VIRTIO_VSOCK_MAX_BUF_SIZE) 389 + val = VIRTIO_VSOCK_MAX_BUF_SIZE; 390 + if (val < vvs->buf_size) 391 + vvs->buf_size = val; 392 + vvs->buf_size_max = val; 393 + } 394 + EXPORT_SYMBOL_GPL(virtio_transport_set_max_buffer_size); 395 + 396 + int 397 + virtio_transport_notify_poll_in(struct vsock_sock *vsk, 398 + size_t target, 399 + bool *data_ready_now) 400 + { 401 + if (vsock_stream_has_data(vsk)) 402 + *data_ready_now = true; 403 + else 404 + *data_ready_now = false; 405 + 406 + return 0; 407 + } 408 + EXPORT_SYMBOL_GPL(virtio_transport_notify_poll_in); 409 + 410 + int 411 + virtio_transport_notify_poll_out(struct vsock_sock *vsk, 412 + size_t target, 413 + bool *space_avail_now) 414 + { 415 + s64 free_space; 416 + 417 + free_space = vsock_stream_has_space(vsk); 418 + if (free_space > 0) 419 + *space_avail_now = true; 420 + else if (free_space == 0) 421 + *space_avail_now = false; 422 + 423 + return 0; 424 + } 425 + EXPORT_SYMBOL_GPL(virtio_transport_notify_poll_out); 426 + 427 + int virtio_transport_notify_recv_init(struct vsock_sock *vsk, 428 + size_t target, struct vsock_transport_recv_notify_data *data) 429 + { 430 + return 0; 431 + } 432 + EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_init); 433 + 434 + int virtio_transport_notify_recv_pre_block(struct vsock_sock *vsk, 435 + size_t target, struct vsock_transport_recv_notify_data *data) 436 + { 437 + return 0; 438 + } 439 + EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_pre_block); 440 + 441 + int virtio_transport_notify_recv_pre_dequeue(struct vsock_sock *vsk, 442 + size_t target, struct vsock_transport_recv_notify_data *data) 443 + { 444 + return 0; 445 + } 446 + EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_pre_dequeue); 447 + 448 + int virtio_transport_notify_recv_post_dequeue(struct vsock_sock *vsk, 449 + size_t target, ssize_t copied, bool data_read, 450 + struct vsock_transport_recv_notify_data *data) 451 + { 452 + return 0; 453 + } 454 + EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_post_dequeue); 455 + 456 + int virtio_transport_notify_send_init(struct vsock_sock *vsk, 457 + struct vsock_transport_send_notify_data *data) 458 + { 459 + return 0; 460 + } 461 + EXPORT_SYMBOL_GPL(virtio_transport_notify_send_init); 462 + 463 + int virtio_transport_notify_send_pre_block(struct vsock_sock *vsk, 464 + struct vsock_transport_send_notify_data *data) 465 + { 466 + return 0; 467 + } 468 + EXPORT_SYMBOL_GPL(virtio_transport_notify_send_pre_block); 469 + 470 + int virtio_transport_notify_send_pre_enqueue(struct vsock_sock *vsk, 471 + struct vsock_transport_send_notify_data *data) 472 + { 473 + return 0; 474 + } 475 + EXPORT_SYMBOL_GPL(virtio_transport_notify_send_pre_enqueue); 476 + 477 + int virtio_transport_notify_send_post_enqueue(struct vsock_sock *vsk, 478 + ssize_t written, struct vsock_transport_send_notify_data *data) 479 + { 480 + return 0; 481 + } 482 + EXPORT_SYMBOL_GPL(virtio_transport_notify_send_post_enqueue); 483 + 484 + u64 virtio_transport_stream_rcvhiwat(struct vsock_sock *vsk) 485 + { 486 + struct virtio_vsock_sock *vvs = vsk->trans; 487 + 488 + return vvs->buf_size; 489 + } 490 + EXPORT_SYMBOL_GPL(virtio_transport_stream_rcvhiwat); 491 + 492 + bool virtio_transport_stream_is_active(struct vsock_sock *vsk) 493 + { 494 + return true; 495 + } 496 + EXPORT_SYMBOL_GPL(virtio_transport_stream_is_active); 497 + 498 + bool virtio_transport_stream_allow(u32 cid, u32 port) 499 + { 500 + return true; 501 + } 502 + EXPORT_SYMBOL_GPL(virtio_transport_stream_allow); 503 + 504 + int virtio_transport_dgram_bind(struct vsock_sock *vsk, 505 + struct sockaddr_vm *addr) 506 + { 507 + return -EOPNOTSUPP; 508 + } 509 + EXPORT_SYMBOL_GPL(virtio_transport_dgram_bind); 510 + 511 + bool virtio_transport_dgram_allow(u32 cid, u32 port) 512 + { 513 + return false; 514 + } 515 + EXPORT_SYMBOL_GPL(virtio_transport_dgram_allow); 516 + 517 + int virtio_transport_connect(struct vsock_sock *vsk) 518 + { 519 + struct virtio_vsock_pkt_info info = { 520 + .op = VIRTIO_VSOCK_OP_REQUEST, 521 + .type = VIRTIO_VSOCK_TYPE_STREAM, 522 + }; 523 + 524 + return virtio_transport_send_pkt_info(vsk, &info); 525 + } 526 + EXPORT_SYMBOL_GPL(virtio_transport_connect); 527 + 528 + int virtio_transport_shutdown(struct vsock_sock *vsk, int mode) 529 + { 530 + struct virtio_vsock_pkt_info info = { 531 + .op = VIRTIO_VSOCK_OP_SHUTDOWN, 532 + .type = VIRTIO_VSOCK_TYPE_STREAM, 533 + .flags = (mode & RCV_SHUTDOWN ? 534 + VIRTIO_VSOCK_SHUTDOWN_RCV : 0) | 535 + (mode & SEND_SHUTDOWN ? 536 + VIRTIO_VSOCK_SHUTDOWN_SEND : 0), 537 + }; 538 + 539 + return virtio_transport_send_pkt_info(vsk, &info); 540 + } 541 + EXPORT_SYMBOL_GPL(virtio_transport_shutdown); 542 + 543 + int 544 + virtio_transport_dgram_enqueue(struct vsock_sock *vsk, 545 + struct sockaddr_vm *remote_addr, 546 + struct msghdr *msg, 547 + size_t dgram_len) 548 + { 549 + return -EOPNOTSUPP; 550 + } 551 + EXPORT_SYMBOL_GPL(virtio_transport_dgram_enqueue); 552 + 553 + ssize_t 554 + virtio_transport_stream_enqueue(struct vsock_sock *vsk, 555 + struct msghdr *msg, 556 + size_t len) 557 + { 558 + struct virtio_vsock_pkt_info info = { 559 + .op = VIRTIO_VSOCK_OP_RW, 560 + .type = VIRTIO_VSOCK_TYPE_STREAM, 561 + .msg = msg, 562 + .pkt_len = len, 563 + }; 564 + 565 + return virtio_transport_send_pkt_info(vsk, &info); 566 + } 567 + EXPORT_SYMBOL_GPL(virtio_transport_stream_enqueue); 568 + 569 + void virtio_transport_destruct(struct vsock_sock *vsk) 570 + { 571 + struct virtio_vsock_sock *vvs = vsk->trans; 572 + 573 + kfree(vvs); 574 + } 575 + EXPORT_SYMBOL_GPL(virtio_transport_destruct); 576 + 577 + static int virtio_transport_reset(struct vsock_sock *vsk, 578 + struct virtio_vsock_pkt *pkt) 579 + { 580 + struct virtio_vsock_pkt_info info = { 581 + .op = VIRTIO_VSOCK_OP_RST, 582 + .type = VIRTIO_VSOCK_TYPE_STREAM, 583 + .reply = !!pkt, 584 + }; 585 + 586 + /* Send RST only if the original pkt is not a RST pkt */ 587 + if (pkt && le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) 588 + return 0; 589 + 590 + return virtio_transport_send_pkt_info(vsk, &info); 591 + } 592 + 593 + /* Normally packets are associated with a socket. There may be no socket if an 594 + * attempt was made to connect to a socket that does not exist. 595 + */ 596 + static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt) 597 + { 598 + struct virtio_vsock_pkt_info info = { 599 + .op = VIRTIO_VSOCK_OP_RST, 600 + .type = le16_to_cpu(pkt->hdr.type), 601 + .reply = true, 602 + }; 603 + 604 + /* Send RST only if the original pkt is not a RST pkt */ 605 + if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) 606 + return 0; 607 + 608 + pkt = virtio_transport_alloc_pkt(&info, 0, 609 + le32_to_cpu(pkt->hdr.dst_cid), 610 + le32_to_cpu(pkt->hdr.dst_port), 611 + le32_to_cpu(pkt->hdr.src_cid), 612 + le32_to_cpu(pkt->hdr.src_port)); 613 + if (!pkt) 614 + return -ENOMEM; 615 + 616 + return virtio_transport_get_ops()->send_pkt(pkt); 617 + } 618 + 619 + static void virtio_transport_wait_close(struct sock *sk, long timeout) 620 + { 621 + if (timeout) { 622 + DEFINE_WAIT(wait); 623 + 624 + do { 625 + prepare_to_wait(sk_sleep(sk), &wait, 626 + TASK_INTERRUPTIBLE); 627 + if (sk_wait_event(sk, &timeout, 628 + sock_flag(sk, SOCK_DONE))) 629 + break; 630 + } while (!signal_pending(current) && timeout); 631 + 632 + finish_wait(sk_sleep(sk), &wait); 633 + } 634 + } 635 + 636 + static void virtio_transport_do_close(struct vsock_sock *vsk, 637 + bool cancel_timeout) 638 + { 639 + struct sock *sk = sk_vsock(vsk); 640 + 641 + sock_set_flag(sk, SOCK_DONE); 642 + vsk->peer_shutdown = SHUTDOWN_MASK; 643 + if (vsock_stream_has_data(vsk) <= 0) 644 + sk->sk_state = SS_DISCONNECTING; 645 + sk->sk_state_change(sk); 646 + 647 + if (vsk->close_work_scheduled && 648 + (!cancel_timeout || cancel_delayed_work(&vsk->close_work))) { 649 + vsk->close_work_scheduled = false; 650 + 651 + vsock_remove_sock(vsk); 652 + 653 + /* Release refcnt obtained when we scheduled the timeout */ 654 + sock_put(sk); 655 + } 656 + } 657 + 658 + static void virtio_transport_close_timeout(struct work_struct *work) 659 + { 660 + struct vsock_sock *vsk = 661 + container_of(work, struct vsock_sock, close_work.work); 662 + struct sock *sk = sk_vsock(vsk); 663 + 664 + sock_hold(sk); 665 + lock_sock(sk); 666 + 667 + if (!sock_flag(sk, SOCK_DONE)) { 668 + (void)virtio_transport_reset(vsk, NULL); 669 + 670 + virtio_transport_do_close(vsk, false); 671 + } 672 + 673 + vsk->close_work_scheduled = false; 674 + 675 + release_sock(sk); 676 + sock_put(sk); 677 + } 678 + 679 + /* User context, vsk->sk is locked */ 680 + static bool virtio_transport_close(struct vsock_sock *vsk) 681 + { 682 + struct sock *sk = &vsk->sk; 683 + 684 + if (!(sk->sk_state == SS_CONNECTED || 685 + sk->sk_state == SS_DISCONNECTING)) 686 + return true; 687 + 688 + /* Already received SHUTDOWN from peer, reply with RST */ 689 + if ((vsk->peer_shutdown & SHUTDOWN_MASK) == SHUTDOWN_MASK) { 690 + (void)virtio_transport_reset(vsk, NULL); 691 + return true; 692 + } 693 + 694 + if ((sk->sk_shutdown & SHUTDOWN_MASK) != SHUTDOWN_MASK) 695 + (void)virtio_transport_shutdown(vsk, SHUTDOWN_MASK); 696 + 697 + if (sock_flag(sk, SOCK_LINGER) && !(current->flags & PF_EXITING)) 698 + virtio_transport_wait_close(sk, sk->sk_lingertime); 699 + 700 + if (sock_flag(sk, SOCK_DONE)) { 701 + return true; 702 + } 703 + 704 + sock_hold(sk); 705 + INIT_DELAYED_WORK(&vsk->close_work, 706 + virtio_transport_close_timeout); 707 + vsk->close_work_scheduled = true; 708 + schedule_delayed_work(&vsk->close_work, VSOCK_CLOSE_TIMEOUT); 709 + return false; 710 + } 711 + 712 + void virtio_transport_release(struct vsock_sock *vsk) 713 + { 714 + struct sock *sk = &vsk->sk; 715 + bool remove_sock = true; 716 + 717 + lock_sock(sk); 718 + if (sk->sk_type == SOCK_STREAM) 719 + remove_sock = virtio_transport_close(vsk); 720 + release_sock(sk); 721 + 722 + if (remove_sock) 723 + vsock_remove_sock(vsk); 724 + } 725 + EXPORT_SYMBOL_GPL(virtio_transport_release); 726 + 727 + static int 728 + virtio_transport_recv_connecting(struct sock *sk, 729 + struct virtio_vsock_pkt *pkt) 730 + { 731 + struct vsock_sock *vsk = vsock_sk(sk); 732 + int err; 733 + int skerr; 734 + 735 + switch (le16_to_cpu(pkt->hdr.op)) { 736 + case VIRTIO_VSOCK_OP_RESPONSE: 737 + sk->sk_state = SS_CONNECTED; 738 + sk->sk_socket->state = SS_CONNECTED; 739 + vsock_insert_connected(vsk); 740 + sk->sk_state_change(sk); 741 + break; 742 + case VIRTIO_VSOCK_OP_INVALID: 743 + break; 744 + case VIRTIO_VSOCK_OP_RST: 745 + skerr = ECONNRESET; 746 + err = 0; 747 + goto destroy; 748 + default: 749 + skerr = EPROTO; 750 + err = -EINVAL; 751 + goto destroy; 752 + } 753 + return 0; 754 + 755 + destroy: 756 + virtio_transport_reset(vsk, pkt); 757 + sk->sk_state = SS_UNCONNECTED; 758 + sk->sk_err = skerr; 759 + sk->sk_error_report(sk); 760 + return err; 761 + } 762 + 763 + static int 764 + virtio_transport_recv_connected(struct sock *sk, 765 + struct virtio_vsock_pkt *pkt) 766 + { 767 + struct vsock_sock *vsk = vsock_sk(sk); 768 + struct virtio_vsock_sock *vvs = vsk->trans; 769 + int err = 0; 770 + 771 + switch (le16_to_cpu(pkt->hdr.op)) { 772 + case VIRTIO_VSOCK_OP_RW: 773 + pkt->len = le32_to_cpu(pkt->hdr.len); 774 + pkt->off = 0; 775 + 776 + spin_lock_bh(&vvs->rx_lock); 777 + virtio_transport_inc_rx_pkt(vvs, pkt); 778 + list_add_tail(&pkt->list, &vvs->rx_queue); 779 + spin_unlock_bh(&vvs->rx_lock); 780 + 781 + sk->sk_data_ready(sk); 782 + return err; 783 + case VIRTIO_VSOCK_OP_CREDIT_UPDATE: 784 + sk->sk_write_space(sk); 785 + break; 786 + case VIRTIO_VSOCK_OP_SHUTDOWN: 787 + if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SHUTDOWN_RCV) 788 + vsk->peer_shutdown |= RCV_SHUTDOWN; 789 + if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SHUTDOWN_SEND) 790 + vsk->peer_shutdown |= SEND_SHUTDOWN; 791 + if (vsk->peer_shutdown == SHUTDOWN_MASK && 792 + vsock_stream_has_data(vsk) <= 0) 793 + sk->sk_state = SS_DISCONNECTING; 794 + if (le32_to_cpu(pkt->hdr.flags)) 795 + sk->sk_state_change(sk); 796 + break; 797 + case VIRTIO_VSOCK_OP_RST: 798 + virtio_transport_do_close(vsk, true); 799 + break; 800 + default: 801 + err = -EINVAL; 802 + break; 803 + } 804 + 805 + virtio_transport_free_pkt(pkt); 806 + return err; 807 + } 808 + 809 + static void 810 + virtio_transport_recv_disconnecting(struct sock *sk, 811 + struct virtio_vsock_pkt *pkt) 812 + { 813 + struct vsock_sock *vsk = vsock_sk(sk); 814 + 815 + if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) 816 + virtio_transport_do_close(vsk, true); 817 + } 818 + 819 + static int 820 + virtio_transport_send_response(struct vsock_sock *vsk, 821 + struct virtio_vsock_pkt *pkt) 822 + { 823 + struct virtio_vsock_pkt_info info = { 824 + .op = VIRTIO_VSOCK_OP_RESPONSE, 825 + .type = VIRTIO_VSOCK_TYPE_STREAM, 826 + .remote_cid = le32_to_cpu(pkt->hdr.src_cid), 827 + .remote_port = le32_to_cpu(pkt->hdr.src_port), 828 + .reply = true, 829 + }; 830 + 831 + return virtio_transport_send_pkt_info(vsk, &info); 832 + } 833 + 834 + /* Handle server socket */ 835 + static int 836 + virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt) 837 + { 838 + struct vsock_sock *vsk = vsock_sk(sk); 839 + struct vsock_sock *vchild; 840 + struct sock *child; 841 + 842 + if (le16_to_cpu(pkt->hdr.op) != VIRTIO_VSOCK_OP_REQUEST) { 843 + virtio_transport_reset(vsk, pkt); 844 + return -EINVAL; 845 + } 846 + 847 + if (sk_acceptq_is_full(sk)) { 848 + virtio_transport_reset(vsk, pkt); 849 + return -ENOMEM; 850 + } 851 + 852 + child = __vsock_create(sock_net(sk), NULL, sk, GFP_KERNEL, 853 + sk->sk_type, 0); 854 + if (!child) { 855 + virtio_transport_reset(vsk, pkt); 856 + return -ENOMEM; 857 + } 858 + 859 + sk->sk_ack_backlog++; 860 + 861 + lock_sock_nested(child, SINGLE_DEPTH_NESTING); 862 + 863 + child->sk_state = SS_CONNECTED; 864 + 865 + vchild = vsock_sk(child); 866 + vsock_addr_init(&vchild->local_addr, le32_to_cpu(pkt->hdr.dst_cid), 867 + le32_to_cpu(pkt->hdr.dst_port)); 868 + vsock_addr_init(&vchild->remote_addr, le32_to_cpu(pkt->hdr.src_cid), 869 + le32_to_cpu(pkt->hdr.src_port)); 870 + 871 + vsock_insert_connected(vchild); 872 + vsock_enqueue_accept(sk, child); 873 + virtio_transport_send_response(vchild, pkt); 874 + 875 + release_sock(child); 876 + 877 + sk->sk_data_ready(sk); 878 + return 0; 879 + } 880 + 881 + static bool virtio_transport_space_update(struct sock *sk, 882 + struct virtio_vsock_pkt *pkt) 883 + { 884 + struct vsock_sock *vsk = vsock_sk(sk); 885 + struct virtio_vsock_sock *vvs = vsk->trans; 886 + bool space_available; 887 + 888 + /* buf_alloc and fwd_cnt is always included in the hdr */ 889 + spin_lock_bh(&vvs->tx_lock); 890 + vvs->peer_buf_alloc = le32_to_cpu(pkt->hdr.buf_alloc); 891 + vvs->peer_fwd_cnt = le32_to_cpu(pkt->hdr.fwd_cnt); 892 + space_available = virtio_transport_has_space(vsk); 893 + spin_unlock_bh(&vvs->tx_lock); 894 + return space_available; 895 + } 896 + 897 + /* We are under the virtio-vsock's vsock->rx_lock or vhost-vsock's vq->mutex 898 + * lock. 899 + */ 900 + void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt) 901 + { 902 + struct sockaddr_vm src, dst; 903 + struct vsock_sock *vsk; 904 + struct sock *sk; 905 + bool space_available; 906 + 907 + vsock_addr_init(&src, le32_to_cpu(pkt->hdr.src_cid), 908 + le32_to_cpu(pkt->hdr.src_port)); 909 + vsock_addr_init(&dst, le32_to_cpu(pkt->hdr.dst_cid), 910 + le32_to_cpu(pkt->hdr.dst_port)); 911 + 912 + trace_virtio_transport_recv_pkt(src.svm_cid, src.svm_port, 913 + dst.svm_cid, dst.svm_port, 914 + le32_to_cpu(pkt->hdr.len), 915 + le16_to_cpu(pkt->hdr.type), 916 + le16_to_cpu(pkt->hdr.op), 917 + le32_to_cpu(pkt->hdr.flags), 918 + le32_to_cpu(pkt->hdr.buf_alloc), 919 + le32_to_cpu(pkt->hdr.fwd_cnt)); 920 + 921 + if (le16_to_cpu(pkt->hdr.type) != VIRTIO_VSOCK_TYPE_STREAM) { 922 + (void)virtio_transport_reset_no_sock(pkt); 923 + goto free_pkt; 924 + } 925 + 926 + /* The socket must be in connected or bound table 927 + * otherwise send reset back 928 + */ 929 + sk = vsock_find_connected_socket(&src, &dst); 930 + if (!sk) { 931 + sk = vsock_find_bound_socket(&dst); 932 + if (!sk) { 933 + (void)virtio_transport_reset_no_sock(pkt); 934 + goto free_pkt; 935 + } 936 + } 937 + 938 + vsk = vsock_sk(sk); 939 + 940 + space_available = virtio_transport_space_update(sk, pkt); 941 + 942 + lock_sock(sk); 943 + 944 + /* Update CID in case it has changed after a transport reset event */ 945 + vsk->local_addr.svm_cid = dst.svm_cid; 946 + 947 + if (space_available) 948 + sk->sk_write_space(sk); 949 + 950 + switch (sk->sk_state) { 951 + case VSOCK_SS_LISTEN: 952 + virtio_transport_recv_listen(sk, pkt); 953 + virtio_transport_free_pkt(pkt); 954 + break; 955 + case SS_CONNECTING: 956 + virtio_transport_recv_connecting(sk, pkt); 957 + virtio_transport_free_pkt(pkt); 958 + break; 959 + case SS_CONNECTED: 960 + virtio_transport_recv_connected(sk, pkt); 961 + break; 962 + case SS_DISCONNECTING: 963 + virtio_transport_recv_disconnecting(sk, pkt); 964 + virtio_transport_free_pkt(pkt); 965 + break; 966 + default: 967 + virtio_transport_free_pkt(pkt); 968 + break; 969 + } 970 + release_sock(sk); 971 + 972 + /* Release refcnt obtained when we fetched this socket out of the 973 + * bound or connected list. 974 + */ 975 + sock_put(sk); 976 + return; 977 + 978 + free_pkt: 979 + virtio_transport_free_pkt(pkt); 980 + } 981 + EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt); 982 + 983 + void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt) 984 + { 985 + kfree(pkt->buf); 986 + kfree(pkt); 987 + } 988 + EXPORT_SYMBOL_GPL(virtio_transport_free_pkt); 989 + 990 + MODULE_LICENSE("GPL v2"); 991 + MODULE_AUTHOR("Asias He"); 992 + MODULE_DESCRIPTION("common code for virtio vsock");