From: Tiwei Bie <tiwei.bie@intel.com>
To: Adrian Moreno <amorenoz@redhat.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 15:25:15 +0800 [thread overview]
Message-ID: <20190923072515.GA20810@___> (raw)
In-Reply-To: <20190917144900.14407-1-amorenoz@redhat.com>
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.
> 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
>
next prev parent reply other threads:[~2019-09-23 7: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 [this message]
2019-09-23 10:28 ` Adrian Moreno
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=20190923072515.GA20810@___ \
--to=tiwei.bie@intel.com \
--cc=amorenoz@redhat.com \
--cc=dev@dpdk.org \
--cc=maxime.coquelin@redhat.com \
--cc=pezhang@redhat.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).