@@ -198,11 +198,14 @@ vvu_vring_call(struct virtio_net *dev, struct vhost_virtqueue *vq)
struct vvu_connection *conn =
container_of(dev, struct vvu_connection, device);
struct vvu_socket *vvu_socket = conn->vvu_socket;
+ struct virtio_hw *hw = &vvu_socket->pdev->hw;
uint16_t vq_idx = vq->vring_idx;
+ uint16_t *notify_addr = (void *)((uint8_t *)vvu_socket->doorbells +
+ vq_idx * hw->doorbell_off_multiplier);
RTE_LOG(DEBUG, VHOST_CONFIG, "%s vq_idx %u\n", __func__, vq_idx);
- rte_write16(rte_cpu_to_le_16(vq_idx), &vvu_socket->doorbells[vq_idx]);
+ rte_write16(rte_cpu_to_le_16(vq_idx), notify_addr);
return 0;
}
@@ -265,14 +268,14 @@ vvu_map_mem_regions(struct virtio_net *dev, struct VhostUserMsg *msg __rte_unuse
struct vvu_connection *conn =
container_of(dev, struct vvu_connection, device);
struct vvu_socket *vvu_socket = conn->vvu_socket;
- struct rte_pci_device *pci_dev = vvu_socket->pdev->pci_dev;
+ struct virtio_hw *hw = &vvu_socket->pdev->hw;
uint8_t *mmap_addr;
uint32_t i;
- /* Memory regions start after the doorbell registers */
- mmap_addr = (uint8_t *)pci_dev->mem_resource[2].addr +
- RTE_ALIGN_CEIL((vvu_socket->max_vhost_queues + 1 /* log fd */) *
- sizeof(uint16_t), 4096);
+ /* Get the starting address of vhost memory regions from
+ * the shared memory virtio PCI capability
+ */
+ mmap_addr = hw->shared_memory_cfg;
for (i = 0; i < dev->mem->nregions; i++) {
struct rte_vhost_mem_region *reg = &dev->mem->regions[i];
@@ -780,10 +783,13 @@ vvu_virtio_pci_init_intr(struct vvu_socket *vvu_socket)
static int
vvu_virtio_pci_init_bar(struct vvu_socket *vvu_socket)
{
- struct rte_pci_device *pci_dev = vvu_socket->pdev->pci_dev;
+ struct virtio_hw *hw = &vvu_socket->pdev->hw;
struct virtio_net *dev = NULL; /* just for sizeof() */
- vvu_socket->doorbells = pci_dev->mem_resource[2].addr;
+ /* Get the starting address of the doorbells from
+ * the doorbell virtio PCI capability
+ */
+ vvu_socket->doorbells = hw->doorbell_base;
if (!vvu_socket->doorbells) {
RTE_LOG(ERR, VHOST_CONFIG, "BAR 2 not available\n");
return -1;
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2014 Intel Corporation
+ * Copyright(c) 2019 Arrikto Inc.
*/
#include <stdint.h>
@@ -407,6 +408,18 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
case VIRTIO_PCI_CAP_ISR_CFG:
hw->isr = get_cfg_addr(dev, &cap);
break;
+ case VIRTIO_PCI_CAP_DOORBELL_CFG:
+ rte_pci_read_config(dev, &hw->doorbell_off_multiplier,
+ 4, pos + sizeof(cap));
+ hw->doorbell_base = get_cfg_addr(dev, &cap);
+ rte_pci_read_config(dev, &hw->doorbell_length, 4, pos + 10);
+ break;
+ case VIRTIO_PCI_CAP_NOTIFICATION_CFG:
+ hw->notify_cfg = get_cfg_addr(dev, &cap);
+ break;
+ case VIRTIO_PCI_CAP_SHARED_MEMORY_CFG:
+ hw->shared_memory_cfg = get_cfg_addr(dev, &cap);
+ break;
}
next:
@@ -426,6 +439,9 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
RTE_LOG(DEBUG, VIRTIO_PCI_CONFIG, "isr cfg mapped at: %p\n", hw->isr);
RTE_LOG(DEBUG, VIRTIO_PCI_CONFIG, "notify base: %p, notify off multiplier: %u\n",
hw->notify_base, hw->notify_off_multiplier);
+ RTE_LOG(DEBUG, VIRTIO_PCI_CONFIG, "doorbell base: %p, doorbell off multiplier: %u\n", hw->doorbell_base, hw->doorbell_off_multiplier);
+ RTE_LOG(DEBUG, VIRTIO_PCI_CONFIG, "notification cfg mapped at: %p\n", hw->notify_cfg);
+ RTE_LOG(DEBUG, VIRTIO_PCI_CONFIG, "shared memory region mapped at: %p\n", hw->shared_memory_cfg);
return 0;
}
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2014 Intel Corporation
+ * Copyright(c) 2019 Arrikto Inc.
*/
/* XXX This file is based on drivers/net/virtio/virtio_pci.h. It would be
@@ -117,6 +118,10 @@ struct virtqueue;
#define VIRTIO_PCI_CAP_DEVICE_CFG 4
/* PCI configuration access */
#define VIRTIO_PCI_CAP_PCI_CFG 5
+/* Additional capabilities for the virtio-vhost-user device */
+#define VIRTIO_PCI_CAP_DOORBELL_CFG 6
+#define VIRTIO_PCI_CAP_NOTIFICATION_CFG 7
+#define VIRTIO_PCI_CAP_SHARED_MEMORY_CFG 8
/* This is the PCI capability header: */
struct virtio_pci_cap {
@@ -161,6 +166,12 @@ struct virtio_pci_common_cfg {
uint32_t queue_used_hi; /* read-write */
};
+/* Fields in VIRTIO_PCI_CAP_NOTIFICATION_CFG */
+struct virtio_pci_notification_cfg {
+ uint16_t notification_select; /* read-write */
+ uint16_t notification_msix_vector; /* read-write */
+};
+
struct virtio_hw;
struct virtio_pci_ops {
@@ -200,6 +211,14 @@ struct virtio_hw {
uint16_t *notify_base;
struct virtio_pci_common_cfg *common_cfg;
void *dev_cfg;
+ /* virtio-vhost-user additional device resource capabilities
+ * https://stefanha.github.io/virtio/vhost-user-slave.html#x1-2830007
+ */
+ uint32_t doorbell_off_multiplier;
+ uint16_t *doorbell_base;
+ uint32_t doorbell_length;
+ struct virtio_pci_notification_cfg *notify_cfg;
+ uint8_t *shared_memory_cfg;
/*
* App management thread and virtio interrupt handler thread
* both can change device state, this lock is meant to avoid