From: Paolo Bonzini <pbonzini@redhat.com>
To: Alex Williamson <alex.williamson@redhat.com>,
Peter Xu <peterx@redhat.com>
Cc: 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 18:11:37 +0100 [thread overview]
Message-ID: <9ef03816-0bef-f54b-63fe-daf27eab4a40@redhat.com> (raw)
In-Reply-To: <20170124092905.41832531@t450s.home>
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.
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?
Paolo
>> }
>>
>> static void vfio_listener_region_add(MemoryListener *listener,
>
>
>
next prev parent reply other threads:[~2017-01-25 17:11 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 [this message]
2017-01-25 17:36 ` Alex Williamson
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=9ef03816-0bef-f54b-63fe-daf27eab4a40@redhat.com \
--to=pbonzini@redhat.com \
--cc=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=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).