From: Alex Williamson <alex.williamson@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Xu <peterx@redhat.com>,
tianyu.lan@intel.com, kevin.tian@intel.com, mst@redhat.com,
jan.kiszka@siemens.com, jasowang@redhat.com,
qemu-devel@nongnu.org, bd.aviv@gmail.com
Subject: Re: [Qemu-devel] [PATCH v5 02/18] vfio: introduce vfio_get_vaddr()
Date: Wed, 25 Jan 2017 10:36:42 -0700 [thread overview]
Message-ID: <20170125103642.5f4232a9@t450s.home> (raw)
In-Reply-To: <9ef03816-0bef-f54b-63fe-daf27eab4a40@redhat.com>
On Wed, 25 Jan 2017 18:11:37 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 24/01/2017 17:29, Alex Williamson wrote:
> > On Tue, 24 Jan 2017 18:25:55 +0800
> > Peter Xu <peterx@redhat.com> wrote:
> >
> >> A cleanup for vfio_iommu_map_notify(). Should have no functional change,
> >> just to make the function shorter and easier to understand.
> >>
> >> Signed-off-by: Peter Xu <peterx@redhat.com>
> >> ---
> >> hw/vfio/common.c | 58 +++++++++++++++++++++++++++++++++++++-------------------
> >> 1 file changed, 38 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> >> index 174f351..ce55dff 100644
> >> --- a/hw/vfio/common.c
> >> +++ b/hw/vfio/common.c
> >> @@ -294,25 +294,14 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section)
> >> section->offset_within_address_space & (1ULL << 63);
> >> }
> >>
> >> -static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> >> +static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
> >> + bool *read_only)
> >> {
> >> - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
> >> - VFIOContainer *container = giommu->container;
> >> - hwaddr iova = iotlb->iova + giommu->iommu_offset;
> >> MemoryRegion *mr;
> >> hwaddr xlat;
> >> hwaddr len = iotlb->addr_mask + 1;
> >> - void *vaddr;
> >> - int ret;
> >> -
> >> - trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : "MAP",
> >> - iova, iova + iotlb->addr_mask);
> >> -
> >> - if (iotlb->target_as != &address_space_memory) {
> >> - error_report("Wrong target AS \"%s\", only system memory is allowed",
> >> - iotlb->target_as->name ? iotlb->target_as->name : "none");
> >> - return;
> >> - }
> >> + bool ret = false;
> >> + bool writable = iotlb->perm & IOMMU_WO;
> >>
> >> /*
> >> * The IOMMU TLB entry we have just covers translation through
> >> @@ -322,12 +311,13 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> >> rcu_read_lock();
> >> mr = address_space_translate(&address_space_memory,
> >> iotlb->translated_addr,
> >> - &xlat, &len, iotlb->perm & IOMMU_WO);
> >> + &xlat, &len, writable);
> >> if (!memory_region_is_ram(mr)) {
> >> error_report("iommu map to non memory area %"HWADDR_PRIx"",
> >> xlat);
> >> goto out;
> >> }
> >> +
> >> /*
> >> * Translation truncates length to the IOMMU page size,
> >> * check that it did not truncate too much.
> >> @@ -337,11 +327,41 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> >> goto out;
> >> }
> >>
> >> + *vaddr = memory_region_get_ram_ptr(mr) + xlat;
> >> + *read_only = !writable || mr->readonly;
> >> + ret = true;
> >> +
> >> +out:
> >> + rcu_read_unlock();
> >> + return ret;
> >> +}
> >> +
> >> +static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> >> +{
> >> + VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
> >> + VFIOContainer *container = giommu->container;
> >> + hwaddr iova = iotlb->iova + giommu->iommu_offset;
> >> + bool read_only;
> >> + void *vaddr;
> >> + int ret;
> >> +
> >> + trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : "MAP",
> >> + iova, iova + iotlb->addr_mask);
> >> +
> >> + if (iotlb->target_as != &address_space_memory) {
> >> + error_report("Wrong target AS \"%s\", only system memory is allowed",
> >> + iotlb->target_as->name ? iotlb->target_as->name : "none");
> >> + return;
> >> + }
> >> +
> >> + if (!vfio_get_vaddr(iotlb, &vaddr, &read_only)) {
> >> + return;
> >> + }
> >> +
> >> if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
> >> - vaddr = memory_region_get_ram_ptr(mr) + xlat;
> >> ret = vfio_dma_map(container, iova,
> >> iotlb->addr_mask + 1, vaddr,
> >> - !(iotlb->perm & IOMMU_WO) || mr->readonly);
> >> + read_only);
> >> if (ret) {
> >> error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
> >> "0x%"HWADDR_PRIx", %p) = %d (%m)",
> >> @@ -357,8 +377,6 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> >> iotlb->addr_mask + 1, ret);
> >> }
> >> }
> >> -out:
> >> - rcu_read_unlock();
> >
> > The comment from v4 still needs input from Paolo, is it valid to make
> > use of vaddr (based on address_space_translate ->
> > memory_region_get_ram_ptr) outside of the rcu read lock or could future
> > BQL reduction efforts allow this to race?
>
> You need to keep a reference to the MemoryRegion if you do
> rcu_read_unlock. But it's simpler to call vfio_get_vaddr within
> rcu_read_lock, and keep the lock/unlock in vfio_iommu_map_notify.
Right, a memory_region_{un}ref() would be another option.
> You probably should also put a comment about why VFIO does *not* need to
> keep a reference between vfio_dma_map and vfio_dma_unmap (which doesn't
> sound easy to do either). Would any well-behaved guest invalidate the
> IOMMU page tables before a memory hot-unplug?
Hmm, we do take a reference in vfio_listener_region_add(), but this is
of course to the iommu region not to the RAM region we're translating.
In the non-vIOMMU case we would be holding a reference to the memory
region backing a DMA mapping. I would expect a well behaved guest to
evacuate DMA mappings targeting a hotplug memory region before it gets
ejected, but how much do we want to rely on well behaved guests.
Perhaps we should be taking a reference for each mapping entry, though
this makes Peter's plans to invalidate the entire address space much
more difficult. Thanks,
Alex
next prev parent reply other threads:[~2017-01-25 17:36 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-24 10:25 [Qemu-devel] [PATCH v5 00/18] VT-d: vfio enablement and misc enhances Peter Xu
2017-01-24 10:25 ` [Qemu-devel] [PATCH v5 01/18] vfio: trace map/unmap for notify as well Peter Xu
2017-01-24 10:25 ` [Qemu-devel] [PATCH v5 02/18] vfio: introduce vfio_get_vaddr() Peter Xu
2017-01-24 16:29 ` Alex Williamson
2017-01-25 4:32 ` Peter Xu
2017-01-25 16:43 ` Alex Williamson
2017-01-25 17:16 ` Paolo Bonzini
2017-01-26 6:26 ` Peter Xu
2017-01-25 17:11 ` Paolo Bonzini
2017-01-25 17:36 ` Alex Williamson [this message]
2017-01-25 17:40 ` Paolo Bonzini
2017-01-25 18:36 ` Alex Williamson
2017-01-25 19:42 ` Paolo Bonzini
2017-01-25 20:09 ` Alex Williamson
2017-01-26 6:46 ` Peter Xu
2017-01-26 7:12 ` Peter Xu
2017-01-26 10:55 ` Paolo Bonzini
2017-01-26 12:01 ` Peter Xu
2017-01-24 10:25 ` [Qemu-devel] [PATCH v5 03/18] vfio: allow to notify unmap for very large region Peter Xu
2017-01-24 16:32 ` Alex Williamson
2017-01-31 3:35 ` David Gibson
2017-02-03 7:30 ` Peter Xu
2017-01-24 10:25 ` [Qemu-devel] [PATCH v5 04/18] intel_iommu: add "caching-mode" option Peter Xu
2017-01-24 10:25 ` [Qemu-devel] [PATCH v5 05/18] intel_iommu: simplify irq region translation Peter Xu
2017-01-24 10:25 ` [Qemu-devel] [PATCH v5 06/18] intel_iommu: renaming gpa to iova where proper Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 07/18] intel_iommu: fix trace for inv desc handling Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 08/18] intel_iommu: fix trace for addr translation Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 09/18] intel_iommu: vtd_slpt_level_shift check level Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 10/18] memory: add section range info for IOMMU notifier Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 11/18] memory: provide IOMMU_NOTIFIER_FOREACH macro Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 12/18] memory: provide iommu_replay_all() Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 13/18] memory: introduce memory_region_notify_one() Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 14/18] memory: add MemoryRegionIOMMUOps.replay() callback Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 15/18] intel_iommu: provide its own replay() callback Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 16/18] intel_iommu: do replay when context invalidate Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 17/18] intel_iommu: allow dynamic switch of IOMMU region Peter Xu
2017-01-24 10:26 ` [Qemu-devel] [PATCH v5 18/18] intel_iommu: enable vfio devices Peter Xu
2017-01-24 11:49 ` [Qemu-devel] [PATCH v5 00/18] VT-d: vfio enablement and misc enhances Peter Xu
2017-01-24 14:48 ` Michael S. Tsirkin
2017-01-25 4:48 ` Peter Xu
2017-01-25 14:26 ` Michael S. Tsirkin
2017-01-26 7:16 ` Peter Xu
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=20170125103642.5f4232a9@t450s.home \
--to=alex.williamson@redhat.com \
--cc=bd.aviv@gmail.com \
--cc=jan.kiszka@siemens.com \
--cc=jasowang@redhat.com \
--cc=kevin.tian@intel.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=tianyu.lan@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).