On Tue, Jul 30, 2019 at 07:21:31PM +0200, Eric Auger wrote: > @@ -464,19 +464,75 @@ static IOMMUTLBEntry > virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, > int iommu_idx) > { > IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr); > + VirtIOIOMMU *s = sdev->viommu; > uint32_t sid; > + viommu_endpoint *ep; > + viommu_mapping *mapping; > + viommu_interval interval; > + bool bypass_allowed; > + > + interval.low = addr; > + interval.high = addr + 1; > > IOMMUTLBEntry entry = { > .target_as = &address_space_memory, > .iova = addr, > .translated_addr = addr, > - .addr_mask = ~(hwaddr)0, > + .addr_mask = (1 << ctz32(s->config.page_size_mask)) - 1, > .perm = IOMMU_NONE, > }; > > + bypass_allowed = virtio_has_feature(s->acked_features, > + VIRTIO_IOMMU_F_BYPASS); > + > sid = virtio_iommu_get_sid(sdev); > > trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag); > + qemu_mutex_lock(&s->mutex); > + > + ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid)); > + if (!ep) { > + if (!bypass_allowed) { > + error_report("%s sid=%d is not known!!", __func__, sid);
Maybe use error_report_once() to avoid DOS attack? Also would it be good to unify the debug prints? I see both error_report() and qemu_log_mask() are used in the whole patchset. Or is that attempted? > + } else { > + entry.perm = flag; > + } > + goto unlock; > + } > + > + if (!ep->domain) { > + if (!bypass_allowed) { > + qemu_log_mask(LOG_GUEST_ERROR, > + "%s %02x:%02x.%01x not attached to any domain\n", > + __func__, PCI_BUS_NUM(sid), > + PCI_SLOT(sid), PCI_FUNC(sid)); > + } else { > + entry.perm = flag; > + } > + goto unlock; > + } > + > + mapping = g_tree_lookup(ep->domain->mappings, (gpointer)(&interval)); > + if (!mapping) { > + qemu_log_mask(LOG_GUEST_ERROR, > + "%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))) > { > + qemu_log_mask(LOG_GUEST_ERROR, > + "Permission error on 0x%"PRIx64"(%d): allowed=%d\n", > + addr, flag, mapping->flags); > + goto unlock; > + } > + entry.translated_addr = addr - mapping->virt_addr + mapping->phys_addr; > + entry.perm = flag; > + trace_virtio_iommu_translate_out(addr, entry.translated_addr, sid); > + > +unlock: > + qemu_mutex_unlock(&s->mutex); > return entry; > } > > -- > 2.20.1 > Regards, -- Peter Xu