On Fri, Oct 25, 2019 at 10:02:36AM +0800, [email protected] wrote:
> > It already exist it is call mmu notifier, you can register an mmu notifier
> > and get callback once the mm exit.
> Currently we register mm_exit for sva path, as suggested by Jean.
Yes that's called from a release() mmu_notifier callback.
> static struct iommu_sva_ops uacce_sva_ops = {
> .mm_exit = uacce_sva_exit,
> };
> iommu_sva_set_ops(handle, &uacce_sva_ops);
>
> Still not certain do we have to register mm_exit for both case,
> sva and !sva, since it is a common situation.
I was wondering about that. For !SVA, since all DMA memory is mapped
through mmap, you'll be notified by the vma->vm_ops->close() callback when
the mm disappears, so I don't think you need a mm release notifier.
However that callback will just remove the IOMMU mappings and invalidate
TLBs, but the queue might still be running and since no fault handler is
registered, the IOMMU driver will flood the kernel logs with translation
faults. Similarly, the user can simply start the queue and call munmap()
for the same result, or even just program the queue with invalid DMA
addresses.
What we could do is when !SVA, register an IOMMU fault handler (the shiny
new iommu_register_device_fault_handler()) and consume all faults
ourselves. That will at least prevent userspace from flooding the kernel
logs. Even better, as soon as we get a fault notification, we could stop
the queue associated to that DMA address to prevent further faults, though
we'll still receive those that are already pending in the fault queue.
Thanks,
Jean