From patchwork Mon Aug 2 12:07:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fuguancheng X-Patchwork-Id: 490618 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AEEC6C4320A for ; Mon, 2 Aug 2021 12:07:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 966C860EFD for ; Mon, 2 Aug 2021 12:07:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233613AbhHBMHs (ORCPT ); Mon, 2 Aug 2021 08:07:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41480 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233592AbhHBMHr (ORCPT ); Mon, 2 Aug 2021 08:07:47 -0400 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3650C061796 for ; Mon, 2 Aug 2021 05:07:37 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id dw2-20020a17090b0942b0290177cb475142so5459602pjb.2 for ; Mon, 02 Aug 2021 05:07:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4lKuIZJ+0KqAGVCoN8Z66K3Xn0Mly9XTxCMHr8cyHAY=; b=08Z7H5ydBYQTIldpt+qGamjHw1zuyIwmOxhdgV/Wn++MYSd1AsKHdptF4YOtEK1NqK 0dLV56s3jhLtScBVrWNj5vG7X6TCzdm1iVeal3kss8bGdsdy6zfNHpuFduoYiqRW6ppy DAbkDg3Djln8qNWGlAra5VIPCv9M3oqrq+tWIEeVYHbR95nY0zt90JbZQHr/JB+WO5rP n8Ft+bJCVicARIz4Zuvwj/lFQJ6XVfUjrCModb97pvd11jfrUl60uHIP3XKA2yKzMHd9 cH4vBn1rss3FtH406mQzhQovciuxKDZEkW3g/z4IF5njD+G+a+yULND9xBMZ4gMuPGWH gaxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4lKuIZJ+0KqAGVCoN8Z66K3Xn0Mly9XTxCMHr8cyHAY=; b=WlsBPuGw8F/ptHD9WOTVd5a1+VhlL8HPOFa6sBvjvvV9RoIL1HqdqKutJBBaLQcE+/ 3wba4XZUYWCNYVVcABpwkXCJoabjisZlTyp4omg9cV3+dxVdYnyUZwaCxLx3ZD9/xixp w0U7BsTnCrRmr6lBEPnKJZ8Et/VPuGQmDl5stbuPx36zXRHPAso5c6NNSc6O9lWQamYs jRWFbh6BnwnpXJBLlgjqpzqQuMzmKhrWActDbamY3XYlo0uZn+1WWZ8zxQXcmGr8PaiE 5vb+iZtYwgVV9E5g9W3O/9mO+M4oAaglmn42Qib0rO/ItT99HccPmP8Do8Q4c1l+kDuR GOTQ== X-Gm-Message-State: AOAM533DRxCtDCfwF/fc2VTrywiqQgCp+R00t2Iv2qYj9MYLGzi3RDOq rPk1BestS5abrjTEUGpGWXlRZw== X-Google-Smtp-Source: ABdhPJywaAdDoymWTtHFlAX+sRztNKxnkCxaCy0xGex449wNmU6iPiv8MapU1U9D9fy1co/oEUsi8g== X-Received: by 2002:aa7:80d9:0:b029:2ed:49fa:6dc5 with SMTP id a25-20020aa780d90000b02902ed49fa6dc5mr16433251pfn.3.1627906057409; Mon, 02 Aug 2021 05:07:37 -0700 (PDT) Received: from n248-175-059.byted.org. ([121.30.179.62]) by smtp.googlemail.com with ESMTPSA id f30sm12874867pgl.48.2021.08.02.05.07.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Aug 2021 05:07:37 -0700 (PDT) From: fuguancheng To: mst@redhat.com, jasowang@redhat.com, stefanha@redhat.com, sgarzare@redhat.com, davem@davemloft.net, kuba@kernel.org, arseny.krasnov@kaspersky.com, andraprs@amazon.com, colin.king@canonical.com Cc: kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, fuguancheng Subject: [PATCH 1/4] VSOCK DRIVER: Add multi-cid support for guest Date: Mon, 2 Aug 2021 20:07:17 +0800 Message-Id: <20210802120720.547894-2-fuguancheng@bytedance.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20210802120720.547894-1-fuguancheng@bytedance.com> References: <20210802120720.547894-1-fuguancheng@bytedance.com> Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch allowes the user to specify multiple additional CIDS for the guest that can be used for communication between host and guest. The guest reads the additional cids from the device config space. The device config space layout can be found at uapi/linux/virtio_vsock.h The existing ioctl call for device VHOST_VIRTIO with request code VHOST_VSOCK_SET_GUEST_CID is modified to notify the host for the additional guest CIDS. Signed-off-by: fuguancheng --- drivers/vhost/vhost.h | 5 ++ drivers/vhost/vsock.c | 173 +++++++++++++++++++++++++++++--------- include/net/af_vsock.h | 1 + include/uapi/linux/vhost.h | 7 ++ include/uapi/linux/virtio_vsock.h | 3 +- net/vmw_vsock/af_vsock.c | 6 +- net/vmw_vsock/virtio_transport.c | 72 ++++++++++++++-- net/vmw_vsock/vsock_loopback.c | 8 ++ 8 files changed, 222 insertions(+), 53 deletions(-) diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 638bb640d6b4..52bd143ccf0c 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -25,6 +25,11 @@ struct vhost_work { unsigned long flags; }; +struct multi_cid_message { + u32 number_cid; + u64 *cid; +}; + /* Poll a file (eventfd or socket) */ /* Note: there's nothing vhost specific about this structure. */ struct vhost_poll { diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index f249622ef11b..f66c87de91b8 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -43,12 +43,25 @@ enum { static DEFINE_MUTEX(vhost_vsock_mutex); static DEFINE_READ_MOSTLY_HASHTABLE(vhost_vsock_hash, 8); +struct vhost_vsock_ref { + struct vhost_vsock *vsock; + struct hlist_node ref_hash; + u32 cid; +}; + +static bool vhost_transport_contain_cid(u32 cid) +{ + if (cid == VHOST_VSOCK_DEFAULT_HOST_CID) + return true; + return false; +} + struct vhost_vsock { struct vhost_dev dev; struct vhost_virtqueue vqs[2]; /* Link to global vhost_vsock_hash, writes use vhost_vsock_mutex */ - struct hlist_node hash; + struct vhost_vsock_ref *ref_list; struct vhost_work send_pkt_work; spinlock_t send_pkt_list_lock; @@ -56,7 +69,8 @@ struct vhost_vsock { atomic_t queued_replies; - u32 guest_cid; + u32 *cids; + u32 num_cid; bool seqpacket_allow; }; @@ -70,23 +84,49 @@ static u32 vhost_transport_get_local_cid(void) */ static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) { - struct vhost_vsock *vsock; + struct vhost_vsock_ref *ref; - hash_for_each_possible_rcu(vhost_vsock_hash, vsock, hash, guest_cid) { - u32 other_cid = vsock->guest_cid; + hash_for_each_possible_rcu(vhost_vsock_hash, ref, ref_hash, guest_cid) { + u32 other_cid = ref->cid; /* Skip instances that have no CID yet */ if (other_cid == 0) continue; if (other_cid == guest_cid) - return vsock; + return ref->vsock; } return NULL; } +static int check_if_cid_valid(u64 guest_cid, struct vhost_vsock *vsock) +{ + struct vhost_vsock *other; + + if (guest_cid <= VMADDR_CID_HOST || guest_cid == U32_MAX) + return -EINVAL; + + /* 64-bit CIDs are not yet supported */ + if (guest_cid > U32_MAX) + return -EINVAL; + /* Refuse if CID is assigned to the guest->host transport (i.e. nested + * VM), to make the loopback work. + */ + if (vsock_find_cid(guest_cid)) + return -EADDRINUSE; + /* Refuse if CID is already in use */ + mutex_lock(&vhost_vsock_mutex); + other = vhost_vsock_get(guest_cid); + if (other) { + mutex_unlock(&vhost_vsock_mutex); + return -EADDRINUSE; + } + mutex_unlock(&vhost_vsock_mutex); + return 0; +} + static void vhost_transport_do_send_pkt(struct vhost_vsock *vsock, struct vhost_virtqueue *vq) @@ -427,6 +467,7 @@ static struct virtio_transport vhost_transport = { .module = THIS_MODULE, .get_local_cid = vhost_transport_get_local_cid, + .contain_cid = vhost_transport_contain_cid, .init = virtio_transport_do_socket_init, .destruct = virtio_transport_destruct, @@ -542,9 +583,9 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) virtio_transport_deliver_tap_pkt(pkt); /* Only accept correctly addressed packets */ - if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid && - le64_to_cpu(pkt->hdr.dst_cid) == - vhost_transport_get_local_cid()) + if (vsock->num_cid > 0 && + (pkt->hdr.src_cid) == vsock->cids[0] && + le64_to_cpu(pkt->hdr.dst_cid) == vhost_transport_get_local_cid()) virtio_transport_recv_pkt(&vhost_transport, pkt); else virtio_transport_free_pkt(pkt); @@ -655,6 +696,10 @@ static int vhost_vsock_stop(struct vhost_vsock *vsock) static void vhost_vsock_free(struct vhost_vsock *vsock) { + if (vsock->ref_list) + kvfree(vsock->ref_list); + if (vsock->cids) + kvfree(vsock->cids); kvfree(vsock); } @@ -677,7 +722,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) goto out; } - vsock->guest_cid = 0; /* no CID assigned yet */ + vsock->ref_list = NULL; + vsock->cids = NULL; + vsock->num_cid = 0; atomic_set(&vsock->queued_replies, 0); @@ -739,11 +786,14 @@ static void vhost_vsock_reset_orphans(struct sock *sk) static int vhost_vsock_dev_release(struct inode *inode, struct file *file) { + int index; struct vhost_vsock *vsock = file->private_data; mutex_lock(&vhost_vsock_mutex); - if (vsock->guest_cid) - hash_del_rcu(&vsock->hash); + if (vsock->num_cid) { + for (index = 0; index < vsock->num_cid; index++) + hash_del_rcu(&vsock->ref_list[index].ref_hash); + } mutex_unlock(&vhost_vsock_mutex); /* Wait for other CPUs to finish using vsock */ @@ -774,41 +824,80 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) return 0; } -static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid) +static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 __user *cids, u32 number_cid) { - struct vhost_vsock *other; + u64 cid; + int i, ret; - /* Refuse reserved CIDs */ - if (guest_cid <= VMADDR_CID_HOST || - guest_cid == U32_MAX) + if (number_cid <= 0) return -EINVAL; - - /* 64-bit CIDs are not yet supported */ - if (guest_cid > U32_MAX) - return -EINVAL; - - /* Refuse if CID is assigned to the guest->host transport (i.e. nested - * VM), to make the loopback work. - */ - if (vsock_find_cid(guest_cid)) - return -EADDRINUSE; - - /* Refuse if CID is already in use */ - mutex_lock(&vhost_vsock_mutex); - other = vhost_vsock_get(guest_cid); - if (other && other != vsock) { + /* delete the old CIDs. */ + if (vsock->num_cid) { + mutex_lock(&vhost_vsock_mutex); + for (i = 0; i < vsock->num_cid; i++) + hash_del_rcu(&vsock->ref_list[i].ref_hash); mutex_unlock(&vhost_vsock_mutex); - return -EADDRINUSE; + kvfree(vsock->ref_list); + vsock->ref_list = NULL; + kvfree(vsock->cids); + vsock->cids = NULL; + } + vsock->num_cid = number_cid; + vsock->cids = kmalloc_array(vsock->num_cid, sizeof(u32), + GFP_KERNEL | __GFP_RETRY_MAYFAIL); + if (!vsock->cids) { + vsock->num_cid = 0; + ret = -ENOMEM; + goto out; + } + vsock->ref_list = kvmalloc_array(vsock->num_cid, sizeof(*vsock->ref_list), + GFP_KERNEL | __GFP_RETRY_MAYFAIL); + if (!vsock->ref_list) { + vsock->num_cid = 0; + ret = -ENOMEM; + goto out; } - if (vsock->guest_cid) - hash_del_rcu(&vsock->hash); - - vsock->guest_cid = guest_cid; - hash_add_rcu(vhost_vsock_hash, &vsock->hash, vsock->guest_cid); - mutex_unlock(&vhost_vsock_mutex); + for (i = 0; i < number_cid; i++) { + if (copy_from_user(&cid, cids + i, sizeof(cid))) { + /* record where we failed, to clean up the ref in hash table. */ + vsock->num_cid = i; + ret = -EFAULT; + goto out; + } + ret = check_if_cid_valid(cid, vsock); + if (ret) { + vsock->num_cid = i; + goto out; + } + vsock->cids[i] = (u32)cid; + vsock->ref_list[i].cid = vsock->cids[i]; + vsock->ref_list[i].vsock = vsock; + mutex_lock(&vhost_vsock_mutex); + hash_add_rcu(vhost_vsock_hash, &vsock->ref_list[i].ref_hash, + vsock->cids[i]); + mutex_unlock(&vhost_vsock_mutex); + } return 0; + +out: + /* Handle the memory release here. */ + if (vsock->num_cid) { + mutex_lock(&vhost_vsock_mutex); + for (i = 0; i < vsock->num_cid; i++) + hash_del_rcu(&vsock->ref_list[i].ref_hash); + mutex_unlock(&vhost_vsock_mutex); + vsock->num_cid = 0; + } + if (vsock->ref_list) + kvfree(vsock->ref_list); + if (vsock->cids) + kvfree(vsock->cids); + /* Set it to null to prevent double release. */ + vsock->ref_list = NULL; + vsock->cids = NULL; + return ret; } static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features) @@ -852,16 +941,16 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl, { struct vhost_vsock *vsock = f->private_data; void __user *argp = (void __user *)arg; - u64 guest_cid; u64 features; int start; int r; + struct multi_cid_message cid_message; switch (ioctl) { case VHOST_VSOCK_SET_GUEST_CID: - if (copy_from_user(&guest_cid, argp, sizeof(guest_cid))) + if (copy_from_user(&cid_message, argp, sizeof(cid_message))) return -EFAULT; - return vhost_vsock_set_cid(vsock, guest_cid); + return vhost_vsock_set_cid(vsock, cid_message.cid, cid_message.number_cid); case VHOST_VSOCK_SET_RUNNING: if (copy_from_user(&start, argp, sizeof(start))) return -EFAULT; diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index ab207677e0a8..d0fc08fb9cac 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -170,6 +170,7 @@ struct vsock_transport { /* Addressing. */ u32 (*get_local_cid)(void); + bool (*contain_cid)(u32 cid); }; /**** CORE ****/ diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index c998860d7bbc..a3ea99f6fc7f 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h @@ -17,6 +17,13 @@ #define VHOST_FILE_UNBIND -1 +/* structs used for hypervisors to send cid info. */ + +struct multi_cid_message { + u32 number_cid; + u64 *cid; +}; + /* ioctls */ #define VHOST_VIRTIO 0xAF diff --git a/include/uapi/linux/virtio_vsock.h b/include/uapi/linux/virtio_vsock.h index 3dd3555b2740..0afc14446b01 100644 --- a/include/uapi/linux/virtio_vsock.h +++ b/include/uapi/linux/virtio_vsock.h @@ -42,7 +42,8 @@ #define VIRTIO_VSOCK_F_SEQPACKET 1 /* SOCK_SEQPACKET supported */ struct virtio_vsock_config { - __le64 guest_cid; + __le32 number_cid; + __le64 cids[]; } __attribute__((packed)); enum virtio_vsock_event_id { diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 3e02cc3b24f8..4e1fbe74013f 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -507,13 +507,13 @@ EXPORT_SYMBOL_GPL(vsock_assign_transport); bool vsock_find_cid(unsigned int cid) { - if (transport_g2h && cid == transport_g2h->get_local_cid()) + if (transport_g2h && transport_g2h->contain_cid(cid)) return true; - if (transport_h2g && cid == VMADDR_CID_HOST) + if (transport_h2g && transport_h2g->contain_cid(cid)) return true; - if (transport_local && cid == VMADDR_CID_LOCAL) + if (transport_local && transport_local->contain_cid(cid)) return true; return false; diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index e0c2c992ad9c..5f256a57d9ae 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -61,10 +61,41 @@ struct virtio_vsock { bool event_run; struct virtio_vsock_event event_list[8]; - u32 guest_cid; + /* The following fields are used to hold additional cids given by the hypervisor + * such as qemu. + */ + u32 number_cid; + u32 *cids; + bool seqpacket_allow; }; +static bool virtio_transport_contain_cid(u32 cid) +{ + struct virtio_vsock *vsock; + bool ret; + u32 num_cid; + + num_cid = 0; + rcu_read_lock(); + vsock = rcu_dereference(the_virtio_vsock); + if (!vsock || !vsock->number_cid) { + ret = false; + goto out_rcu; + } + + for (num_cid = 0; num_cid < vsock->number_cid; num_cid++) { + if (vsock->cids[num_cid] == cid) { + ret = true; + goto out_rcu; + } + } + ret = false; +out_rcu: + rcu_read_unlock(); + return ret; +} + static u32 virtio_transport_get_local_cid(void) { struct virtio_vsock *vsock; @@ -72,12 +103,12 @@ static u32 virtio_transport_get_local_cid(void) rcu_read_lock(); vsock = rcu_dereference(the_virtio_vsock); - if (!vsock) { + if (!vsock || !vsock->number_cid) { ret = VMADDR_CID_ANY; goto out_rcu; } - ret = vsock->guest_cid; + ret = vsock->cids[0]; out_rcu: rcu_read_unlock(); return ret; @@ -176,7 +207,7 @@ virtio_transport_send_pkt(struct virtio_vsock_pkt *pkt) goto out_rcu; } - if (le64_to_cpu(pkt->hdr.dst_cid) == vsock->guest_cid) { + if (le64_to_cpu(pkt->hdr.dst_cid) == vsock->cids[0]) { virtio_transport_free_pkt(pkt); len = -ENODEV; goto out_rcu; @@ -368,10 +399,33 @@ static void virtio_vsock_update_guest_cid(struct virtio_vsock *vsock) { struct virtio_device *vdev = vsock->vdev; __le64 guest_cid; + __le32 number_cid; + u32 index; - vdev->config->get(vdev, offsetof(struct virtio_vsock_config, guest_cid), - &guest_cid, sizeof(guest_cid)); - vsock->guest_cid = le64_to_cpu(guest_cid); + vdev->config->get(vdev, offsetof(struct virtio_vsock_config, number_cid), + &number_cid, sizeof(number_cid)); + vsock->number_cid = le32_to_cpu(number_cid); + + /* number_cid must be greater than 0 in the config space + * to use this feature. + */ + if (vsock->number_cid > 0) { + vsock->cids = kmalloc_array(vsock->number_cid, sizeof(u32), GFP_KERNEL); + if (!vsock->cids) { + /* Space allocated failed, reset number_cid to 0. + * only use the original guest_cid. + */ + vsock->number_cid = 0; + } + } + + for (index = 0; index < vsock->number_cid; index++) { + vdev->config->get(vdev, + offsetof(struct virtio_vsock_config, cids) + + index * sizeof(uint64_t), + &guest_cid, sizeof(guest_cid)); + vsock->cids[index] = le64_to_cpu(guest_cid); + } } /* event_lock must be held */ @@ -451,6 +505,7 @@ static struct virtio_transport virtio_transport = { .module = THIS_MODULE, .get_local_cid = virtio_transport_get_local_cid, + .contain_cid = virtio_transport_contain_cid, .init = virtio_transport_do_socket_init, .destruct = virtio_transport_destruct, @@ -594,6 +649,8 @@ static int virtio_vsock_probe(struct virtio_device *vdev) } vsock->vdev = vdev; + vsock->cids = NULL; + vsock->number_cid = 0; ret = virtio_find_vqs(vsock->vdev, VSOCK_VQ_MAX, vsock->vqs, callbacks, names, @@ -713,6 +770,7 @@ static void virtio_vsock_remove(struct virtio_device *vdev) mutex_unlock(&the_virtio_vsock_mutex); + kfree(vsock->cids); kfree(vsock); } diff --git a/net/vmw_vsock/vsock_loopback.c b/net/vmw_vsock/vsock_loopback.c index 169a8cf65b39..3abbbaff34eb 100644 --- a/net/vmw_vsock/vsock_loopback.c +++ b/net/vmw_vsock/vsock_loopback.c @@ -63,6 +63,13 @@ static int vsock_loopback_cancel_pkt(struct vsock_sock *vsk) return 0; } +static bool vsock_loopback_contain_cid(u32 cid) +{ + if (cid == VMADDR_CID_LOCAL) + return true; + return false; +} + static bool vsock_loopback_seqpacket_allow(u32 remote_cid); static struct virtio_transport loopback_transport = { @@ -70,6 +77,7 @@ static struct virtio_transport loopback_transport = { .module = THIS_MODULE, .get_local_cid = vsock_loopback_get_local_cid, + .contain_cid = vsock_loopback_contain_cid, .init = virtio_transport_do_socket_init, .destruct = virtio_transport_destruct, From patchwork Mon Aug 2 12:07:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fuguancheng X-Patchwork-Id: 490617 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73F6CC432BE for ; Mon, 2 Aug 2021 12:08:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6028360FC2 for ; Mon, 2 Aug 2021 12:08:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233665AbhHBMIW (ORCPT ); Mon, 2 Aug 2021 08:08:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233625AbhHBMIV (ORCPT ); Mon, 2 Aug 2021 08:08:21 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B658C06175F for ; Mon, 2 Aug 2021 05:08:12 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id o44-20020a17090a0a2fb0290176ca3e5a2fso24362819pjo.1 for ; Mon, 02 Aug 2021 05:08:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PTiBhSwkCea98qDiT23buvBtsb9gfJUIRj5xML15LbA=; b=AwxZLgcT65GUilQ+qYh3pNT3wt1RwBwIssNdZsmb96xmIF4qy2qHbKj72p5YlqvGkb 3gJqJbE7XUcZwunjGU5wYAiMKVXlPjAbP6FQ8QS8lrjjVLEbHweqfpCaXrcWEXzRG8C1 danBUTn83/M04FP7E6A9h3UjAB2rBbU4v85iM/flY6jKXA+r/k2iw1556oQDh4YNp8So dgvf2K+rN/17nJlEQSqiF+j8Hr3Rnjrvn2gOH8AbPVm/loLNkv9Tjyg/llBUab/+7/q3 IshikrSd0npLCkB0/0YGEVeZ419mIdS54GY8K3JxikQ04FlQkyKTdlwQipStcTFmz+DB lAuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PTiBhSwkCea98qDiT23buvBtsb9gfJUIRj5xML15LbA=; b=BvgoFQLSDjwAFe1hB2Ze5aS7wLrGm0oyFqfNXu8qxP48AwN4xV88+RuWSX5qVG2m4M czMoWnqKWKwQbIxt0V4tZ6ZqpO7NMybkXGwPrh+uSlPPmzcRmXi/tHGsZnz79OtW8ZwT lwg7X9bhlBQlsznCEGGhU4uRgW8PQS1AuialLM1fzrZaCk3VfJ814Q3soHdizVkMVjq8 /J3lrsGPGPHDIu7L/KlPfKvfXW4JODnJiQfQrNJxFPUYhw09KAbTpstVKhLLC/Jy83Ni 66Xkshh+aEQhTqb+BKTF9EdLXetxQld1meMt5WEzBgz6D547rTXCc/rI+n3LkfvEAAVD jicw== X-Gm-Message-State: AOAM531dshblZys+YMDtWv45zckB3niAQiM/2uknFPG3XOOW70GBYACn gr8JRcPV7MPHI+kVK88dHn1dsg== X-Google-Smtp-Source: ABdhPJwf7bHaKaWhpbZNiqIyyNSOA8m7JriTu91VqX/WXhlCR944DRM/Coy5lsMW8EEGuYngY4bVEQ== X-Received: by 2002:a17:902:8484:b029:101:7016:fb7b with SMTP id c4-20020a1709028484b02901017016fb7bmr13809258plo.23.1627906091423; Mon, 02 Aug 2021 05:08:11 -0700 (PDT) Received: from n248-175-059.byted.org. ([121.30.179.62]) by smtp.googlemail.com with ESMTPSA id f30sm12874867pgl.48.2021.08.02.05.08.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Aug 2021 05:08:11 -0700 (PDT) From: fuguancheng To: mst@redhat.com, jasowang@redhat.com, stefanha@redhat.com, sgarzare@redhat.com, davem@davemloft.net, kuba@kernel.org, arseny.krasnov@kaspersky.com, andraprs@amazon.com, colin.king@canonical.com Cc: kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, fuguancheng Subject: [PATCH 2/4] VSOCK DRIVER: support communication using additional guest cid Date: Mon, 2 Aug 2021 20:07:18 +0800 Message-Id: <20210802120720.547894-3-fuguancheng@bytedance.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20210802120720.547894-1-fuguancheng@bytedance.com> References: <20210802120720.547894-1-fuguancheng@bytedance.com> Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Changes in this patch are made to allow the guest communicate with the host using the additional cids specified when creating the guest. In original settings, the packet sent with the additional CIDS will be rejected when received by the host, the newly added function vhost_vsock_contain_cid will fix this error. Now that we have multiple CIDS, the VMADDR_CID_ANY now behaves like this: 1. The client will use the first available cid specified in the cids array if VMADDR_CID_ANY is used. 2. The host will still use the original default CID. 3. If a guest server binds to VMADDR_CID_ANY, then the server can choose to connect to any of the available CIDs for this guest. Signed-off-by: fuguancheng --- drivers/vhost/vsock.c | 14 +++++++++++++- net/vmw_vsock/af_vsock.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 5 ++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index f66c87de91b8..013f8ebf8189 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -74,6 +74,18 @@ struct vhost_vsock { bool seqpacket_allow; }; +static bool +vhost_vsock_contain_cid(struct vhost_vsock *vsock, u32 cid) +{ + u32 index; + + for (index = 0; index < vsock->num_cid; index++) { + if (cid == vsock->cids[index]) + return true; + } + return false; +} + static u32 vhost_transport_get_local_cid(void) { return VHOST_VSOCK_DEFAULT_HOST_CID; @@ -584,7 +596,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) /* Only accept correctly addressed packets */ if (vsock->num_cid > 0 && - (pkt->hdr.src_cid) == vsock->cids[0] && + vhost_vsock_contain_cid(vsock, pkt->hdr.src_cid) && le64_to_cpu(pkt->hdr.dst_cid) == vhost_transport_get_local_cid()) virtio_transport_recv_pkt(&vhost_transport, pkt); else diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 4e1fbe74013f..c22ae7101e55 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -251,7 +251,7 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, list_for_each_entry(vsk, vsock_connected_sockets(src, dst), connected_table) { if (vsock_addr_equals_addr(src, &vsk->remote_addr) && - dst->svm_port == vsk->local_addr.svm_port) { + vsock_addr_equals_addr(&vsk->local_addr, dst)) { return sk_vsock(vsk); } } diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 169ba8b72a63..cb45e2f801f1 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -197,7 +197,10 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, if (unlikely(!t_ops)) return -EFAULT; - src_cid = t_ops->transport.get_local_cid(); + if (vsk->local_addr.svm_cid != VMADDR_CID_ANY) + src_cid = vsk->local_addr.svm_cid; + else + src_cid = t_ops->transport.get_local_cid(); src_port = vsk->local_addr.svm_port; if (!info->remote_cid) { dst_cid = vsk->remote_addr.svm_cid; From patchwork Mon Aug 2 12:07:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fuguancheng X-Patchwork-Id: 490616 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8A73C4338F for ; Mon, 2 Aug 2021 12:08:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 88E2160FA0 for ; Mon, 2 Aug 2021 12:08:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233722AbhHBMIo (ORCPT ); Mon, 2 Aug 2021 08:08:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233676AbhHBMIf (ORCPT ); Mon, 2 Aug 2021 08:08:35 -0400 Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6DEA1C061796 for ; Mon, 2 Aug 2021 05:08:26 -0700 (PDT) Received: by mail-pl1-x630.google.com with SMTP id t3so17250454plg.9 for ; Mon, 02 Aug 2021 05:08:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=j42q5rdRZ8gBlePD6vWg8hPTNcHOSjWSlt+Ho+ufcE8=; b=UwJwUPjlDNb71qW4v0Y+K8kmjyAwvH04VEeNmg7tGkkOuSswF/yNEXYddpFCC0XJ9c 6fIn3JuZqAQXBkzx/b60j5tel3/imCLlvLyB7tC2jqffS2+Bcalqt6rw5xaVVKpLkZ9z LjZlRiL9LCaSjslKkC1oZPCMorGfIHC3uo78b2se7pFoCgGTxjaExiGm9IvecQO+zdpz YuQLqROwGIUxMALDUAhEgZ0EnJMw0nSnljq9o//n4uuT9Vo/0N5+kBmJb0C33qgGgYvh fZl6w/8FwwnWwHWI3TeKkLzdM5rLazrOPrBYSiKtEW+AarU1aQx8UL35gQr2rqp1zHBs EnFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=j42q5rdRZ8gBlePD6vWg8hPTNcHOSjWSlt+Ho+ufcE8=; b=VcSucQWG5gSQ6dj/IMdbADAlHPycznkUwu6YIVsdSQ8sE3sYJbzN8v2NFduile8/fy 1iguowFYO15g/6YZQH4HaIFw8XlxHLLfeuQT9XCMxrhVhDd7Vuodv9VS2gJNYKb5Y3B/ U/fUalvc8ZylVOBaTBLBkXmPLI0lUUWOw1ihsNFfS4zA29rwN/7G+rvkLdEbxXHlQQBM hntOHrpE4lwN+DOxXtVQ5EOy45W7SfToTNcktTx6DHTXJBDMpjuAoO8kob52Uk725qvO HmAtNsTAw5Oi7LjlibmJNC619Wd3S6Z+8lL1vT1e/CmOwExi6EpRtH2CoKTkvX/n6Oao P3WQ== X-Gm-Message-State: AOAM532/me3/7N6Yraq1s65d2nLTVamrIWnhhBQp39YEpMUvYaQw/MFf YcrQJsNFQoI3eHNU+ocoa9Q21A== X-Google-Smtp-Source: ABdhPJyWEyx8aChLggqRUs8fOfQ650EJoTGy+jTjblU9JsWLXnlVzZKnHrFbberN8DpROD+/drzUxQ== X-Received: by 2002:a17:902:c20c:b029:12c:afb8:fad2 with SMTP id 12-20020a170902c20cb029012cafb8fad2mr6139991pll.19.1627906105954; Mon, 02 Aug 2021 05:08:25 -0700 (PDT) Received: from n248-175-059.byted.org. ([121.30.179.62]) by smtp.googlemail.com with ESMTPSA id f30sm12874867pgl.48.2021.08.02.05.08.22 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Aug 2021 05:08:25 -0700 (PDT) From: fuguancheng To: mst@redhat.com, jasowang@redhat.com, stefanha@redhat.com, sgarzare@redhat.com, davem@davemloft.net, kuba@kernel.org, arseny.krasnov@kaspersky.com, andraprs@amazon.com, colin.king@canonical.com Cc: kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, fuguancheng Subject: [PATCH 4/4] VSOCK DRIVER: support communication using host additional cids Date: Mon, 2 Aug 2021 20:07:20 +0800 Message-Id: <20210802120720.547894-5-fuguancheng@bytedance.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20210802120720.547894-1-fuguancheng@bytedance.com> References: <20210802120720.547894-1-fuguancheng@bytedance.com> Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch allows the user to use the additional host CIDS to communicate with the guest. As server, the host can bind to any CIDS as long as the cid can be mapped to one guest. The VHOST_DEFAULT_CID can be used as normal. As client, when connect to a remote server, if no address is specified to be used, then it will use the first cid in the array. If the user wants to use a specific cid, then the user can perfrom bind before the connect operation, so that vsock_auto_bind will not be performed. The patch depends on the previous patch which enables hypervisors such as qemu to specify multiple cids for host and guest. Signed-off-by: fuguancheng --- drivers/vhost/vsock.c | 39 ++++++++++++++++++++++++++++++++++++++- include/net/af_vsock.h | 4 ++++ net/vmw_vsock/af_vsock.c | 20 ++++++++++++++------ net/vmw_vsock/virtio_transport.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index f5d9b9f06ba5..104fcdea2dd7 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -57,8 +57,22 @@ struct vhost_vsock_ref { static bool vhost_transport_contain_cid(u32 cid) { + unsigned int index; + struct vhost_vsock_ref *ref; + if (cid == VHOST_VSOCK_DEFAULT_HOST_CID) return true; + + mutex_lock(&valid_host_mutex); + hash_for_each(valid_host_hash, index, ref, ref_hash) { + u32 other_cid = ref->cid; + + if (other_cid == cid) { + mutex_unlock(&valid_host_mutex); + return true; + } + } + mutex_unlock(&valid_host_mutex); return false; } @@ -101,6 +115,21 @@ vhost_vsock_contain_cid(struct vhost_vsock *vsock, u32 cid) return false; } +/* Check if a cid is valid for the pkt to be received. */ +static bool +vhost_vsock_contain_host_cid(struct vhost_vsock *vsock, u32 dst_cid) +{ + uint32_t index; + + if (dst_cid == VHOST_VSOCK_DEFAULT_HOST_CID) + return true; + for (index = 0; index < vsock->num_host_cid; index++) { + if (vsock->hostcids[index] == dst_cid) + return true; + } + return false; +} + static u32 vhost_transport_get_local_cid(void) { return VHOST_VSOCK_DEFAULT_HOST_CID; @@ -128,6 +157,13 @@ static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) return NULL; } +/* This function checks if the cid is used by one of the guests. */ +static bool +vhost_transport_contain_opposite_cid(u32 cid) +{ + return vhost_vsock_get(cid) != NULL; +} + /* Callers that dereference the return value must hold vhost_vsock_mutex or the * RCU read lock. */ @@ -512,6 +548,7 @@ static struct virtio_transport vhost_transport = { .get_local_cid = vhost_transport_get_local_cid, .contain_cid = vhost_transport_contain_cid, + .contain_opposite_cid = vhost_transport_contain_opposite_cid, .init = virtio_transport_do_socket_init, .destruct = virtio_transport_destruct, @@ -629,7 +666,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) /* Only accept correctly addressed packets */ if (vsock->num_cid > 0 && vhost_vsock_contain_cid(vsock, pkt->hdr.src_cid) && - le64_to_cpu(pkt->hdr.dst_cid) == vhost_transport_get_local_cid()) + vhost_vsock_contain_host_cid(vsock, le64_to_cpu(pkt->hdr.dst_cid))) virtio_transport_recv_pkt(&vhost_transport, pkt); else virtio_transport_free_pkt(pkt); diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index d0fc08fb9cac..739ac9aaff8f 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -171,6 +171,10 @@ struct vsock_transport { /* Addressing. */ u32 (*get_local_cid)(void); bool (*contain_cid)(u32 cid); + /* For transport_g2h, this checks if the cid is used by its host. */ + /* For transport_h2g, this checks if the cid is used by one of its guests. */ + /* This function is set to NULL for loopback_transport. */ + bool (*contain_opposite_cid)(u32 cid); }; /**** CORE ****/ diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index c22ae7101e55..d3037ee885be 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -397,9 +397,9 @@ static bool vsock_use_local_transport(unsigned int remote_cid) return true; if (transport_g2h) { - return remote_cid == transport_g2h->get_local_cid(); + return transport_g2h->contain_cid(remote_cid); } else { - return remote_cid == VMADDR_CID_HOST; + return transport_h2g->contain_cid(remote_cid); } } @@ -423,7 +423,9 @@ static void vsock_deassign_transport(struct vsock_sock *vsk) * g2h is not loaded, will use local transport; * - remote CID <= VMADDR_CID_HOST or h2g is not loaded or remote flags field * includes VMADDR_FLAG_TO_HOST flag value, will use guest->host transport; - * - remote CID > VMADDR_CID_HOST will use host->guest transport; + * - remote CID > VMADDR_CID_HOST will use host->guest transport if + * guest->host transport is not loaded. Otherwise, if guest->host transport + * contains the remote_cid, then use the guest->host transport. */ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) { @@ -434,15 +436,18 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) int ret; /* If the packet is coming with the source and destination CIDs higher - * than VMADDR_CID_HOST, then a vsock channel where all the packets are + * than VMADDR_CID_HOST, and the source and destination CIDs are not + * used by the host, then a vsock channel where all the packets are * forwarded to the host should be established. Then the host will * need to forward the packets to the guest. * * The flag is set on the (listen) receive path (psk is not NULL). On * the connect path the flag can be set by the user space application. */ - if (psk && vsk->local_addr.svm_cid > VMADDR_CID_HOST && - vsk->remote_addr.svm_cid > VMADDR_CID_HOST) + if (psk && transport_h2g && vsk->local_addr.svm_cid > VMADDR_CID_HOST && + !transport_h2g->contain_cid(vsk->local_addr.svm_cid) && + vsk->remote_addr.svm_cid > VMADDR_CID_HOST && + !transport_h2g->contain_cid(vsk->remote_addr.svm_cid)) vsk->remote_addr.svm_flags |= VMADDR_FLAG_TO_HOST; remote_flags = vsk->remote_addr.svm_flags; @@ -458,6 +463,9 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) else if (remote_cid <= VMADDR_CID_HOST || !transport_h2g || (remote_flags & VMADDR_FLAG_TO_HOST)) new_transport = transport_g2h; + else if (remote_cid > VMADDR_CID_HOST && transport_g2h && + transport_g2h->contain_opposite_cid(remote_cid)) + new_transport = transport_g2h; else new_transport = transport_h2g; break; diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index c552bc60e539..0c4a2f03318c 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -99,6 +99,35 @@ static bool virtio_transport_contain_cid(u32 cid) return ret; } +/* This function checks if the transport_g2h is using the cid. */ +static bool virtio_transport_contain_opposite_cid(u32 cid) +{ + struct virtio_vsock *vsock; + bool ret; + u32 num_host_cid; + + if (cid == VMADDR_CID_HOST) + return true; + num_host_cid = 0; + rcu_read_lock(); + vsock = rcu_dereference(the_virtio_vsock); + if (!vsock || vsock->number_host_cid == 0) { + ret = false; + goto out_rcu; + } + + for (num_host_cid = 0; num_host_cid < vsock->number_host_cid; num_host_cid++) { + if (vsock->host_cids[num_host_cid] == cid) { + ret = true; + goto out_rcu; + } + } + ret = false; +out_rcu: + rcu_read_unlock(); + return ret; +} + static u32 virtio_transport_get_local_cid(void) { struct virtio_vsock *vsock; @@ -532,6 +561,7 @@ static struct virtio_transport virtio_transport = { .get_local_cid = virtio_transport_get_local_cid, .contain_cid = virtio_transport_contain_cid, + .contain_opposite_cid = virtio_transport_contain_opposite_cid, .init = virtio_transport_do_socket_init, .destruct = virtio_transport_destruct,