From fc74d9d2c1832576c63a35e4073abc0c3eb4c393 Mon Sep 17 00:00:00 2001
From: Fang Lijun <fanglijun3@huawei.com>
Date: Sat, 30 Oct 2021 17:23:09 +0800
Subject: [PATCH] share pool: Add export __get_vm_area map_vm_area for ascend
 driver

ascend inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4EUVI
CVE: NA

-------------------------------------------------

Signed-off-by: Fang Lijun <fanglijun3@huawei.com>
Signed-off-by: Zhou Guanghui <zhouguanghui1@huawei.com>
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
Reviewed-by: Ding Tianhong <dingtianhong@huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
 include/linux/mm.h         |  6 ++++++
 include/linux/share_pool.h |  6 ------
 include/linux/vmalloc.h    |  4 ++++
 mm/vmalloc.c               | 19 +++++++++++++++++++
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7ee7214f17be..f801fa5e6028 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -156,6 +156,12 @@ extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *,
 /* test whether an address (unsigned long or pointer) is aligned to PAGE_SIZE */
 #define PAGE_ALIGNED(addr)	IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
 
+/* to align the pointer to the (next) PMD hugepage boundary */
+#define PMD_ALIGN(addr) ALIGN(addr, PMD_SIZE)
+
+/* test whether an address (unsigned long or pointer) is aligned to PMD_SIZE */
+#define PMD_ALIGNED(addr)   IS_ALIGNED((unsigned long)(addr), PMD_SIZE)
+
 /*
  * Linux kernel virtual memory manager primitives.
  * The idea being to have a "virtual" mm in the same way
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h
index e421587ff977..6bd03c3504c4 100644
--- a/include/linux/share_pool.h
+++ b/include/linux/share_pool.h
@@ -26,12 +26,6 @@
 
 #define MAX_DEVID 2	/* the max num of Da-vinci devices */
 
-/* to align the pointer to the (next) PMD boundary */
-#define PMD_ALIGN(addr)		ALIGN(addr, PMD_SIZE)
-
-/* test whether an address (unsigned long or pointer) is aligned to PMD_SIZE */
-#define PMD_ALIGNED(addr)	IS_ALIGNED((unsigned long)(addr), PMD_SIZE)
-
 extern int sysctl_share_pool_hugepage_enable;
 
 extern int sysctl_ac_mode;
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 298eff5579b2..7322909aed15 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -151,12 +151,16 @@ static inline size_t get_vm_area_size(const struct vm_struct *area)
 extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
 extern struct vm_struct *get_vm_area_caller(unsigned long size,
 					unsigned long flags, const void *caller);
+extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
+					unsigned long start, unsigned long end);
 extern struct vm_struct *__get_vm_area_caller(unsigned long size,
 					unsigned long flags,
 					unsigned long start, unsigned long end,
 					const void *caller);
 extern struct vm_struct *remove_vm_area(const void *addr);
 extern struct vm_struct *find_vm_area(const void *addr);
+extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
+					struct page **pages);
 
 #ifdef CONFIG_MMU
 int vmap_range(unsigned long addr, unsigned long end,
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 9bd49a700707..36f0e6d94a95 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2206,6 +2206,17 @@ void unmap_kernel_range(unsigned long addr, unsigned long size)
 	flush_tlb_kernel_range(addr, end);
 }
 
+int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page **pages)
+{
+	unsigned long addr = (unsigned long)area->addr;
+	int err;
+
+	err = map_kernel_range(addr, get_vm_area_size(area), prot, pages);
+
+	return err > 0 ? 0 : err;
+}
+EXPORT_SYMBOL_GPL(map_vm_area);
+
 static void setup_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
 			      unsigned long flags, const void *caller)
 {
@@ -2264,6 +2275,14 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 	return area;
 }
 
+struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
+						unsigned long start, unsigned long end)
+{
+	return __get_vm_area_node(size, 1, flags, start, end, NUMA_NO_NODE,
+				  GFP_KERNEL, __builtin_return_address(0));
+}
+EXPORT_SYMBOL_GPL(__get_vm_area);
+
 struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
 				       unsigned long start, unsigned long end,
 				       const void *caller)
-- 
GitLab