> -----Original Message----- > From: Eric Auger [mailto:eric.au...@redhat.com] > Sent: Tuesday, September 19, 2017 1:17 PM > To: eric.auger....@gmail.com; eric.au...@redhat.com; > peter.mayd...@linaro.org; alex.william...@redhat.com; m...@redhat.com; > qemu-...@nongnu.org; qemu-devel@nongnu.org; jean- > philippe.bruc...@arm.com > Cc: will.dea...@arm.com; kevin.t...@intel.com; marc.zyng...@arm.com; > christoffer.d...@linaro.org; drjo...@redhat.com; w...@redhat.com; > t...@semihalf.com; Bharat Bhushan <bharat.bhus...@nxp.com>; > pet...@redhat.com; linuc.dec...@gmail.com > Subject: [RFC v4 09/16] virtio-iommu: Implement translate > > This patch implements the translate callback > > Signed-off-by: Eric Auger <eric.au...@redhat.com> > --- > hw/virtio/trace-events | 1 + > hw/virtio/virtio-iommu.c | 39 > +++++++++++++++++++++++++++++++++++++-- > 2 files changed, 38 insertions(+), 2 deletions(-) > > diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index > da298c1..9010fbd 100644 > --- a/hw/virtio/trace-events > +++ b/hw/virtio/trace-events > @@ -45,3 +45,4 @@ virtio_iommu_put_as(uint32_t asid) "Free asid=%d" > virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t > next_low, uint64_t next_high) "Unmap left [0x%"PRIx64",0x%"PRIx64"], > new interval=[0x%"PRIx64",0x%"PRIx64"]" > virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t > next_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], > new interval=[0x%"PRIx64",0x%"PRIx64"]" > virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc > [0x%"PRIx64",0x%"PRIx64"]" > +virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, > uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d" > diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index > 6f1a7d1..db46a91 100644 > --- a/hw/virtio/virtio-iommu.c > +++ b/hw/virtio/virtio-iommu.c > @@ -496,19 +496,54 @@ static IOMMUTLBEntry > virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, > IOMMUAccessFlags flag) { > IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr); > + VirtIOIOMMU *s = sdev->viommu; > uint32_t sid; > + viommu_dev *dev; > + viommu_mapping *mapping; > + viommu_interval interval; > + > + interval.low = addr; > + interval.high = addr + 1; > > IOMMUTLBEntry entry = { > .target_as = &address_space_memory, > .iova = addr, > .translated_addr = addr, > - .addr_mask = ~(hwaddr)0, > - .perm = IOMMU_NONE, > + .addr_mask = (1 << ctz32(s->config.page_size_mask)) - 1, > + .perm = flag, > }; > > sid = virtio_iommu_get_sid(sdev); > > trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag); > + qemu_mutex_lock(&s->mutex); > + > + dev = g_tree_lookup(s->devices, GUINT_TO_POINTER(sid)); > + if (!dev) { > + /* device cannot be attached to another as */ > + printf("%s sid=%d is not known!!\n", __func__, sid); > + goto unlock; > + } > + > + mapping = g_tree_lookup(dev->as->mappings, (gpointer)(&interval));
Should check of !dev->as before accessing this. Thanks -Bharat > + if (!mapping) { > + printf("%s no mapping for 0x%"PRIx64" for sid=%d\n", __func__, > + addr, sid); > + goto unlock; > + } > + > + if (((flag & IOMMU_RO) && !(mapping->flags & > VIRTIO_IOMMU_MAP_F_READ)) || > + ((flag & IOMMU_WO) && !(mapping->flags & > VIRTIO_IOMMU_MAP_F_WRITE))) { > + error_report("Permission error on 0x%"PRIx64"(%d): allowed=%d", > + addr, flag, mapping->flags); > + entry.perm = IOMMU_NONE; > + goto unlock; > + } > + entry.translated_addr = addr - mapping->virt_addr + mapping- > >phys_addr, > + trace_virtio_iommu_translate_out(addr, entry.translated_addr, sid); > + > +unlock: > + qemu_mutex_unlock(&s->mutex); > return entry; > } > > -- > 2.5.5