From: Zhou Guanghui zhouguanghui1@huawei.com
ascend inclusion category: bugfix bugzilla: NA DTS: NA CVE: NA
-----------------------------------------------------------------
In the SVA scenario, the master device of the SMMU can access the address space of the process by the operation of binding proces. The page table of the process is shared by the MMU and SMMU, In this case, if some addrss range cannot be accessed through the MMU, access to this address range needs to be isolated from the process page table.
If the default domain of the SMMU is used, the isolation can be achieved. However, the address space created by default domain do not like the address space of the process which can be shared by multiple SMMUs.
Therefore, we add a shadow virtual space of process. This address space is used only by the SMMU.
Signed-off-by: Zhou Guanghui zhouguanghui1@huawei.com Signed-off-by: Zhang Zekun zhangzekun11@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com --- arch/arm64/Kconfig | 15 +++++++++++++++ include/linux/ascend_smmu.h | 31 +++++++++++++++++++++++++++++++ kernel/fork.c | 1 + mm/mmap.c | 1 + 4 files changed, 48 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a0bba8e5426a..762e0243145b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2084,6 +2084,21 @@ config ASCEND_SHARE_POOL This feature allows multiple processes to share virtual memory both in kernel and user level, which is only enabled for ascend platform.
+config ASCEND_SVSP + bool "Enable support for SVSP" + default n + depends on ARM_SMMU_V3_SVA + help + SVSP means Shadow Virtual Space of Process, which is an IO space used for + master device of SMMU. + + This space is only used for the master device, since the target address + after traslation by MMU is not an accessible physical address, but can + accessible by SMMU. + + Therefore, in the sva scenario, an svsp is created for each target process + address space. + endif
endmenu diff --git a/include/linux/ascend_smmu.h b/include/linux/ascend_smmu.h index 8350feb4e358..4a4615acdfa2 100644 --- a/include/linux/ascend_smmu.h +++ b/include/linux/ascend_smmu.h @@ -47,4 +47,35 @@ struct agent_smmu_atos_data {
extern int agent_smmu_iova_to_phys(struct agent_smmu_atos_data *data, int *succeed);
+extern int svm_get_pasid(pid_t vpid, int dev_id); + +#ifdef CONFIG_ASCEND_SVSP +extern unsigned long svm_svsp_mmap(unsigned long len, int pasid); +extern int svm_svsp_remap_range(unsigned long va, unsigned long iova, + size_t size, int pasid, pgprot_t prot); +extern void svm_svsp_munmap(unsigned long start, unsigned long len, int pasid); +extern struct mm_struct *svm_svsp_of_mm(struct mm_struct *mm); +#else +static inline unsigned long svm_svsp_mmap(unsigned long len, int pasid) +{ + return -EINVAL; +} + +static inline int svm_svsp_remap_range(unsigned long va, unsigned long iova, + size_t size, int pasid, pgprot_t prot) +{ + return -EINVAL; +} + +static inline void svm_svsp_munmap(unsigned long start, unsigned long len, int pasid) +{ + return; +} + +static inline struct mm_struct *svm_svsp_of_mm(struct mm_struct *mm) +{ + return NULL; +} +#endif + #endif diff --git a/kernel/fork.c b/kernel/fork.c index 0ac2ae1e8f85..150c970e84f4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1115,6 +1115,7 @@ struct mm_struct *mm_alloc(void)
return mm_init(mm, current, current_user_ns()); } +EXPORT_SYMBOL_GPL(mm_alloc);
static inline void __mmput(struct mm_struct *mm) { diff --git a/mm/mmap.c b/mm/mmap.c index 568bc1b68fae..c17781bed8de 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -3216,6 +3216,7 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
return downgrade ? 1 : 0; } +EXPORT_SYMBOL(__do_munmap);
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf)