From: Jean-Philippe Brucker jean-philippe.brucker@arm.com
ascend inclusion category: feature bugzilla: 14369 CVE: NA
--------------
commit https://patchwork.ozlabs.org/patch/822423/
When creating an iommu_process structure, register a notifier to be informed of changes to the virtual address space and to know when the process exits.
Two new operations are added to the IOMMU driver:
* process_invalidate when a range of addresses is unmapped, to let the IOMMU driver send TLB invalidations.
* process_exit when the mm is released. It's a bit more involved in this case, as the IOMMU driver has to tell all devices drivers to stop using this PASID, then clear the PASID table and invalidate TLBs.
Adding the notifier in the mix complicates process release. In one case device drivers free the process explicitly by calling unbind (or detaching the device). In the other case the process could crash before unbind, in which case the release notifier has to do all the work.
Signed-off-by: Jean-Philippe Brucker jean-philippe.brucker@arm.com Signed-off-by: Fang Lijun fanglijun3@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/linux/iommu.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 3ca9d171620e..dc78957b5544 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -122,9 +122,15 @@ struct iommu_process { int pasid; struct list_head domains; struct kref kref; +#ifdef CONFIG_MMU_NOTIFIER + struct mmu_notifier notifier; +#endif + struct mm_struct *mm;
/* Release callback for this process */ void (*release)(struct iommu_process *process); + /* For postponed release */ + struct rcu_head rcu; };
struct io_mm { @@ -278,6 +284,9 @@ struct iommu_sva_param { * @domain_free: free iommu domain * @attach_dev: attach device to an iommu domain * @detach_dev: detach device from an iommu domain + * @process_invalidate: Invalidate a range of mappings for a process. + * @process_exit: A process is exiting. Stop using the PASID, remove PASID entry + * and flush associated TLB entries. * @sva_device_init: initialize Shared Virtual Adressing for a device * @sva_device_shutdown: shutdown Shared Virtual Adressing for a device * @mm_alloc: allocate io_mm @@ -321,6 +330,10 @@ struct iommu_ops {
int (*attach_dev)(struct iommu_domain *domain, struct device *dev); void (*detach_dev)(struct iommu_domain *domain, struct device *dev); + void (*process_invalidate)(struct iommu_domain *domain, + struct iommu_process *process, + unsigned long iova, size_t size); + void (*process_exit)(struct iommu_domain *domain, struct iommu_process *process); int (*sva_device_init)(struct device *dev, struct iommu_sva_param *param); void (*sva_device_shutdown)(struct device *dev,