From: Lijun Fang fanglijun3@huawei.com
ascend inclusion category: bugfix bugzilla: NA CVE: NA
------------
The svm mm_notifier and iommu_sva mm_notifier do the same unbind process, but the one do this unbind, another would not do it normally. Depressingly, new process allocate a pasid, that might be freed by the old process unbind in mult-process, when this allocation is between the two mm_notifier.
The svm_notifier_release() no need to call svm_unbind_cores(), as iommu-sva will do the unbind in its mm_notifier callback.
v2: add change log for this bugfix
Signed-off-by: Lijun Fang fanglijun3@huawei.com Reviewed-by: Li Zefan lizefan@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/char/svm.c | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-)
diff --git a/drivers/char/svm.c b/drivers/char/svm.c index d57d179..21a361c 100644 --- a/drivers/char/svm.c +++ b/drivers/char/svm.c @@ -568,26 +568,6 @@ static int svm_bind_core( return err; }
-static int svm_unbind_core( -#ifndef CONFIG_ACPI - struct device *dev, -#else - struct core_device *cdev, -#endif - void *data) -{ - struct svm_process *process = data; -#ifndef CONFIG_ACPI - struct core_device *cdev = to_core_device(dev); -#endif - - if (cdev->smmu_bypass) - return 0; - - iommu_sva_unbind_device(&cdev->dev, process->pasid); - return 0; -} - static void svm_bind_cores(struct svm_process *process) { #ifdef CONFIG_ACPI @@ -601,19 +581,6 @@ static void svm_bind_cores(struct svm_process *process) #endif }
-static void svm_unbind_cores(struct svm_process *process) -{ -#ifdef CONFIG_ACPI - struct core_device *pos = NULL; - - list_for_each_entry(pos, &child_list, entry) { - svm_unbind_core(pos, process); - } -#else - device_for_each_child(process->sdev->dev, process, svm_unbind_core); -#endif -} - static void svm_process_free(struct rcu_head *rcu) { struct svm_process *process = NULL; @@ -657,7 +624,10 @@ static void svm_notifier_release(struct mmu_notifier *mn,
process = container_of(mn, struct svm_process, notifier);
- svm_unbind_cores(process); + /* + * No need to call svm_unbind_cores(), as iommu-sva will do the + * unbind in its mm_notifier callback. + */
mutex_lock(&svm_process_mutex); svm_process_release(process);