/*
 * vhost-vdpa.c
 *
 * Copyright(c) 2017-2018 Intel Corporation.
 * Copyright(c) 2020 Red Hat, Inc.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "clients.h"
#include "hw/virtio/virtio-net.h"
#include "net/vhost_net.h"
#include "net/vhost-vdpa.h"
#include "hw/virtio/vhost-vdpa.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/memalign.h"
#include "qemu/option.h"
#include "qapi/error.h"
#include <linux/vhost.h>
#include <sys/ioctl.h>
#include <err.h>
#include "standard-headers/linux/virtio_net.h"
#include "monitor/monitor.h"
#include "migration/misc.h"
#include "hw/virtio/vhost.h"
#include "trace.h"

/* Todo:need to add the multiqueue support here */
typedef struct VhostVDPAState {
    NetClientState nc;
    struct vhost_vdpa vhost_vdpa;
    NotifierWithReturn migration_state;
    VHostNetState *vhost_net;

    /* Control commands shadow buffers */
    void *cvq_cmd_out_buffer;
    virtio_net_ctrl_ack *status;

    /* The device always have SVQ enabled */
    bool always_svq;

    /* The device can isolate CVQ in its own ASID */
    bool cvq_isolated;

    bool started;
} VhostVDPAState;

/*
 * The array is sorted alphabetically in ascending order,
 * with the exception of VHOST_INVALID_FEATURE_BIT,
 * which should always be the last entry.
 */
const int vdpa_feature_bits[] = {
    VIRTIO_F_ANY_LAYOUT,
    VIRTIO_F_IOMMU_PLATFORM,
    VIRTIO_F_NOTIFY_ON_EMPTY,
    VIRTIO_F_RING_PACKED,
    VIRTIO_F_RING_RESET,
    VIRTIO_F_VERSION_1,
    VIRTIO_F_IN_ORDER,
    VIRTIO_F_NOTIFICATION_DATA,
    VIRTIO_NET_F_CSUM,
    VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
    VIRTIO_NET_F_CTRL_MAC_ADDR,
    VIRTIO_NET_F_CTRL_RX,
    VIRTIO_NET_F_CTRL_RX_EXTRA,
    VIRTIO_NET_F_CTRL_VLAN,
    VIRTIO_NET_F_CTRL_VQ,
    VIRTIO_NET_F_GSO,
    VIRTIO_NET_F_GUEST_CSUM,
    VIRTIO_NET_F_GUEST_ECN,
    VIRTIO_NET_F_GUEST_TSO4,
    VIRTIO_NET_F_GUEST_TSO6,
    VIRTIO_NET_F_GUEST_UFO,
    VIRTIO_NET_F_GUEST_USO4,
    VIRTIO_NET_F_GUEST_USO6,
    VIRTIO_NET_F_HASH_REPORT,
    VIRTIO_NET_F_HOST_ECN,
    VIRTIO_NET_F_HOST_TSO4,
    VIRTIO_NET_F_HOST_TSO6,
    VIRTIO_NET_F_HOST_UFO,
    VIRTIO_NET_F_HOST_USO,
    VIRTIO_NET_F_MQ,
    VIRTIO_NET_F_MRG_RXBUF,
    VIRTIO_NET_F_MTU,
    VIRTIO_NET_F_RSC_EXT,
    VIRTIO_NET_F_RSS,
    VIRTIO_NET_F_STATUS,
    VIRTIO_RING_F_EVENT_IDX,
    VIRTIO_RING_F_INDIRECT_DESC,

    /* VHOST_INVALID_FEATURE_BIT should always be the last entry */
    VHOST_INVALID_FEATURE_BIT
};

/** Supported device specific feature bits with SVQ */
static const uint64_t vdpa_svq_device_features =
    BIT_ULL(VIRTIO_NET_F_CSUM) |
    BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) |
    BIT_ULL(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) |
    BIT_ULL(VIRTIO_NET_F_MTU) |
    BIT_ULL(VIRTIO_NET_F_MAC) |
    BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) |
    BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) |
    BIT_ULL(VIRTIO_NET_F_GUEST_ECN) |
    BIT_ULL(VIRTIO_NET_F_GUEST_UFO) |
    BIT_ULL(VIRTIO_NET_F_HOST_TSO4) |
    BIT_ULL(VIRTIO_NET_F_HOST_TSO6) |
    BIT_ULL(VIRTIO_NET_F_HOST_ECN) |
    BIT_ULL(VIRTIO_NET_F_HOST_UFO) |
    BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) |
    BIT_ULL(VIRTIO_NET_F_STATUS) |
    BIT_ULL(VIRTIO_NET_F_CTRL_VQ) |
    BIT_ULL(VIRTIO_NET_F_CTRL_RX) |
    BIT_ULL(VIRTIO_NET_F_CTRL_VLAN) |
    BIT_ULL(VIRTIO_NET_F_CTRL_RX_EXTRA) |
    BIT_ULL(VIRTIO_NET_F_MQ) |
    BIT_ULL(VIRTIO_F_ANY_LAYOUT) |
    BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) |
    /* VHOST_F_LOG_ALL is exposed by SVQ */
    BIT_ULL(VHOST_F_LOG_ALL) |
    BIT_ULL(VIRTIO_NET_F_HASH_REPORT) |
    BIT_ULL(VIRTIO_NET_F_RSS) |
    BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
    BIT_ULL(VIRTIO_NET_F_STANDBY) |
    BIT_ULL(VIRTIO_NET_F_SPEED_DUPLEX);

#define VHOST_VDPA_NET_CVQ_ASID 1

VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
    return s->vhost_net;
}

static size_t vhost_vdpa_net_cvq_cmd_len(void)
{
    /*
     * MAC_TABLE_SET is the ctrl command that produces the longer out buffer.
     * In buffer is always 1 byte, so it should fit here
     */
    return sizeof(struct virtio_net_ctrl_hdr) +
           2 * sizeof(struct virtio_net_ctrl_mac) +
           MAC_TABLE_ENTRIES * ETH_ALEN;
}

static size_t vhost_vdpa_net_cvq_cmd_page_len(void)
{
    return ROUND_UP(vhost_vdpa_net_cvq_cmd_len(), qemu_real_host_page_size());
}

static bool vhost_vdpa_net_valid_svq_features(uint64_t features, Error **errp)
{
    uint64_t invalid_dev_features =
        features & ~vdpa_svq_device_features &
        /* Transport are all accepted at this point */
        ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START,
                         VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START);

    if (invalid_dev_features) {
        error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64,
                   invalid_dev_features);
        return false;
    }

    return vhost_svq_valid_features(features, errp);
}

static int vhost_vdpa_net_check_device_id(struct vhost_net *net)
{
    uint32_t device_id;
    int ret;
    struct vhost_dev *hdev;

    hdev = (struct vhost_dev *)&net->dev;
    ret = hdev->vhost_ops->vhost_get_device_id(hdev, &device_id);
    if (device_id != VIRTIO_ID_NET) {
        return -ENOTSUP;
    }
    return ret;
}

static int vhost_vdpa_add(NetClientState *ncs, void *be,
                          int queue_pair_index, int nvqs)
{
    VhostNetOptions options;
    struct vhost_net *net = NULL;
    VhostVDPAState *s;
    int ret;

    options.backend_type = VHOST_BACKEND_TYPE_VDPA;
    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
    s = DO_UPCAST(VhostVDPAState, nc, ncs);
    options.net_backend = ncs;
    options.opaque      = be;
    options.busyloop_timeout = 0;
    options.nvqs = nvqs;

    net = vhost_net_init(&options);
    if (!net) {
        error_report("failed to init vhost_net for queue");
        goto err_init;
    }
    s->vhost_net = net;
    ret = vhost_vdpa_net_check_device_id(net);
    if (ret) {
        goto err_check;
    }
    return 0;
err_check:
    vhost_net_cleanup(net);
    g_free(net);
err_init:
    return -1;
}

static void vhost_vdpa_cleanup(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);

    munmap(s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_page_len());
    munmap(s->status, vhost_vdpa_net_cvq_cmd_page_len());
    if (s->vhost_net) {
        vhost_net_cleanup(s->vhost_net);
        g_free(s->vhost_net);
        s->vhost_net = NULL;
    }
    if (s->vhost_vdpa.index != 0) {
        return;
    }
    qemu_close(s->vhost_vdpa.shared->device_fd);
    g_free(s->vhost_vdpa.shared);
}

/** Dummy SetSteeringEBPF to support RSS for vhost-vdpa backend  */
static bool vhost_vdpa_set_steering_ebpf(NetClientState *nc, int prog_fd)
{
    return true;
}

static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc)
{
    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

    return true;
}

static bool vhost_vdpa_has_ufo(NetClientState *nc)
{
    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
    uint64_t features = 0;
    features |= (1ULL << VIRTIO_NET_F_HOST_UFO);
    features = vhost_net_get_features(s->vhost_net, features);
    return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO));

}

/*
 * FIXME: vhost_vdpa doesn't have an API to "set h/w endianness". But it's
 * reasonable to assume that h/w is LE by default, because LE is what
 * virtio 1.0 and later ask for. So, this function just says "yes, the h/w is
 * LE". Otherwise, on a BE machine, higher-level code would mistakely think
 * the h/w is BE and can't support VDPA for a virtio 1.0 client.
 */
static int vhost_vdpa_set_vnet_le(NetClientState *nc, bool enable)
{
    return 0;
}

static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc,
                                       Error **errp)
{
    const char *driver = object_class_get_name(oc);

    if (!g_str_has_prefix(driver, "virtio-net-")) {
        error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*");
        return false;
    }

    return true;
}

/** Dummy receive in case qemu falls back to userland tap networking */
static ssize_t vhost_vdpa_receive(NetClientState *nc, const uint8_t *buf,
                                  size_t size)
{
    return size;
}


/** From any vdpa net client, get the netclient of the i-th queue pair */
static VhostVDPAState *vhost_vdpa_net_get_nc_vdpa(VhostVDPAState *s, int i)
{
    NICState *nic = qemu_get_nic(s->nc.peer);
    NetClientState *nc_i = qemu_get_peer(nic->ncs, i);

    return DO_UPCAST(VhostVDPAState, nc, nc_i);
}

static VhostVDPAState *vhost_vdpa_net_first_nc_vdpa(VhostVDPAState *s)
{
    return vhost_vdpa_net_get_nc_vdpa(s, 0);
}

static void vhost_vdpa_net_log_global_enable(VhostVDPAState *s, bool enable)
{
    struct vhost_vdpa *v = &s->vhost_vdpa;
    VirtIONet *n;
    VirtIODevice *vdev;
    int data_queue_pairs, cvq, r;

    /* We are only called on the first data vqs and only if x-svq is not set */
    if (s->vhost_vdpa.shadow_vqs_enabled == enable) {
        return;
    }

    vdev = v->dev->vdev;
    n = VIRTIO_NET(vdev);
    if (!n->vhost_started) {
        return;
    }

    data_queue_pairs = n->multiqueue ? n->max_queue_pairs : 1;
    cvq = virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ) ?
                                  n->max_ncs - n->max_queue_pairs : 0;
    v->shared->svq_switching = enable ?
        SVQ_TSTATE_ENABLING : SVQ_TSTATE_DISABLING;
    /*
     * TODO: vhost_net_stop does suspend, get_base and reset. We can be smarter
     * in the future and resume the device if read-only operations between
     * suspend and reset goes wrong.
     */
    vhost_net_stop(vdev, n->nic->ncs, data_queue_pairs, cvq);

    /* Start will check migration setup_or_active to configure or not SVQ */
    r = vhost_net_start(vdev, n->nic->ncs, data_queue_pairs, cvq);
    if (unlikely(r < 0)) {
        error_report("unable to start vhost net: %s(%d)", g_strerror(-r), -r);
    }
    v->shared->svq_switching = SVQ_TSTATE_DONE;
}

static int vdpa_net_migration_state_notifier(NotifierWithReturn *notifier,
                                             MigrationEvent *e, Error **errp)
{
    VhostVDPAState *s = container_of(notifier, VhostVDPAState, migration_state);

    if (e->type == MIG_EVENT_PRECOPY_SETUP) {
        vhost_vdpa_net_log_global_enable(s, true);
    } else if (e->type == MIG_EVENT_PRECOPY_FAILED) {
        vhost_vdpa_net_log_global_enable(s, false);
    }
    return 0;
}

static void vhost_vdpa_net_data_start_first(VhostVDPAState *s)
{
    struct vhost_vdpa *v = &s->vhost_vdpa;

    migration_add_notifier(&s->migration_state,
                           vdpa_net_migration_state_notifier);
    if (v->shadow_vqs_enabled) {
        v->shared->iova_tree = vhost_iova_tree_new(v->shared->iova_range.first,
                                                   v->shared->iova_range.last);
    }
}

static int vhost_vdpa_net_data_start(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
    struct vhost_vdpa *v = &s->vhost_vdpa;

    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

    if (s->always_svq || migration_is_running()) {
        v->shadow_vqs_enabled = true;
    } else {
        v->shadow_vqs_enabled = false;
    }

    if (v->index == 0) {
        v->shared->shadow_data = v->shadow_vqs_enabled;
        vhost_vdpa_net_data_start_first(s);
        return 0;
    }

    return 0;
}

static int vhost_vdpa_net_data_load(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
    struct vhost_vdpa *v = &s->vhost_vdpa;
    bool has_cvq = v->dev->vq_index_end % 2;

    if (has_cvq) {
        return 0;
    }

    for (int i = 0; i < v->dev->nvqs; ++i) {
        int ret = vhost_vdpa_set_vring_ready(v, i + v->dev->vq_index);
        if (ret < 0) {
            return ret;
        }
    }
    return 0;
}

static void vhost_vdpa_net_client_stop(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
    struct vhost_dev *dev;

    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

    if (s->vhost_vdpa.index == 0) {
        migration_remove_notifier(&s->migration_state);
    }

    dev = s->vhost_vdpa.dev;
    if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
        g_clear_pointer(&s->vhost_vdpa.shared->iova_tree,
                        vhost_iova_tree_delete);
    }
}

static NetClientInfo net_vhost_vdpa_info = {
        .type = NET_CLIENT_DRIVER_VHOST_VDPA,
        .size = sizeof(VhostVDPAState),
        .receive = vhost_vdpa_receive,
        .start = vhost_vdpa_net_data_start,
        .load = vhost_vdpa_net_data_load,
        .stop = vhost_vdpa_net_client_stop,
        .cleanup = vhost_vdpa_cleanup,
        .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
        .has_ufo = vhost_vdpa_has_ufo,
        .set_vnet_le = vhost_vdpa_set_vnet_le,
        .check_peer_type = vhost_vdpa_check_peer_type,
        .set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
};

static int64_t vhost_vdpa_get_vring_group(int device_fd, unsigned vq_index,
                                          Error **errp)
{
    struct vhost_vring_state state = {
        .index = vq_index,
    };
    int r = ioctl(device_fd, VHOST_VDPA_GET_VRING_GROUP, &state);

    if (unlikely(r < 0)) {
        r = -errno;
        error_setg_errno(errp, errno, "Cannot get VQ %u group", vq_index);
        return r;
    }

    return state.num;
}

static int vhost_vdpa_set_address_space_id(struct vhost_vdpa *v,
                                           unsigned vq_group,
                                           unsigned asid_num)
{
    struct vhost_vring_state asid = {
        .index = vq_group,
        .num = asid_num,
    };
    int r;

    trace_vhost_vdpa_set_address_space_id(v, vq_group, asid_num);

    r = ioctl(v->shared->device_fd, VHOST_VDPA_SET_GROUP_ASID, &asid);
    if (unlikely(r < 0)) {
        error_report("Can't set vq group %u asid %u, errno=%d (%s)",
                     asid.index, asid.num, errno, g_strerror(errno));
    }
    return r;
}

static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr)
{
    VhostIOVATree *tree = v->shared->iova_tree;
    DMAMap needle = {
        /*
         * No need to specify size or to look for more translations since
         * this contiguous chunk was allocated by us.
         */
        .translated_addr = (hwaddr)(uintptr_t)addr,
    };
    const DMAMap *map = vhost_iova_tree_find_iova(tree, &needle);
    int r;

    if (unlikely(!map)) {
        error_report("Cannot locate expected map");
        return;
    }

    r = vhost_vdpa_dma_unmap(v->shared, v->address_space_id, map->iova,
                             map->size + 1);
    if (unlikely(r != 0)) {
        error_report("Device cannot unmap: %s(%d)", g_strerror(r), r);
    }

    vhost_iova_tree_remove(tree, *map);
}

/** Map CVQ buffer. */
static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size,
                                  bool write)
{
    DMAMap map = {};
    hwaddr taddr = (hwaddr)(uintptr_t)buf;
    int r;

    map.size = size - 1;
    map.perm = write ? IOMMU_RW : IOMMU_RO,
    r = vhost_iova_tree_map_alloc(v->shared->iova_tree, &map, taddr);
    if (unlikely(r != IOVA_OK)) {
        error_report("Cannot map injected element");

        if (map.translated_addr == taddr) {
            error_report("Insertion to IOVA->HVA tree failed");
            /* Remove the mapping from the IOVA-only tree */
            goto dma_map_err;
        }
        return r;
    }

    r = vhost_vdpa_dma_map(v->shared, v->address_space_id, map.iova,
                           vhost_vdpa_net_cvq_cmd_page_len(), buf, !write);
    if (unlikely(r < 0)) {
        goto dma_map_err;
    }

    return 0;

dma_map_err:
    vhost_iova_tree_remove(v->shared->iova_tree, map);
    return r;
}

static int vhost_vdpa_net_cvq_start(NetClientState *nc)
{
    VhostVDPAState *s, *s0;
    struct vhost_vdpa *v;
    int64_t cvq_group;
    int r;
    Error *err = NULL;

    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

    s = DO_UPCAST(VhostVDPAState, nc, nc);
    v = &s->vhost_vdpa;

    s0 = vhost_vdpa_net_first_nc_vdpa(s);
    v->shadow_vqs_enabled = s0->vhost_vdpa.shadow_vqs_enabled;
    s->vhost_vdpa.address_space_id = VHOST_VDPA_GUEST_PA_ASID;

    if (v->shared->shadow_data) {
        /* SVQ is already configured for all virtqueues */
        goto out;
    }

    /*
     * If we early return in these cases SVQ will not be enabled. The migration
     * will be blocked as long as vhost-vdpa backends will not offer _F_LOG.
     */
    if (!vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) {
        return 0;
    }

    if (!s->cvq_isolated) {
        return 0;
    }

    cvq_group = vhost_vdpa_get_vring_group(v->shared->device_fd,
                                           v->dev->vq_index_end - 1,
                                           &err);
    if (unlikely(cvq_group < 0)) {
        error_report_err(err);
        return cvq_group;
    }

    r = vhost_vdpa_set_address_space_id(v, cvq_group, VHOST_VDPA_NET_CVQ_ASID);
    if (unlikely(r < 0)) {
        return r;
    }

    v->shadow_vqs_enabled = true;
    s->vhost_vdpa.address_space_id = VHOST_VDPA_NET_CVQ_ASID;

out:
    if (!s->vhost_vdpa.shadow_vqs_enabled) {
        return 0;
    }

    /*
     * If other vhost_vdpa already have an iova_tree, reuse it for simplicity,
     * whether CVQ shares ASID with guest or not, because:
     * - Memory listener need access to guest's memory addresses allocated in
     *   the IOVA tree.
     * - There should be plenty of IOVA address space for both ASID not to
     *   worry about collisions between them.  Guest's translations are still
     *   validated with virtio virtqueue_pop so there is no risk for the guest
     *   to access memory that it shouldn't.
     *
     * To allocate a iova tree per ASID is doable but it complicates the code
     * and it is not worth it for the moment.
     */
    if (!v->shared->iova_tree) {
        v->shared->iova_tree = vhost_iova_tree_new(v->shared->iova_range.first,
                                                   v->shared->iova_range.last);
    }

    r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer,
                               vhost_vdpa_net_cvq_cmd_page_len(), false);
    if (unlikely(r < 0)) {
        return r;
    }

    r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->status,
                               vhost_vdpa_net_cvq_cmd_page_len(), true);
    if (unlikely(r < 0)) {
        vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
    }

    return r;
}

static void vhost_vdpa_net_cvq_stop(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);

    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

    if (s->vhost_vdpa.shadow_vqs_enabled) {
        vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
        vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->status);
    }

    vhost_vdpa_net_client_stop(nc);
}

static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s,
                                    const struct iovec *out_sg, size_t out_num,
                                    const struct iovec *in_sg, size_t in_num)
{
    VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0);
    int r;

    r = vhost_svq_add(svq, out_sg, out_num, NULL, in_sg, in_num, NULL, NULL);
    if (unlikely(r != 0)) {
        if (unlikely(r == -ENOSPC)) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n",
                          __func__);
        }
    }

    return r;
}

/*
 * Convenience wrapper to poll SVQ for multiple control commands.
 *
 * Caller should hold the BQL when invoking this function, and should take
 * the answer before SVQ pulls by itself when BQL is released.
 */
static ssize_t vhost_vdpa_net_svq_poll(VhostVDPAState *s, size_t cmds_in_flight)
{
    VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0);
    return vhost_svq_poll(svq, cmds_in_flight);
}

static void vhost_vdpa_net_load_cursor_reset(VhostVDPAState *s,
                                             struct iovec *out_cursor,
                                             struct iovec *in_cursor)
{
    /* reset the cursor of the output buffer for the device */
    out_cursor->iov_base = s->cvq_cmd_out_buffer;
    out_cursor->iov_len = vhost_vdpa_net_cvq_cmd_page_len();

    /* reset the cursor of the in buffer for the device */
    in_cursor->iov_base = s->status;
    in_cursor->iov_len = vhost_vdpa_net_cvq_cmd_page_len();
}

/*
 * Poll SVQ for multiple pending control commands and check the device's ack.
 *
 * Caller should hold the BQL when invoking this function.
 *
 * @s: The VhostVDPAState
 * @len: The length of the pending status shadow buffer
 */
static ssize_t vhost_vdpa_net_svq_flush(VhostVDPAState *s, size_t len)
{
    /* device uses a one-byte length ack for each control command */
    ssize_t dev_written = vhost_vdpa_net_svq_poll(s, len);
    if (unlikely(dev_written != len)) {
        return -EIO;
    }

    /* check the device's ack */
    for (int i = 0; i < len; ++i) {
        if (s->status[i] != VIRTIO_NET_OK) {
            return -EIO;
        }
    }
    return 0;
}

static ssize_t vhost_vdpa_net_load_cmd(VhostVDPAState *s,
                                       struct iovec *out_cursor,
                                       struct iovec *in_cursor, uint8_t class,
                                       uint8_t cmd, const struct iovec *data_sg,
                                       size_t data_num)
{
    const struct virtio_net_ctrl_hdr ctrl = {
        .class = class,
        .cmd = cmd,
    };
    size_t data_size = iov_size(data_sg, data_num), cmd_size;
    struct iovec out, in;
    ssize_t r;
    unsigned dummy_cursor_iov_cnt;
    VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0);

    assert(data_size < vhost_vdpa_net_cvq_cmd_page_len() - sizeof(ctrl));
    cmd_size = sizeof(ctrl) + data_size;
    trace_vhost_vdpa_net_load_cmd(s, class, cmd, data_num, data_size);
    if (vhost_svq_available_slots(svq) < 2 ||
        iov_size(out_cursor, 1) < cmd_size) {
        /*
         * It is time to flush all pending control commands if SVQ is full
         * or control commands shadow buffers are full.
         *
         * We can poll here since we've had BQL from the time
         * we sent the descriptor.
         */
        r = vhost_vdpa_net_svq_flush(s, in_cursor->iov_base -
                                     (void *)s->status);
        if (unlikely(r < 0)) {
            return r;
        }

        vhost_vdpa_net_load_cursor_reset(s, out_cursor, in_cursor);
    }

    /* pack the CVQ command header */
    iov_from_buf(out_cursor, 1, 0, &ctrl, sizeof(ctrl));
    /* pack the CVQ command command-specific-data */
    iov_to_buf(data_sg, data_num, 0,
               out_cursor->iov_base + sizeof(ctrl), data_size);

    /* extract the required buffer from the cursor for output */
    iov_copy(&out, 1, out_cursor, 1, 0, cmd_size);
    /* extract the required buffer from the cursor for input */
    iov_copy(&in, 1, in_cursor, 1, 0, sizeof(*s->status));

    r = vhost_vdpa_net_cvq_add(s, &out, 1, &in, 1);
    if (unlikely(r < 0)) {
        trace_vhost_vdpa_net_load_cmd_retval(s, class, cmd, r);
        return r;
    }

    /* iterate the cursors */
    dummy_cursor_iov_cnt = 1;
    iov_discard_front(&out_cursor, &dummy_cursor_iov_cnt, cmd_size);
    dummy_cursor_iov_cnt = 1;
    iov_discard_front(&in_cursor, &dummy_cursor_iov_cnt, sizeof(*s->status));

    return 0;
}

static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n,
                                   struct iovec *out_cursor,
                                   struct iovec *in_cursor)
{
    if (virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
        const struct iovec data = {
            .iov_base = (void *)n->mac,
            .iov_len = sizeof(n->mac),
        };
        ssize_t r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                            VIRTIO_NET_CTRL_MAC,
                                            VIRTIO_NET_CTRL_MAC_ADDR_SET,
                                            &data, 1);
        if (unlikely(r < 0)) {
            return r;
        }
    }

    /*
     * According to VirtIO standard, "The device MUST have an
     * empty MAC filtering table on reset.".
     *
     * Therefore, there is no need to send this CVQ command if the
     * driver also sets an empty MAC filter table, which aligns with
     * the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_RX) ||
        n->mac_table.in_use == 0) {
        return 0;
    }

    uint32_t uni_entries = n->mac_table.first_multi,
             uni_macs_size = uni_entries * ETH_ALEN,
             mul_entries = n->mac_table.in_use - uni_entries,
             mul_macs_size = mul_entries * ETH_ALEN;
    struct virtio_net_ctrl_mac uni = {
        .entries = cpu_to_le32(uni_entries),
    };
    struct virtio_net_ctrl_mac mul = {
        .entries = cpu_to_le32(mul_entries),
    };
    const struct iovec data[] = {
        {
            .iov_base = &uni,
            .iov_len = sizeof(uni),
        }, {
            .iov_base = n->mac_table.macs,
            .iov_len = uni_macs_size,
        }, {
            .iov_base = &mul,
            .iov_len = sizeof(mul),
        }, {
            .iov_base = &n->mac_table.macs[uni_macs_size],
            .iov_len = mul_macs_size,
        },
    };
    ssize_t r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_MAC,
                                        VIRTIO_NET_CTRL_MAC_TABLE_SET,
                                        data, ARRAY_SIZE(data));
    if (unlikely(r < 0)) {
        return r;
    }

    return 0;
}

static int vhost_vdpa_net_load_rss(VhostVDPAState *s, const VirtIONet *n,
                                   struct iovec *out_cursor,
                                   struct iovec *in_cursor, bool do_rss)
{
    struct virtio_net_rss_config cfg = {};
    ssize_t r;
    g_autofree uint16_t *table = NULL;

    /*
     * According to VirtIO standard, "Initially the device has all hash
     * types disabled and reports only VIRTIO_NET_HASH_REPORT_NONE.".
     *
     * Therefore, there is no need to send this CVQ command if the
     * driver disables the all hash types, which aligns with
     * the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (!n->rss_data.enabled ||
        n->rss_data.hash_types == VIRTIO_NET_HASH_REPORT_NONE) {
        return 0;
    }

    table = g_malloc_n(n->rss_data.indirections_len,
                       sizeof(n->rss_data.indirections_table[0]));
    cfg.hash_types = cpu_to_le32(n->rss_data.hash_types);

    if (do_rss) {
        /*
         * According to VirtIO standard, "Number of entries in indirection_table
         * is (indirection_table_mask + 1)".
         */
        cfg.indirection_table_mask = cpu_to_le16(n->rss_data.indirections_len -
                                                 1);
        cfg.unclassified_queue = cpu_to_le16(n->rss_data.default_queue);
        for (int i = 0; i < n->rss_data.indirections_len; ++i) {
            table[i] = cpu_to_le16(n->rss_data.indirections_table[i]);
        }
        cfg.max_tx_vq = cpu_to_le16(n->curr_queue_pairs);
    } else {
        /*
         * According to VirtIO standard, "Field reserved MUST contain zeroes.
         * It is defined to make the structure to match the layout of
         * virtio_net_rss_config structure, defined in 5.1.6.5.7.".
         *
         * Therefore, we need to zero the fields in
         * struct virtio_net_rss_config, which corresponds to the
         * `reserved` field in struct virtio_net_hash_config.
         *
         * Note that all other fields are zeroed at their definitions,
         * except for the `indirection_table` field, where the actual data
         * is stored in the `table` variable to ensure compatibility
         * with RSS case. Therefore, we need to zero the `table` variable here.
         */
        table[0] = 0;
    }

    /*
     * Considering that virtio_net_handle_rss() currently does not restore
     * the hash key length parsed from the CVQ command sent from the guest
     * into n->rss_data and uses the maximum key length in other code, so
     * we also employ the maximum key length here.
     */
    cfg.hash_key_length = sizeof(n->rss_data.key);

    const struct iovec data[] = {
        {
            .iov_base = &cfg,
            .iov_len = offsetof(struct virtio_net_rss_config,
                                indirection_table),
        }, {
            .iov_base = table,
            .iov_len = n->rss_data.indirections_len *
                       sizeof(n->rss_data.indirections_table[0]),
        }, {
            .iov_base = &cfg.max_tx_vq,
            .iov_len = offsetof(struct virtio_net_rss_config, hash_key_data) -
                       offsetof(struct virtio_net_rss_config, max_tx_vq),
        }, {
            .iov_base = (void *)n->rss_data.key,
            .iov_len = sizeof(n->rss_data.key),
        }
    };

    r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                VIRTIO_NET_CTRL_MQ,
                                do_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG :
                                VIRTIO_NET_CTRL_MQ_HASH_CONFIG,
                                data, ARRAY_SIZE(data));
    if (unlikely(r < 0)) {
        return r;
    }

    return 0;
}

static int vhost_vdpa_net_load_mq(VhostVDPAState *s,
                                  const VirtIONet *n,
                                  struct iovec *out_cursor,
                                  struct iovec *in_cursor)
{
    struct virtio_net_ctrl_mq mq;
    ssize_t r;

    if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_MQ)) {
        return 0;
    }

    trace_vhost_vdpa_net_load_mq(s, n->curr_queue_pairs);

    mq.virtqueue_pairs = cpu_to_le16(n->curr_queue_pairs);
    const struct iovec data = {
        .iov_base = &mq,
        .iov_len = sizeof(mq),
    };
    r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                VIRTIO_NET_CTRL_MQ,
                                VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET,
                                &data, 1);
    if (unlikely(r < 0)) {
        return r;
    }

    if (virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_RSS)) {
        /* load the receive-side scaling state */
        r = vhost_vdpa_net_load_rss(s, n, out_cursor, in_cursor, true);
        if (unlikely(r < 0)) {
            return r;
        }
    } else if (virtio_vdev_has_feature(&n->parent_obj,
                                       VIRTIO_NET_F_HASH_REPORT)) {
        /* load the hash calculation state */
        r = vhost_vdpa_net_load_rss(s, n, out_cursor, in_cursor, false);
        if (unlikely(r < 0)) {
            return r;
        }
    }

    return 0;
}

static int vhost_vdpa_net_load_offloads(VhostVDPAState *s,
                                        const VirtIONet *n,
                                        struct iovec *out_cursor,
                                        struct iovec *in_cursor)
{
    uint64_t offloads;
    ssize_t r;

    if (!virtio_vdev_has_feature(&n->parent_obj,
                                 VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
        return 0;
    }

    if (n->curr_guest_offloads == virtio_net_supported_guest_offloads(n)) {
        /*
         * According to VirtIO standard, "Upon feature negotiation
         * corresponding offload gets enabled to preserve
         * backward compatibility.".
         *
         * Therefore, there is no need to send this CVQ command if the
         * driver also enables all supported offloads, which aligns with
         * the device's defaults.
         *
         * Note that the device's defaults can mismatch the driver's
         * configuration only at live migration.
         */
        return 0;
    }

    offloads = cpu_to_le64(n->curr_guest_offloads);
    const struct iovec data = {
        .iov_base = &offloads,
        .iov_len = sizeof(offloads),
    };
    r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                VIRTIO_NET_CTRL_GUEST_OFFLOADS,
                                VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET,
                                &data, 1);
    if (unlikely(r < 0)) {
        return r;
    }

    return 0;
}

static int vhost_vdpa_net_load_rx_mode(VhostVDPAState *s,
                                       struct iovec *out_cursor,
                                       struct iovec *in_cursor,
                                       uint8_t cmd,
                                       uint8_t on)
{
    const struct iovec data = {
        .iov_base = &on,
        .iov_len = sizeof(on),
    };
    ssize_t r;

    r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                VIRTIO_NET_CTRL_RX, cmd, &data, 1);
    if (unlikely(r < 0)) {
        return r;
    }

    return 0;
}

static int vhost_vdpa_net_load_rx(VhostVDPAState *s,
                                  const VirtIONet *n,
                                  struct iovec *out_cursor,
                                  struct iovec *in_cursor)
{
    ssize_t r;

    if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_RX)) {
        return 0;
    }

    /*
     * According to virtio_net_reset(), device turns promiscuous mode
     * on by default.
     *
     * Additionally, according to VirtIO standard, "Since there are
     * no guarantees, it can use a hash filter or silently switch to
     * allmulti or promiscuous mode if it is given too many addresses.".
     * QEMU marks `n->mac_table.uni_overflow` if guest sets too many
     * non-multicast MAC addresses, indicating that promiscuous mode
     * should be enabled.
     *
     * Therefore, QEMU should only send this CVQ command if the
     * `n->mac_table.uni_overflow` is not marked and `n->promisc` is off,
     * which sets promiscuous mode on, different from the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (!n->mac_table.uni_overflow && !n->promisc) {
        r = vhost_vdpa_net_load_rx_mode(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_RX_PROMISC, 0);
        if (unlikely(r < 0)) {
            return r;
        }
    }

    /*
     * According to virtio_net_reset(), device turns all-multicast mode
     * off by default.
     *
     * According to VirtIO standard, "Since there are no guarantees,
     * it can use a hash filter or silently switch to allmulti or
     * promiscuous mode if it is given too many addresses.". QEMU marks
     * `n->mac_table.multi_overflow` if guest sets too many
     * non-multicast MAC addresses.
     *
     * Therefore, QEMU should only send this CVQ command if the
     * `n->mac_table.multi_overflow` is marked or `n->allmulti` is on,
     * which sets all-multicast mode on, different from the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (n->mac_table.multi_overflow || n->allmulti) {
        r = vhost_vdpa_net_load_rx_mode(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_RX_ALLMULTI, 1);
        if (unlikely(r < 0)) {
            return r;
        }
    }

    if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_RX_EXTRA)) {
        return 0;
    }

    /*
     * According to virtio_net_reset(), device turns all-unicast mode
     * off by default.
     *
     * Therefore, QEMU should only send this CVQ command if the driver
     * sets all-unicast mode on, different from the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (n->alluni) {
        r = vhost_vdpa_net_load_rx_mode(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_RX_ALLUNI, 1);
        if (r < 0) {
            return r;
        }
    }

    /*
     * According to virtio_net_reset(), device turns non-multicast mode
     * off by default.
     *
     * Therefore, QEMU should only send this CVQ command if the driver
     * sets non-multicast mode on, different from the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (n->nomulti) {
        r = vhost_vdpa_net_load_rx_mode(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_RX_NOMULTI, 1);
        if (r < 0) {
            return r;
        }
    }

    /*
     * According to virtio_net_reset(), device turns non-unicast mode
     * off by default.
     *
     * Therefore, QEMU should only send this CVQ command if the driver
     * sets non-unicast mode on, different from the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (n->nouni) {
        r = vhost_vdpa_net_load_rx_mode(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_RX_NOUNI, 1);
        if (r < 0) {
            return r;
        }
    }

    /*
     * According to virtio_net_reset(), device turns non-broadcast mode
     * off by default.
     *
     * Therefore, QEMU should only send this CVQ command if the driver
     * sets non-broadcast mode on, different from the device's defaults.
     *
     * Note that the device's defaults can mismatch the driver's
     * configuration only at live migration.
     */
    if (n->nobcast) {
        r = vhost_vdpa_net_load_rx_mode(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_RX_NOBCAST, 1);
        if (r < 0) {
            return r;
        }
    }

    return 0;
}

static int vhost_vdpa_net_load_single_vlan(VhostVDPAState *s,
                                           const VirtIONet *n,
                                           struct iovec *out_cursor,
                                           struct iovec *in_cursor,
                                           uint16_t vid)
{
    const struct iovec data = {
        .iov_base = &vid,
        .iov_len = sizeof(vid),
    };
    ssize_t r = vhost_vdpa_net_load_cmd(s, out_cursor, in_cursor,
                                        VIRTIO_NET_CTRL_VLAN,
                                        VIRTIO_NET_CTRL_VLAN_ADD,
                                        &data, 1);
    if (unlikely(r < 0)) {
        return r;
    }

    return 0;
}

static int vhost_vdpa_net_load_vlan(VhostVDPAState *s,
                                    const VirtIONet *n,
                                    struct iovec *out_cursor,
                                    struct iovec *in_cursor)
{
    int r;

    if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_VLAN)) {
        return 0;
    }

    for (int i = 0; i < MAX_VLAN >> 5; i++) {
        for (int j = 0; n->vlans[i] && j <= 0x1f; j++) {
            if (n->vlans[i] & (1U << j)) {
                r = vhost_vdpa_net_load_single_vlan(s, n, out_cursor,
                                                    in_cursor, (i << 5) + j);
                if (unlikely(r != 0)) {
                    return r;
                }
            }
        }
    }

    return 0;
}

static int vhost_vdpa_net_cvq_load(NetClientState *nc)
{
    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
    struct vhost_vdpa *v = &s->vhost_vdpa;
    const VirtIONet *n;
    int r;
    struct iovec out_cursor, in_cursor;

    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

    r = vhost_vdpa_set_vring_ready(v, v->dev->vq_index);
    if (unlikely(r < 0)) {
        return r;
    }

    if (v->shadow_vqs_enabled) {
        n = VIRTIO_NET(v->dev->vdev);
        vhost_vdpa_net_load_cursor_reset(s, &out_cursor, &in_cursor);
        r = vhost_vdpa_net_load_mac(s, n, &out_cursor, &in_cursor);
        if (unlikely(r < 0)) {
            return r;
        }
        r = vhost_vdpa_net_load_mq(s, n, &out_cursor, &in_cursor);
        if (unlikely(r)) {
            return r;
        }
        r = vhost_vdpa_net_load_offloads(s, n, &out_cursor, &in_cursor);
        if (unlikely(r)) {
            return r;
        }
        r = vhost_vdpa_net_load_rx(s, n, &out_cursor, &in_cursor);
        if (unlikely(r)) {
            return r;
        }
        r = vhost_vdpa_net_load_vlan(s, n, &out_cursor, &in_cursor);
        if (unlikely(r)) {
            return r;
        }

        /*
         * We need to poll and check all pending device's used buffers.
         *
         * We can poll here since we've had BQL from the time
         * we sent the descriptor.
         */
        r = vhost_vdpa_net_svq_flush(s, in_cursor.iov_base - (void *)s->status);
        if (unlikely(r)) {
            return r;
        }
    }

    for (int i = 0; i < v->dev->vq_index; ++i) {
        r = vhost_vdpa_set_vring_ready(v, i);
        if (unlikely(r < 0)) {
            return r;
        }
    }

    return 0;
}

static NetClientInfo net_vhost_vdpa_cvq_info = {
    .type = NET_CLIENT_DRIVER_VHOST_VDPA,
    .size = sizeof(VhostVDPAState),
    .receive = vhost_vdpa_receive,
    .start = vhost_vdpa_net_cvq_start,
    .load = vhost_vdpa_net_cvq_load,
    .stop = vhost_vdpa_net_cvq_stop,
    .cleanup = vhost_vdpa_cleanup,
    .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
    .has_ufo = vhost_vdpa_has_ufo,
    .check_peer_type = vhost_vdpa_check_peer_type,
    .set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
};

/*
 * Forward the excessive VIRTIO_NET_CTRL_MAC_TABLE_SET CVQ command to
 * vdpa device.
 *
 * Considering that QEMU cannot send the entire filter table to the
 * vdpa device, it should send the VIRTIO_NET_CTRL_RX_PROMISC CVQ
 * command to enable promiscuous mode to receive all packets,
 * according to VirtIO standard, "Since there are no guarantees,
 * it can use a hash filter or silently switch to allmulti or
 * promiscuous mode if it is given too many addresses.".
 *
 * Since QEMU ignores MAC addresses beyond `MAC_TABLE_ENTRIES` and
 * marks `n->mac_table.x_overflow` accordingly, it should have
 * the same effect on the device model to receive
 * (`MAC_TABLE_ENTRIES` + 1) or more non-multicast MAC addresses.
 * The same applies to multicast MAC addresses.
 *
 * Therefore, QEMU can provide the device model with a fake
 * VIRTIO_NET_CTRL_MAC_TABLE_SET command with (`MAC_TABLE_ENTRIES` + 1)
 * non-multicast MAC addresses and (`MAC_TABLE_ENTRIES` + 1) multicast
 * MAC addresses. This ensures that the device model marks
 * `n->mac_table.uni_overflow` and `n->mac_table.multi_overflow`,
 * allowing all packets to be received, which aligns with the
 * state of the vdpa device.
 */
static int vhost_vdpa_net_excessive_mac_filter_cvq_add(VhostVDPAState *s,
                                                       VirtQueueElement *elem,
                                                       struct iovec *out,
                                                       const struct iovec *in)
{
    struct virtio_net_ctrl_mac mac_data, *mac_ptr;
    struct virtio_net_ctrl_hdr *hdr_ptr;
    uint32_t cursor;
    ssize_t r;
    uint8_t on = 1;

    /* parse the non-multicast MAC address entries from CVQ command */
    cursor = sizeof(*hdr_ptr);
    r = iov_to_buf(elem->out_sg, elem->out_num, cursor,
                   &mac_data, sizeof(mac_data));
    if (unlikely(r != sizeof(mac_data))) {
        /*
         * If the CVQ command is invalid, we should simulate the vdpa device
         * to reject the VIRTIO_NET_CTRL_MAC_TABLE_SET CVQ command
         */
        *s->status = VIRTIO_NET_ERR;
        return sizeof(*s->status);
    }
    cursor += sizeof(mac_data) + le32_to_cpu(mac_data.entries) * ETH_ALEN;

    /* parse the multicast MAC address entries from CVQ command */
    r = iov_to_buf(elem->out_sg, elem->out_num, cursor,
                   &mac_data, sizeof(mac_data));
    if (r != sizeof(mac_data)) {
        /*
         * If the CVQ command is invalid, we should simulate the vdpa device
         * to reject the VIRTIO_NET_CTRL_MAC_TABLE_SET CVQ command
         */
        *s->status = VIRTIO_NET_ERR;
        return sizeof(*s->status);
    }
    cursor += sizeof(mac_data) + le32_to_cpu(mac_data.entries) * ETH_ALEN;

    /* validate the CVQ command */
    if (iov_size(elem->out_sg, elem->out_num) != cursor) {
        /*
         * If the CVQ command is invalid, we should simulate the vdpa device
         * to reject the VIRTIO_NET_CTRL_MAC_TABLE_SET CVQ command
         */
        *s->status = VIRTIO_NET_ERR;
        return sizeof(*s->status);
    }

    /*
     * According to VirtIO standard, "Since there are no guarantees,
     * it can use a hash filter or silently switch to allmulti or
     * promiscuous mode if it is given too many addresses.".
     *
     * Therefore, considering that QEMU is unable to send the entire
     * filter table to the vdpa device, it should send the
     * VIRTIO_NET_CTRL_RX_PROMISC CVQ command to enable promiscuous mode
     */
    hdr_ptr = out->iov_base;
    out->iov_len = sizeof(*hdr_ptr) + sizeof(on);

    hdr_ptr->class = VIRTIO_NET_CTRL_RX;
    hdr_ptr->cmd = VIRTIO_NET_CTRL_RX_PROMISC;
    iov_from_buf(out, 1, sizeof(*hdr_ptr), &on, sizeof(on));
    r = vhost_vdpa_net_cvq_add(s, out, 1, in, 1);
    if (unlikely(r < 0)) {
        return r;
    }

    /*
     * We can poll here since we've had BQL from the time
     * we sent the descriptor.
     */
    r = vhost_vdpa_net_svq_poll(s, 1);
    if (unlikely(r < sizeof(*s->status))) {
        return r;
    }
    if (*s->status != VIRTIO_NET_OK) {
        return sizeof(*s->status);
    }

    /*
     * QEMU should also send a fake VIRTIO_NET_CTRL_MAC_TABLE_SET CVQ
     * command to the device model, including (`MAC_TABLE_ENTRIES` + 1)
     * non-multicast MAC addresses and (`MAC_TABLE_ENTRIES` + 1)
     * multicast MAC addresses.
     *
     * By doing so, the device model can mark `n->mac_table.uni_overflow`
     * and `n->mac_table.multi_overflow`, enabling all packets to be
     * received, which aligns with the state of the vdpa device.
     */
    cursor = 0;
    uint32_t fake_uni_entries = MAC_TABLE_ENTRIES + 1,
             fake_mul_entries = MAC_TABLE_ENTRIES + 1,
             fake_cvq_size = sizeof(struct virtio_net_ctrl_hdr) +
                             sizeof(mac_data) + fake_uni_entries * ETH_ALEN +
                             sizeof(mac_data) + fake_mul_entries * ETH_ALEN;

    assert(fake_cvq_size < vhost_vdpa_net_cvq_cmd_page_len());
    out->iov_len = fake_cvq_size;

    /* pack the header for fake CVQ command */
    hdr_ptr = out->iov_base + cursor;
    hdr_ptr->class = VIRTIO_NET_CTRL_MAC;
    hdr_ptr->cmd = VIRTIO_NET_CTRL_MAC_TABLE_SET;
    cursor += sizeof(*hdr_ptr);

    /*
     * Pack the non-multicast MAC addresses part for fake CVQ command.
     *
     * According to virtio_net_handle_mac(), QEMU doesn't verify the MAC
     * addresses provided in CVQ command. Therefore, only the entries
     * field need to be prepared in the CVQ command.
     */
    mac_ptr = out->iov_base + cursor;
    mac_ptr->entries = cpu_to_le32(fake_uni_entries);
    cursor += sizeof(*mac_ptr) + fake_uni_entries * ETH_ALEN;

    /*
     * Pack the multicast MAC addresses part for fake CVQ command.
     *
     * According to virtio_net_handle_mac(), QEMU doesn't verify the MAC
     * addresses provided in CVQ command. Therefore, only the entries
     * field need to be prepared in the CVQ command.
     */
    mac_ptr = out->iov_base + cursor;
    mac_ptr->entries = cpu_to_le32(fake_mul_entries);

    /*
     * Simulating QEMU poll a vdpa device used buffer
     * for VIRTIO_NET_CTRL_MAC_TABLE_SET CVQ command
     */
    return sizeof(*s->status);
}

/**
 * Validate and copy control virtqueue commands.
 *
 * Following QEMU guidelines, we offer a copy of the buffers to the device to
 * prevent TOCTOU bugs.
 */
static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
                                            VirtQueueElement *elem,
                                            void *opaque)
{
    VhostVDPAState *s = opaque;
    size_t in_len;
    const struct virtio_net_ctrl_hdr *ctrl;
    virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
    /* Out buffer sent to both the vdpa device and the device model */
    struct iovec out = {
        .iov_base = s->cvq_cmd_out_buffer,
    };
    /* in buffer used for device model */
    const struct iovec model_in = {
        .iov_base = &status,
        .iov_len = sizeof(status),
    };
    /* in buffer used for vdpa device */
    const struct iovec vdpa_in = {
        .iov_base = s->status,
        .iov_len = sizeof(*s->status),
    };
    ssize_t dev_written = -EINVAL;

    out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0,
                             s->cvq_cmd_out_buffer,
                             vhost_vdpa_net_cvq_cmd_page_len());

    ctrl = s->cvq_cmd_out_buffer;
    if (ctrl->class == VIRTIO_NET_CTRL_ANNOUNCE) {
        /*
         * Guest announce capability is emulated by qemu, so don't forward to
         * the device.
         */
        dev_written = sizeof(status);
        *s->status = VIRTIO_NET_OK;
    } else if (unlikely(ctrl->class == VIRTIO_NET_CTRL_MAC &&
                        ctrl->cmd == VIRTIO_NET_CTRL_MAC_TABLE_SET &&
                        iov_size(elem->out_sg, elem->out_num) > out.iov_len)) {
        /*
         * Due to the size limitation of the out buffer sent to the vdpa device,
         * which is determined by vhost_vdpa_net_cvq_cmd_page_len(), excessive
         * MAC addresses set by the driver for the filter table can cause
         * truncation of the CVQ command in QEMU. As a result, the vdpa device
         * rejects the flawed CVQ command.
         *
         * Therefore, QEMU must handle this situation instead of sending
         * the CVQ command directly.
         */
        dev_written = vhost_vdpa_net_excessive_mac_filter_cvq_add(s, elem,
                                                            &out, &vdpa_in);
        if (unlikely(dev_written < 0)) {
            goto out;
        }
    } else {
        ssize_t r;
        r = vhost_vdpa_net_cvq_add(s, &out, 1, &vdpa_in, 1);
        if (unlikely(r < 0)) {
            dev_written = r;
            goto out;
        }

        /*
         * We can poll here since we've had BQL from the time
         * we sent the descriptor.
         */
        dev_written = vhost_vdpa_net_svq_poll(s, 1);
    }

    if (unlikely(dev_written < sizeof(status))) {
        error_report("Insufficient written data (%zu)", dev_written);
        goto out;
    }

    if (*s->status != VIRTIO_NET_OK) {
        goto out;
    }

    status = VIRTIO_NET_ERR;
    virtio_net_handle_ctrl_iov(svq->vdev, &model_in, 1, &out, 1);
    if (status != VIRTIO_NET_OK) {
        error_report("Bad CVQ processing in model");
    }

out:
    in_len = iov_from_buf(elem->in_sg, elem->in_num, 0, &status,
                          sizeof(status));
    if (unlikely(in_len < sizeof(status))) {
        error_report("Bad device CVQ written length");
    }
    vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status)));
    /*
     * `elem` belongs to vhost_vdpa_net_handle_ctrl_avail() only when
     * the function successfully forwards the CVQ command, indicated
     * by a non-negative value of `dev_written`. Otherwise, it still
     * belongs to SVQ.
     * This function should only free the `elem` when it owns.
     */
    if (dev_written >= 0) {
        g_free(elem);
    }
    return dev_written < 0 ? dev_written : 0;
}

static const VhostShadowVirtqueueOps vhost_vdpa_net_svq_ops = {
    .avail_handler = vhost_vdpa_net_handle_ctrl_avail,
};

/**
 * Probe if CVQ is isolated
 *
 * @device_fd         The vdpa device fd
 * @features          Features offered by the device.
 * @cvq_index         The control vq pair index
 *
 * Returns <0 in case of failure, 0 if false and 1 if true.
 */
static int vhost_vdpa_probe_cvq_isolation(int device_fd, uint64_t features,
                                          int cvq_index, Error **errp)
{
    ERRP_GUARD();
    uint64_t backend_features;
    int64_t cvq_group;
    uint8_t status = VIRTIO_CONFIG_S_ACKNOWLEDGE |
                     VIRTIO_CONFIG_S_DRIVER;
    int r;

    r = ioctl(device_fd, VHOST_GET_BACKEND_FEATURES, &backend_features);
    if (unlikely(r < 0)) {
        error_setg_errno(errp, errno, "Cannot get vdpa backend_features");
        return r;
    }

    if (!(backend_features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID))) {
        return 0;
    }

    r = ioctl(device_fd, VHOST_VDPA_SET_STATUS, &status);
    if (unlikely(r)) {
        error_setg_errno(errp, -r, "Cannot set device status");
        goto out;
    }

    r = ioctl(device_fd, VHOST_SET_FEATURES, &features);
    if (unlikely(r)) {
        error_setg_errno(errp, -r, "Cannot set features");
        goto out;
    }

    status |= VIRTIO_CONFIG_S_FEATURES_OK;
    r = ioctl(device_fd, VHOST_VDPA_SET_STATUS, &status);
    if (unlikely(r)) {
        error_setg_errno(errp, -r, "Cannot set device status");
        goto out;
    }

    cvq_group = vhost_vdpa_get_vring_group(device_fd, cvq_index, errp);
    if (unlikely(cvq_group < 0)) {
        if (cvq_group != -ENOTSUP) {
            r = cvq_group;
            goto out;
        }

        /*
         * The kernel report VHOST_BACKEND_F_IOTLB_ASID if the vdpa frontend
         * support ASID even if the parent driver does not.  The CVQ cannot be
         * isolated in this case.
         */
        error_free(*errp);
        *errp = NULL;
        r = 0;
        goto out;
    }

    for (int i = 0; i < cvq_index; ++i) {
        int64_t group = vhost_vdpa_get_vring_group(device_fd, i, errp);
        if (unlikely(group < 0)) {
            r = group;
            goto out;
        }

        if (group == (int64_t)cvq_group) {
            r = 0;
            goto out;
        }
    }

    r = 1;

out:
    status = 0;
    ioctl(device_fd, VHOST_VDPA_SET_STATUS, &status);
    return r;
}

static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
                                       const char *device,
                                       const char *name,
                                       int vdpa_device_fd,
                                       int queue_pair_index,
                                       int nvqs,
                                       bool is_datapath,
                                       bool svq,
                                       struct vhost_vdpa_iova_range iova_range,
                                       uint64_t features,
                                       VhostVDPAShared *shared,
                                       Error **errp)
{
    NetClientState *nc = NULL;
    VhostVDPAState *s;
    int ret = 0;
    assert(name);
    int cvq_isolated = 0;

    if (is_datapath) {
        nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device,
                                 name);
    } else {
        cvq_isolated = vhost_vdpa_probe_cvq_isolation(vdpa_device_fd, features,
                                                      queue_pair_index * 2,
                                                      errp);
        if (unlikely(cvq_isolated < 0)) {
            return NULL;
        }

        nc = qemu_new_net_control_client(&net_vhost_vdpa_cvq_info, peer,
                                         device, name);
    }
    qemu_set_info_str(nc, TYPE_VHOST_VDPA);
    s = DO_UPCAST(VhostVDPAState, nc, nc);

    s->vhost_vdpa.index = queue_pair_index;
    s->always_svq = svq;
    s->migration_state.notify = NULL;
    s->vhost_vdpa.shadow_vqs_enabled = svq;
    if (queue_pair_index == 0) {
        vhost_vdpa_net_valid_svq_features(features,
                                          &s->vhost_vdpa.migration_blocker);
        s->vhost_vdpa.shared = g_new0(VhostVDPAShared, 1);
        s->vhost_vdpa.shared->device_fd = vdpa_device_fd;
        s->vhost_vdpa.shared->iova_range = iova_range;
        s->vhost_vdpa.shared->shadow_data = svq;
    } else if (!is_datapath) {
        s->cvq_cmd_out_buffer = mmap(NULL, vhost_vdpa_net_cvq_cmd_page_len(),
                                     PROT_READ | PROT_WRITE,
                                     MAP_SHARED | MAP_ANONYMOUS, -1, 0);
        s->status = mmap(NULL, vhost_vdpa_net_cvq_cmd_page_len(),
                         PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
                         -1, 0);

        s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops;
        s->vhost_vdpa.shadow_vq_ops_opaque = s;
        s->cvq_isolated = cvq_isolated;
    }
    if (queue_pair_index != 0) {
        s->vhost_vdpa.shared = shared;
    }

    ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs);
    if (ret) {
        qemu_del_net_client(nc);
        return NULL;
    }

    return nc;
}

static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp)
{
    int ret = ioctl(fd, VHOST_GET_FEATURES, features);
    if (unlikely(ret < 0)) {
        error_setg_errno(errp, errno,
                         "Fail to query features from vhost-vDPA device");
    }
    return ret;
}

static int vhost_vdpa_get_max_queue_pairs(int fd, uint64_t features,
                                          int *has_cvq, Error **errp)
{
    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
    g_autofree struct vhost_vdpa_config *config = NULL;
    __virtio16 *max_queue_pairs;
    int ret;

    if (features & (1 << VIRTIO_NET_F_CTRL_VQ)) {
        *has_cvq = 1;
    } else {
        *has_cvq = 0;
    }

    if (features & (1 << VIRTIO_NET_F_MQ)) {
        config = g_malloc0(config_size + sizeof(*max_queue_pairs));
        config->off = offsetof(struct virtio_net_config, max_virtqueue_pairs);
        config->len = sizeof(*max_queue_pairs);

        ret = ioctl(fd, VHOST_VDPA_GET_CONFIG, config);
        if (ret) {
            error_setg(errp, "Fail to get config from vhost-vDPA device");
            return -ret;
        }

        max_queue_pairs = (__virtio16 *)&config->buf;

        return lduw_le_p(max_queue_pairs);
    }

    return 1;
}

int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
                        NetClientState *peer, Error **errp)
{
    ERRP_GUARD();
    const NetdevVhostVDPAOptions *opts;
    uint64_t features;
    int vdpa_device_fd;
    g_autofree NetClientState **ncs = NULL;
    struct vhost_vdpa_iova_range iova_range;
    NetClientState *nc;
    int queue_pairs, r, i = 0, has_cvq = 0;

    assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
    opts = &netdev->u.vhost_vdpa;
    if (!opts->vhostdev && !opts->vhostfd) {
        error_setg(errp,
                   "vhost-vdpa: neither vhostdev= nor vhostfd= was specified");
        return -1;
    }

    if (opts->vhostdev && opts->vhostfd) {
        error_setg(errp,
                   "vhost-vdpa: vhostdev= and vhostfd= are mutually exclusive");
        return -1;
    }

    if (opts->vhostdev) {
        vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp);
        if (vdpa_device_fd == -1) {
            return -errno;
        }
    } else {
        /* has_vhostfd */
        vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp);
        if (vdpa_device_fd == -1) {
            error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: ");
            return -1;
        }
    }

    r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp);
    if (unlikely(r < 0)) {
        goto err;
    }

    queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features,
                                                 &has_cvq, errp);
    if (queue_pairs < 0) {
        qemu_close(vdpa_device_fd);
        return queue_pairs;
    }

    r = vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range);
    if (unlikely(r < 0)) {
        error_setg(errp, "vhost-vdpa: get iova range failed: %s",
                   strerror(-r));
        goto err;
    }

    if (opts->x_svq && !vhost_vdpa_net_valid_svq_features(features, errp)) {
        goto err;
    }

    ncs = g_malloc0(sizeof(*ncs) * queue_pairs);

    for (i = 0; i < queue_pairs; i++) {
        VhostVDPAShared *shared = NULL;

        if (i) {
            shared = DO_UPCAST(VhostVDPAState, nc, ncs[0])->vhost_vdpa.shared;
        }
        ncs[i] = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
                                     vdpa_device_fd, i, 2, true, opts->x_svq,
                                     iova_range, features, shared, errp);
        if (!ncs[i])
            goto err;
    }

    if (has_cvq) {
        VhostVDPAState *s0 = DO_UPCAST(VhostVDPAState, nc, ncs[0]);
        VhostVDPAShared *shared = s0->vhost_vdpa.shared;

        nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
                                 vdpa_device_fd, i, 1, false,
                                 opts->x_svq, iova_range, features, shared,
                                 errp);
        if (!nc)
            goto err;
    }

    return 0;

err:
    if (i) {
        for (i--; i >= 0; i--) {
            qemu_del_net_client(ncs[i]);
        }
    }

    qemu_close(vdpa_device_fd);

    return -1;
}
