@@ -20,6 +20,33 @@
#define VPNET_CQ_SIZE 32
#define VPNET_RQ_SIZE 256
+void vpnet_set_peer_vq_num(VhostPCINet *vpnet, uint16_t num)
+{
+ vpnet->peer_vq_num = num;
+}
+
+void vpnet_init_device_features(VhostPCINet *vpnet, uint64_t features)
+{
+ vpnet->device_features = features;
+}
+
+void vpnet_set_peer_vq_msg(VhostPCINet *vpnet, PeerVqNode *vq_node)
+{
+ struct peer_vq_msg *pvq_msg;
+ uint32_t vring_num = vq_node->vring_num;
+
+ if (vpnet->pvq_msg == NULL)
+ vpnet->pvq_msg = g_malloc0(sizeof(struct peer_vq_msg) * (vring_num + 1));
+
+ pvq_msg = vpnet->pvq_msg + vring_num;
+ pvq_msg->last_avail_idx = vq_node->last_avail_idx;
+ pvq_msg->vring_num = vring_num;
+ pvq_msg->vring_enable = vq_node->enabled;
+ pvq_msg->desc_gpa = vq_node->addr.desc_user_addr;
+ pvq_msg->avail_gpa = vq_node->addr.avail_user_addr;
+ pvq_msg->used_gpa = vq_node->addr.used_user_addr;
+}
+
static void vpnet_handle_rq(VirtIODevice *vdev, VirtQueue *vq)
{
}
@@ -2320,7 +2320,21 @@ static void vpnet_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
VhostPCINetPCI *dev = VHOST_PCI_NET_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
+ int bar_id = 2;
+ PeerVqNode *vq_node;
+ qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+
+ pci_register_bar(&vpci_dev->pci_dev, bar_id,
+ PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_PREFETCH |
+ PCI_BASE_ADDRESS_MEM_TYPE_64,
+ vp_slave->bar_mr);
+ vpnet_set_peer_vq_num(&dev->vdev, vp_slave->pvq_num);
+ vpnet_init_device_features(&dev->vdev, vp_slave->feature_bits);
+ QLIST_FOREACH(vq_node, &vp_slave->pvq_list, node) {
+ vpnet_set_peer_vq_msg(&dev->vdev, vq_node);
+ }
object_property_set_bool(OBJECT(vdev), true, "realized", errp);
}
@@ -16,6 +16,7 @@
#include "standard-headers/linux/vhost_pci_net.h"
#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost-pci-slave.h"
#define TYPE_VHOST_PCI_NET "vhost-pci-net-device"
#define VHOST_PCI_NET(obj) \
@@ -31,6 +32,14 @@ typedef struct VhostPCINet {
uint16_t peer_vq_num;
size_t config_size;
uint64_t device_features;
+ struct peer_mem_msg pmem_msg;
+ struct peer_vq_msg *pvq_msg;
} VhostPCINet;
+void vpnet_set_peer_vq_num(VhostPCINet *vpnet, uint16_t num);
+
+void vpnet_init_device_features(VhostPCINet *vpnet, uint64_t features);
+
+void vpnet_set_peer_vq_msg(VhostPCINet *vpnet, PeerVqNode *vq_node);
+
#endif
@@ -51,4 +51,18 @@ struct vhost_pci_net_config {
uint16_t status;
} QEMU_PACKED;
+struct peer_vq_msg {
+ uint16_t last_avail_idx;
+ int32_t vring_enable;
+ uint32_t vring_num;
+ uint64_t desc_gpa;
+ uint64_t avail_gpa;
+ uint64_t used_gpa;
+};
+
+struct peer_vqs_msg {
+ uint32_t nvqs;
+ struct peer_vq_msg pvq_msg[];
+};
+
#endif
When the device is realized, pass the vring info to the device from the slave maintained list. The device uses bar2 to hold the peer VM memory. Signed-off-by: Wei Wang <wei.w.wang@intel.com> --- hw/net/vhost-pci-net.c | 27 ++++++++++++++++++++++++++ hw/virtio/virtio-pci.c | 14 +++++++++++++ include/hw/virtio/vhost-pci-net.h | 9 +++++++++ include/standard-headers/linux/vhost_pci_net.h | 14 +++++++++++++ 4 files changed, 64 insertions(+)