DPDK patches and discussions
 help / color / mirror / Atom feed
From: Adrian Moreno <amorenoz@redhat.com>
To: Tiwei Bie <tiwei.bie@intel.com>
Cc: dev@dpdk.org, zhihong.wang@intel.com,
	Maxime Coquelin <maxime.coquelin@redhat.com>,
	Pei Zhang <pezhang@redhat.com>
Subject: Re: [dpdk-dev] [PATCH] vhost: translate incoming log address to gpa
Date: Mon, 23 Sep 2019 12:28:35 +0200	[thread overview]
Message-ID: <21f69f49-5921-bf3b-9655-f986d68d7202@redhat.com> (raw)
In-Reply-To: <20190923072515.GA20810@___>

On 9/23/19 9:25 AM, Tiwei Bie wrote:
> On Tue, Sep 17, 2019 at 04:49:00PM +0200, Adrian Moreno wrote:
>> When IOMMU is enabled the incoming log address is in IOVA space. In that
>> case, look in IOTLB table and translate the resulting HVA to GPA.
>>
>> If IOMMU is not enabled, the incoming log address is already a GPA so no
>> transformation is needed.
>>
>> This change makes page logging work when IOVA_VA is selected in the guest.
> 
> Besides the log address of the ring, when IOMMU is enabled,
> the addresses in descriptors are also IOVAs and should be
> translated to GPAs before doing the dirty page logging.
> 
Thanks Tiwei. You're right. In fact, it's not the only place where IOVAs are
assumed to be GPAs, for example in vhost.h:gpa_to_hpa:

/* Convert guest physical address to host physical address */
static __rte_always_inline rte_iova_t
gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)
{
	uint32_t i;
	struct guest_page *page;

	for (i = 0; i < dev->nr_guest_pages; i++) {
		page = &dev->guest_pages[i];

		if (gpa >= page->guest_phys_addr &&
		    gpa + size < page->guest_phys_addr + page->size) {
			return gpa - page->guest_phys_addr +
			       page->host_phys_addr;
		}
	}

	return 0;
}

used in ZERO-COPY mode to check if the IOVA range is continuous in host physical
memory and called buffer IOVAs. If I'm not mistaken this should also be
translated as:

IOVA --> HVA (iotlb lookup)
HVA --> GPA (mem_region lookup)
GPA --> HIOVA (guest_page lookup)

Right?

Thanks.
Adrián

>> Further information: https://bugs.dpdk.org/show_bug.cgi?id=337
> 
> As this is fixing a real bug, we also need a "Fixes: " line and Cc stable.
> 
> Thanks!
> Tiwei
> 
>>
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Reported-by: Pei Zhang <pezhang@redhat.com>
>>
>> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
>> ---
>>  lib/librte_vhost/vhost.c      |  1 +
>>  lib/librte_vhost/vhost_user.c | 78 ++++++++++++++++++++++++++++++++++-
>>  2 files changed, 78 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
>> index 981837b5d..e57dda22f 100644
>> --- a/lib/librte_vhost/vhost.c
>> +++ b/lib/librte_vhost/vhost.c
>> @@ -383,6 +383,7 @@ vring_invalidate(struct virtio_net *dev, struct vhost_virtqueue *vq)
>>  	vq->desc = NULL;
>>  	vq->avail = NULL;
>>  	vq->used = NULL;
>> +	vq->log_guest_addr = 0;
>>  
>>  	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
>>  		vhost_user_iotlb_wr_unlock(vq);
>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>> index 0b72648a5..35fca00fe 100644
>> --- a/lib/librte_vhost/vhost_user.c
>> +++ b/lib/librte_vhost/vhost_user.c
>> @@ -570,6 +570,74 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
>>  	return qva_to_vva(dev, ra, size);
>>  }
>>  
>> +/*
>> + * Converts Vhost Virtual Address to Guest Physical Address
>> + */
>> +static uint64_t
>> +vva_to_gpa(struct virtio_net *dev, uint64_t vva, uint64_t *len)
>> +{
>> +	struct rte_vhost_mem_region *r;
>> +	uint32_t i;
>> +
>> +	if (unlikely(!dev || !dev->mem))
>> +		goto out_error;
>> +
>> +	/* Find the region where the address lives. */
>> +	for (i = 0; i < dev->mem->nregions; i++) {
>> +		r = &dev->mem->regions[i];
>> +
>> +		if (vva >= r->host_user_addr &&
>> +		    vva <  r->host_user_addr + r->size) {
>> +
>> +			if (unlikely(vva + *len > r->host_user_addr + r->size))
>> +				*len = r->guest_user_addr + r->size - vva;
>> +
>> +			return r->guest_phys_addr + vva - r->host_user_addr;
>> +		}
>> +	}
>> +out_error:
>> +	*len = 0;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * 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)
>> +{
>> +	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 vva, gpa;
>> +		uint64_t size = exp_size;
>> +
>> +		vva = vhost_user_iotlb_cache_find(vq, log_addr,
>> +					&size, VHOST_ACCESS_RW);
>> +		if (size != exp_size) {
>> +			vhost_user_iotlb_miss(dev, log_addr + size,
>> +					      VHOST_ACCESS_RW);
>> +			return 0;
>> +		}
>> +
>> +		gpa = vva_to_gpa(dev, vva, &size);
>> +		if (size != exp_size) {
>> +			RTE_LOG(ERR, VHOST_CONFIG,
>> +				"VQ: Failed to find GPA mapping for log_addr."
>> +				"log_addr: 0x%0lx vva: 0x%0lx\n",
>> +				log_addr, vva);
>> +			return 0;
>> +		}
>> +		return gpa;
>> +
>> +	} else
>> +		return log_addr;
>> +}
>> +
>>  static struct virtio_net *
>>  translate_ring_addresses(struct virtio_net *dev, int vq_index)
>>  {
>> @@ -676,7 +744,15 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index)
>>  		vq->last_avail_idx = vq->used->idx;
>>  	}
>>  
>> -	vq->log_guest_addr = addr->log_guest_addr;
>> +	vq->log_guest_addr =
>> +		translate_log_addr(dev, vq, addr->log_guest_addr);
>> +	if (vq->log_guest_addr == 0) {
>> +		RTE_LOG(DEBUG, VHOST_CONFIG,
>> +			"(%d) failed to map log_guest_addr .\n",
>> +			dev->vid);
>> +		return dev;
>> +	}
>> +
>>  
>>  	VHOST_LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n",
>>  			dev->vid, vq->desc);
>> -- 
>> 2.21.0
>>


  reply	other threads:[~2019-09-23 10:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-17 14:49 Adrian Moreno
2019-09-23  7:25 ` Tiwei Bie
2019-09-23 10:28   ` Adrian Moreno [this message]
2019-09-24  5:23     ` Tiwei Bie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=21f69f49-5921-bf3b-9655-f986d68d7202@redhat.com \
    --to=amorenoz@redhat.com \
    --cc=dev@dpdk.org \
    --cc=maxime.coquelin@redhat.com \
    --cc=pezhang@redhat.com \
    --cc=tiwei.bie@intel.com \
    --cc=zhihong.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).