dev->mem = NULL;
}
- free(dev->guest_pages);
+ rte_free(dev->guest_pages);
dev->guest_pages = NULL;
if (dev->log_addr) {
{
if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) {
uint64_t vva;
- uint64_t req_size = *size;
- vva = vhost_user_iotlb_cache_find(vq, ra,
+ vhost_user_iotlb_rd_lock(vq);
+ vva = vhost_iova_to_vva(dev, vq, ra,
size, VHOST_ACCESS_RW);
- if (req_size != *size)
- vhost_user_iotlb_miss(dev, (ra + *size),
- VHOST_ACCESS_RW);
+ vhost_user_iotlb_rd_unlock(vq);
return vva;
}
return qva_to_vva(dev, ra, size);
}
-/*
- * Converts vring log address to GPA
- * If IOMMU is enabled, the log address is IOVA
- * If IOMMU not enabled, the log address is already GPA
- */
static uint64_t
-translate_log_addr(struct virtio_net *dev, struct vhost_virtqueue *vq,
- uint64_t log_addr)
+log_addr_to_gpa(struct virtio_net *dev, struct vhost_virtqueue *vq)
{
- if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) {
- const uint64_t exp_size = sizeof(struct vring_used) +
- sizeof(struct vring_used_elem) * vq->size;
- uint64_t hva, gpa;
- uint64_t size = exp_size;
-
- hva = vhost_iova_to_vva(dev, vq, log_addr,
- &size, VHOST_ACCESS_RW);
- if (size != exp_size)
- return 0;
+ uint64_t log_gpa;
- gpa = hva_to_gpa(dev, hva, exp_size);
- if (!gpa) {
- VHOST_LOG_CONFIG(ERR,
- "VQ: Failed to find GPA for log_addr: 0x%" PRIx64 " hva: 0x%" PRIx64 "\n",
- log_addr, hva);
- return 0;
- }
- return gpa;
+ vhost_user_iotlb_rd_lock(vq);
+ log_gpa = translate_log_addr(dev, vq, vq->ring_addrs.log_guest_addr);
+ vhost_user_iotlb_rd_unlock(vq);
- } else
- return log_addr;
+ return log_gpa;
}
static struct virtio_net *
if (addr->flags & (1 << VHOST_VRING_F_LOG)) {
vq->log_guest_addr =
- translate_log_addr(dev, vq, addr->log_guest_addr);
+ log_addr_to_gpa(dev, vq);
if (vq->log_guest_addr == 0) {
VHOST_LOG_CONFIG(DEBUG,
"(%d) failed to map log_guest_addr.\n",
if (dev->nr_guest_pages == dev->max_guest_pages) {
dev->max_guest_pages *= 2;
old_pages = dev->guest_pages;
- dev->guest_pages = realloc(dev->guest_pages,
- dev->max_guest_pages * sizeof(*page));
- if (!dev->guest_pages) {
+ dev->guest_pages = rte_realloc(dev->guest_pages,
+ dev->max_guest_pages * sizeof(*page),
+ RTE_CACHE_LINE_SIZE);
+ if (dev->guest_pages == NULL) {
VHOST_LOG_CONFIG(ERR, "cannot realloc guest_pages\n");
- free(old_pages);
+ rte_free(old_pages);
return -1;
}
}
reg_size -= size;
}
+ /* sort guest page array if over binary search threshold */
+ if (dev->nr_guest_pages >= VHOST_BINARY_SEARCH_THRESH) {
+ qsort((void *)dev->guest_pages, dev->nr_guest_pages,
+ sizeof(struct guest_page), guest_page_addrcmp);
+ }
+
return 0;
}
vhost_user_iotlb_flush_all(dev->virtqueue[i]);
dev->nr_guest_pages = 0;
- if (!dev->guest_pages) {
+ if (dev->guest_pages == NULL) {
dev->max_guest_pages = 8;
- dev->guest_pages = malloc(dev->max_guest_pages *
- sizeof(struct guest_page));
+ dev->guest_pages = rte_zmalloc(NULL,
+ dev->max_guest_pages *
+ sizeof(struct guest_page),
+ RTE_CACHE_LINE_SIZE);
if (dev->guest_pages == NULL) {
VHOST_LOG_CONFIG(ERR,
"(%d) failed to allocate memory "
size = msg->payload.log.mmap_size;
off = msg->payload.log.mmap_offset;
- /* Don't allow mmap_offset to point outside the mmap region */
- if (off > size) {
+ /* Check for mmap size and offset overflow. */
+ if (off >= -size) {
VHOST_LOG_CONFIG(ERR,
- "log offset %#"PRIx64" exceeds log size %#"PRIx64"\n",
+ "log offset %#"PRIx64" and log size %#"PRIx64" overflow\n",
off, size);
return RTE_VHOST_MSG_RESULT_ERR;
}
* Set the flag to inject a RARP broadcast packet at
* rte_vhost_dequeue_burst().
*
- * rte_smp_wmb() is for making sure the mac is copied
- * before the flag is set.
+ * __ATOMIC_RELEASE ordering is for making sure the mac is
+ * copied before the flag is set.
*/
- rte_smp_wmb();
- rte_atomic16_set(&dev->broadcast_rarp, 1);
+ __atomic_store_n(&dev->broadcast_rarp, 1, __ATOMIC_RELEASE);
did = dev->vdpa_dev_id;
vdpa_dev = rte_vdpa_get_device(did);
if (vdpa_dev && vdpa_dev->ops->migration_done)
if (ra->used_user_addr < end && (ra->used_user_addr + len) > start)
return 1;
+ if (ra->flags & (1 << VHOST_VRING_F_LOG)) {
+ len = sizeof(uint64_t);
+ if (ra->log_guest_addr < end &&
+ (ra->log_guest_addr + len) > start)
+ return 1;
+ }
+
return 0;
}
if (ra->used_user_addr < end && (ra->used_user_addr + len) > start)
return 1;
+ if (ra->flags & (1 << VHOST_VRING_F_LOG)) {
+ len = sizeof(uint64_t);
+ if (ra->log_guest_addr < end &&
+ (ra->log_guest_addr + len) > start)
+ return 1;
+ }
+
return 0;
}
vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev,
struct VhostUserMsg *msg)
{
- uint16_t vring_idx;
+ uint32_t vring_idx;
switch (msg->request.master) {
case VHOST_USER_SET_VRING_KICK:
if ((msg->flags & VHOST_USER_NEED_REPLY) == 0)
return 0;
- if (read_vhost_message(dev->slave_req_fd, &msg_reply) < 0) {
+ ret = read_vhost_message(dev->slave_req_fd, &msg_reply);
+ if (ret <= 0) {
+ if (ret < 0)
+ VHOST_LOG_CONFIG(ERR,
+ "vhost read slave message reply failed\n");
+ else
+ VHOST_LOG_CONFIG(INFO,
+ "vhost peer closed\n");
ret = -1;
goto out;
}
+ ret = 0;
if (msg_reply.request.slave != msg->request.slave) {
VHOST_LOG_CONFIG(ERR,
"Received unexpected msg type (%u), expected %u\n",