在 2022/1/17 下午5:29, Longpeng(Mike) 写道:
From: Longpeng <longpe...@huawei.com>

Introduces the control virtqueue support for vdpasim_net, based on
Jason's RFC [1].

[1] 
https://patchwork.kernel.org/project/kvm/patch/20200924032125.18619-25-jasow...@redhat.com/


I'd expect to implement the receive filter as well[1]. This gives us a chance to test this.

Thanks

[1] https://lkml.org/lkml/2020/9/23/1269



Signed-off-by: Longpeng <longpe...@huawei.com>
---
  drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 83 +++++++++++++++++++++++++++-
  1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c 
b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
index 76dd24abc791..e9e388fd3cff 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
@@ -26,9 +26,85 @@
  #define DRV_LICENSE  "GPL v2"
#define VDPASIM_NET_FEATURES (VDPASIM_FEATURES | \
-                                (1ULL << VIRTIO_NET_F_MAC))
+                                (1ULL << VIRTIO_NET_F_MAC) | \
+                                (1ULL << VIRTIO_NET_F_CTRL_VQ) | \
+                                (1ULL << VIRTIO_NET_F_CTRL_MAC_ADDR))
-#define VDPASIM_NET_VQ_NUM 2
+#define VDPASIM_NET_VQ_NUM     3
+
+virtio_net_ctrl_ack vdpasim_net_handle_ctrl_mac(struct vdpasim *vdpasim,
+                                               u8 cmd)
+{
+       struct vdpasim_virtqueue *cvq = &vdpasim->vqs[2];
+       virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
+       struct virtio_net_config *config = vdpasim->config;
+       size_t read;
+
+       switch (cmd) {
+       case VIRTIO_NET_CTRL_MAC_ADDR_SET:
+               read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->out_iov,
+                                            (void *)config->mac, ETH_ALEN);
+               if (read == ETH_ALEN)
+                       status = VIRTIO_NET_OK;
+               break;
+       default:
+               break;
+       }
+
+       return status;
+}
+
+static void vdpasim_net_handle_cvq(struct vdpasim *vdpasim)
+{
+       struct vdpasim_virtqueue *cvq = &vdpasim->vqs[2];
+       virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
+       struct virtio_net_ctrl_hdr ctrl;
+       size_t read, write;
+       int err;
+
+       if (!(vdpasim->features & (1ULL << VIRTIO_NET_F_CTRL_VQ)))
+               return;
+
+       if (!cvq->ready)
+               return;
+
+       while (true) {
+               err = vringh_getdesc_iotlb(&cvq->vring, &cvq->out_iov, 
&cvq->in_iov,
+                                          &cvq->head, GFP_ATOMIC);
+               if (err <= 0)
+                       break;
+
+               read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->in_iov, &ctrl,
+                                            sizeof(ctrl));
+               if (read != sizeof(ctrl))
+                       break;
+
+               switch (ctrl.class) {
+               case VIRTIO_NET_CTRL_MAC:
+                       status = vdpasim_net_handle_ctrl_mac(vdpasim, ctrl.cmd);
+                       break;
+               default:
+                       break;
+               }
+
+               /* Make sure data is wrote before advancing index */
+               smp_wmb();
+
+               write = vringh_iov_push_iotlb(&cvq->vring, &cvq->out_iov,
+                                             &status, sizeof (status));
+               vringh_complete_iotlb(&cvq->vring, cvq->head, write);
+               vringh_kiov_cleanup(&cvq->in_iov);
+               vringh_kiov_cleanup(&cvq->out_iov);
+
+               /* Make sure used is visible before rasing the interrupt. */
+               smp_wmb();
+
+               local_bh_disable();
+               if (vringh_need_notify_iotlb(&cvq->vring) > 0)
+                       vringh_notify(&cvq->vring);
+               local_bh_enable();
+       }
+}
static void vdpasim_net_work(struct work_struct *work)
  {
@@ -42,6 +118,9 @@ static void vdpasim_net_work(struct work_struct *work)
spin_lock(&vdpasim->lock); + /* process ctrl vq first */
+       vdpasim_net_handle_cvq(vdpasim);
+
        if (!(vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK))
                goto out;

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to