Default replay does not work with virtio-iommu, so this patch provide virtio-iommu replay functionality.
Signed-off-by: Bharat Bhushan <bharat.bhus...@nxp.com> --- v3->v4: - Replay functionality moved in separate patch - No other changes hw/virtio/trace-events | 1 + hw/virtio/virtio-iommu.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 251b595..840d54f 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -51,3 +51,4 @@ virtio_iommu_fill_none_property(uint32_t devid) "devid=%d" virtio_iommu_set_page_size_mask(const char *iommu_mr, uint64_t mask) "mr=%s page_size_mask=0x%"PRIx64 virtio_iommu_notify_map(const char *name, hwaddr iova, hwaddr paddr, hwaddr map_size) "mr=%s iova=0x%"PRIx64" pa=0x%" PRIx64" size=0x%"PRIx64"" virtio_iommu_notify_unmap(const char *name, hwaddr iova, hwaddr map_size) "mr=%s iova=0x%"PRIx64" size=0x%"PRIx64"" +virtio_iommu_remap(hwaddr iova, hwaddr pa, hwaddr size) "iova=0x%"PRIx64" pa=0x%" PRIx64" size=0x%"PRIx64"" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index ff91bce..d4d34cf 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -906,6 +906,43 @@ static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data) return (ua > ub) - (ua < ub); } +static gboolean virtio_iommu_remap(gpointer key, gpointer value, gpointer data) +{ + viommu_mapping *mapping = (viommu_mapping *) value; + IOMMUMemoryRegion *mr = (IOMMUMemoryRegion *) data; + + trace_virtio_iommu_remap(mapping->virt_addr, mapping->phys_addr, + mapping->size); + /* unmap previous entry and map again */ + virtio_iommu_notify_unmap(mr, mapping->virt_addr, mapping->size); + + virtio_iommu_notify_map(mr, mapping->virt_addr, mapping->phys_addr, + mapping->size); + return false; +} + +static void virtio_iommu_replay(IOMMUMemoryRegion *mr, IOMMUNotifier *n) +{ + IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr); + VirtIOIOMMU *s = sdev->viommu; + uint32_t sid; + viommu_dev *dev; + + sid = virtio_iommu_get_sid(sdev); + + qemu_mutex_lock(&s->mutex); + + dev = g_tree_lookup(s->devices, GUINT_TO_POINTER(sid)); + if (!dev || !dev->as) { + goto unlock; + } + + g_tree_foreach(dev->as->mappings, virtio_iommu_remap, mr); + +unlock: + qemu_mutex_unlock(&s->mutex); +} + static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); @@ -1003,6 +1040,7 @@ static void virtio_iommu_memory_region_class_init(ObjectClass *klass, imrc->translate = virtio_iommu_translate; imrc->set_page_size_mask = virtio_iommu_set_page_size_mask; + imrc->replay = virtio_iommu_replay; } static const TypeInfo virtio_iommu_info = { -- 1.9.3