From: Wang Wensheng wangwensheng4@huawei.com
This reverts commit 730bfcab402f846d64906d3d07fcbac9e1a9239e. --- include/linux/share_pool.h | 90 ++++++++++++++++++++++- mm/share_pool.c | 144 ++++++++++++++++++++++++++++++++----- 2 files changed, 214 insertions(+), 20 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 1432aaa08087..406b59aa76ec 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -250,31 +250,53 @@ static inline void sp_init_mm(struct mm_struct *mm) * Those interfaces are exported for modules */ extern int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id); +extern int sp_group_add_task(int pid, int spg_id); + extern int mg_sp_group_del_task(int pid, int spg_id); +extern int sp_group_del_task(int pid, int spg_id); + extern int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num); +extern int sp_group_id_by_pid(int pid); + +extern int sp_group_walk(int spg_id, void *data, int (*func)(struct mm_struct *mm, void *)); extern int proc_sp_group_state(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task);
+extern void *sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id); extern void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id); + +extern int sp_free(unsigned long addr, int id); extern int mg_sp_free(unsigned long addr, int id);
+extern void *sp_make_share_k2u(unsigned long kva, unsigned long size, + unsigned long sp_flags, int pid, int spg_id); extern void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, unsigned long sp_flags, int pid, int spg_id); + +extern void *sp_make_share_u2k(unsigned long uva, unsigned long size, int pid); extern void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid); -extern int mg_sp_unshare(unsigned long va, unsigned long size, int spg_id);
+extern int sp_unshare(unsigned long va, unsigned long size, int pid, int spg_id); +extern int mg_sp_unshare(unsigned long va, unsigned long size, int id); + +extern int sp_walk_page_range(unsigned long uva, unsigned long size, + struct task_struct *tsk, struct sp_walk_data *sp_walk_data); extern int mg_sp_walk_page_range(unsigned long uva, unsigned long size, struct task_struct *tsk, struct sp_walk_data *sp_walk_data);
+extern void sp_walk_page_free(struct sp_walk_data *sp_walk_data); extern void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data);
extern int sp_register_notifier(struct notifier_block *nb); extern int sp_unregister_notifier(struct notifier_block *nb);
+extern bool sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid); extern bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid);
+extern bool is_sharepool_addr(unsigned long addr); extern bool mg_is_sharepool_addr(unsigned long addr);
+extern int sp_id_of_current(void); extern int mg_sp_id_of_current(void);
extern void sp_area_drop(struct vm_area_struct *vma); @@ -326,11 +348,21 @@ static inline int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) return -EPERM; }
+static inline int sp_group_add_task(int pid, int spg_id) +{ + return -EPERM; +} + static inline int mg_sp_group_del_task(int pid, int spg_id) { return -EPERM; }
+static inline int sp_group_del_task(int pid, int spg_id) +{ + return -EPERM; +} + static inline int sp_group_exit(struct mm_struct *mm) { return 0; @@ -345,38 +377,74 @@ static inline int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num) return -EPERM; }
+static inline int sp_group_id_by_pid(int pid) +{ + return -EPERM; +} + static inline int proc_sp_group_state(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) { return -EPERM; }
+static inline void *sp_alloc(unsigned long size, unsigned long sp_flags, int sp_id) +{ + return NULL; +} + static inline void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id) { return NULL; }
+static inline int sp_free(unsigned long addr, int id) +{ + return -EPERM; +} + static inline int mg_sp_free(unsigned long addr, int id) { return -EPERM; }
+static inline void *sp_make_share_k2u(unsigned long kva, unsigned long size, + unsigned long sp_flags, int pid, int spg_id) +{ + return NULL; +} + static inline void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, unsigned long sp_flags, int pid, int spg_id) { return NULL; }
+static inline void *sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) +{ + return NULL; +} + static inline void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) { return NULL; }
+static inline int sp_unshare(unsigned long va, unsigned long size, int pid, int spg_id) +{ + return -EPERM; +} + static inline int mg_sp_unshare(unsigned long va, unsigned long size, int id) { return -EPERM; }
+static inline int sp_id_of_current(void) +{ + return -EPERM; +} + static inline int mg_sp_id_of_current(void) { return -EPERM; @@ -390,12 +458,22 @@ static inline void sp_area_drop(struct vm_area_struct *vma) { }
+static inline int sp_walk_page_range(unsigned long uva, unsigned long size, + struct task_struct *tsk, struct sp_walk_data *sp_walk_data) +{ + return 0; +} + static inline int mg_sp_walk_page_range(unsigned long uva, unsigned long size, struct task_struct *tsk, struct sp_walk_data *sp_walk_data) { return 0; }
+static inline void sp_walk_page_free(struct sp_walk_data *sp_walk_data) +{ +} + static inline void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data) { } @@ -410,11 +488,21 @@ static inline int sp_unregister_notifier(struct notifier_block *nb) return -EPERM; }
+static inline bool sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) +{ + return false; +} + static inline bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) { return false; }
+static inline bool is_sharepool_addr(unsigned long addr) +{ + return false; +} + static inline bool mg_is_sharepool_addr(unsigned long addr) { return false; diff --git a/mm/share_pool.c b/mm/share_pool.c index ba3e32da6c0d..e787ececc355 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -1052,6 +1052,38 @@ static struct sp_group *__sp_find_spg(int pid, int spg_id) return spg; }
+/** + * sp_group_id_by_pid() - Get the sp_group ID of a process. + * @pid: pid of target process. + * + * Return: + * 0 the sp_group ID. + * -ENODEV target process doesn't belong to any sp_group. + */ +int sp_group_id_by_pid(int pid) +{ + struct sp_group *spg; + int spg_id = -ENODEV; + + if (!sp_is_enabled()) + return -EOPNOTSUPP; + + check_interrupt_context(); + + spg = __sp_find_spg(pid, SPG_ID_DEFAULT); + if (!spg) + return -ENODEV; + + down_read(&spg->rw_lock); + if (spg_valid(spg)) + spg_id = spg->id; + up_read(&spg->rw_lock); + + sp_group_drop(spg); + return spg_id; +} +EXPORT_SYMBOL_GPL(sp_group_id_by_pid); + /** * mp_sp_group_id_by_pid() - Get the sp_group ID array of a process. * @pid: pid of target process. @@ -1600,6 +1632,12 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) } EXPORT_SYMBOL_GPL(mg_sp_group_add_task);
+int sp_group_add_task(int pid, int spg_id) +{ + return mg_sp_group_add_task(pid, PROT_READ | PROT_WRITE, spg_id); +} +EXPORT_SYMBOL_GPL(sp_group_add_task); + /** * mg_sp_group_del_task() - delete a process from a sp group. * @pid: the pid of the task to be deleted @@ -1699,7 +1737,13 @@ int mg_sp_group_del_task(int pid, int spg_id) } EXPORT_SYMBOL_GPL(mg_sp_group_del_task);
-int mg_sp_id_of_current(void) +int sp_group_del_task(int pid, int spg_id) +{ + return mg_sp_group_del_task(pid, spg_id); +} +EXPORT_SYMBOL_GPL(sp_group_del_task); + +int sp_id_of_current(void) { int ret, spg_id; struct sp_group_master *master; @@ -1731,6 +1775,12 @@ int mg_sp_id_of_current(void)
return spg_id; } +EXPORT_SYMBOL_GPL(sp_id_of_current); + +int mg_sp_id_of_current(void) +{ + return sp_id_of_current(); +} EXPORT_SYMBOL_GPL(mg_sp_id_of_current);
/* the caller must hold sp_area_lock */ @@ -2199,7 +2249,7 @@ static int sp_free_get_spa(struct sp_free_context *fc) }
/** - * mg_sp_free() - Free the memory allocated by mg_sp_alloc(). + * sp_free() - Free the memory allocated by sp_alloc(). * @addr: the starting VA of the memory. * @id: Address space identifier, which is used to distinguish the addr. * @@ -2208,7 +2258,7 @@ static int sp_free_get_spa(struct sp_free_context *fc) * * -EINVAL - the memory can't be found or was not allocted by share pool. * * -EPERM - the caller has no permision to free the memory. */ -int mg_sp_free(unsigned long addr, int id) +int sp_free(unsigned long addr, int id) { int ret = 0; struct sp_free_context fc = { @@ -2239,6 +2289,12 @@ int mg_sp_free(unsigned long addr, int id) out: return ret; } +EXPORT_SYMBOL_GPL(sp_free); + +int mg_sp_free(unsigned long addr, int id) +{ + return sp_free(addr, id); +} EXPORT_SYMBOL_GPL(mg_sp_free);
/* wrapper of __do_mmap() and the caller must hold down_write(&mm->mmap_lock). */ @@ -2565,7 +2621,7 @@ static void sp_alloc_finish(int result, struct sp_area *spa, }
/** - * mg_sp_alloc() - Allocate shared memory for all the processes in a sp_group. + * sp_alloc() - Allocate shared memory for all the processes in a sp_group. * @size: the size of memory to allocate. * @sp_flags: how to allocate the memory. * @spg_id: the share group that the memory is allocated to. @@ -2576,7 +2632,7 @@ static void sp_alloc_finish(int result, struct sp_area *spa, * * if succeed, return the starting address of the shared memory. * * if fail, return the pointer of -errno. */ -void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id) +void *sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id) { struct sp_area *spa = NULL; int ret = 0; @@ -2617,6 +2673,12 @@ void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id) else return (void *)(spa->va_start); } +EXPORT_SYMBOL_GPL(sp_alloc); + +void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id) +{ + return sp_alloc(size, sp_flags, spg_id); +} EXPORT_SYMBOL_GPL(mg_sp_alloc);
/** @@ -2917,7 +2979,7 @@ static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc) }
/** - * mg_sp_make_share_k2u() - Share kernel memory to current process or an sp_group. + * sp_make_share_k2u() - Share kernel memory to current process or an sp_group. * @kva: the VA of shared kernel memory. * @size: the size of shared kernel memory. * @sp_flags: how to allocate the memory. We only support SP_DVPP. @@ -2933,7 +2995,7 @@ static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc) * * if succeed, return the shared user address to start at. * * if fail, return the pointer of -errno. */ -void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, +void *sp_make_share_k2u(unsigned long kva, unsigned long size, unsigned long sp_flags, int pid, int spg_id) { void *uva; @@ -2971,6 +3033,13 @@ void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, out: return sp_k2u_finish(uva, &kc); } +EXPORT_SYMBOL_GPL(sp_make_share_k2u); + +void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, + unsigned long sp_flags, int pid, int spg_id) +{ + return sp_make_share_k2u(kva, size, sp_flags, pid, spg_id); +} EXPORT_SYMBOL_GPL(mg_sp_make_share_k2u);
static int sp_pmd_entry(pmd_t *pmd, unsigned long addr, @@ -3209,7 +3278,7 @@ static void __sp_walk_page_free(struct sp_walk_data *data) }
/** - * mg_sp_make_share_u2k() - Share user memory of a specified process to kernel. + * sp_make_share_u2k() - Share user memory of a specified process to kernel. * @uva: the VA of shared user memory * @size: the size of shared user memory * @pid: the pid of the specified process(Not currently in use) @@ -3218,7 +3287,7 @@ static void __sp_walk_page_free(struct sp_walk_data *data) * * if success, return the starting kernel address of the shared memory. * * if failed, return the pointer of -errno. */ -void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) +void *sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) { int ret = 0; struct mm_struct *mm = current->mm; @@ -3277,6 +3346,12 @@ void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) kvfree(sp_walk_data.pages); return p; } +EXPORT_SYMBOL_GPL(sp_make_share_u2k); + +void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) +{ + return sp_make_share_u2k(uva, size, pid); +} EXPORT_SYMBOL_GPL(mg_sp_make_share_u2k);
/* @@ -3483,7 +3558,7 @@ static int sp_unshare_kva(unsigned long kva, unsigned long size) }
/** - * mg_sp_unshare() - Unshare the kernel or user memory which shared by calling + * sp_unshare() - Unshare the kernel or user memory which shared by calling * sp_make_share_{k2u,u2k}(). * @va: the specified virtual address of memory * @size: the size of unshared memory @@ -3492,7 +3567,7 @@ static int sp_unshare_kva(unsigned long kva, unsigned long size) * * Return: 0 for success, -errno on failure. */ -int mg_sp_unshare(unsigned long va, unsigned long size, int spg_id) +int sp_unshare(unsigned long va, unsigned long size, int pid, int spg_id) { int ret = 0;
@@ -3518,10 +3593,16 @@ int mg_sp_unshare(unsigned long va, unsigned long size, int spg_id)
return ret; } +EXPORT_SYMBOL_GPL(sp_unshare); + +int mg_sp_unshare(unsigned long va, unsigned long size, int id) +{ + return sp_unshare(va, size, 0, id); +} EXPORT_SYMBOL_GPL(mg_sp_unshare);
/** - * mg_sp_walk_page_range() - Walk page table with caller specific callbacks. + * sp_walk_page_range() - Walk page table with caller specific callbacks. * @uva: the start VA of user memory. * @size: the size of user memory. * @tsk: task struct of the target task. @@ -3532,7 +3613,7 @@ EXPORT_SYMBOL_GPL(mg_sp_unshare); * When return 0, sp_walk_data describing [uva, uva+size) can be used. * When return -errno, information in sp_walk_data is useless. */ -int mg_sp_walk_page_range(unsigned long uva, unsigned long size, +int sp_walk_page_range(unsigned long uva, unsigned long size, struct task_struct *tsk, struct sp_walk_data *sp_walk_data) { struct mm_struct *mm; @@ -3571,13 +3652,20 @@ int mg_sp_walk_page_range(unsigned long uva, unsigned long size,
return ret; } +EXPORT_SYMBOL_GPL(sp_walk_page_range); + +int mg_sp_walk_page_range(unsigned long uva, unsigned long size, + struct task_struct *tsk, struct sp_walk_data *sp_walk_data) +{ + return sp_walk_page_range(uva, size, tsk, sp_walk_data); +} EXPORT_SYMBOL_GPL(mg_sp_walk_page_range);
/** - * mg_sp_walk_page_free() - Free the sp_walk_data structure. + * sp_walk_page_free() - Free the sp_walk_data structure. * @sp_walk_data: a structure of a page pointer array to be freed. */ -void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data) +void sp_walk_page_free(struct sp_walk_data *sp_walk_data) { if (!sp_is_enabled()) return; @@ -3589,6 +3677,12 @@ void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data)
__sp_walk_page_free(sp_walk_data); } +EXPORT_SYMBOL_GPL(sp_walk_page_free); + +void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data) +{ + sp_walk_page_free(sp_walk_data); +} EXPORT_SYMBOL_GPL(mg_sp_walk_page_free);
int sp_register_notifier(struct notifier_block *nb) @@ -3605,7 +3699,7 @@ EXPORT_SYMBOL_GPL(sp_unregister_notifier);
static bool is_sp_dynamic_dvpp_addr(unsigned long addr); /** - * mg_sp_config_dvpp_range() - User can config the share pool start address + * sp_config_dvpp_range() - User can config the share pool start address * of each Da-vinci device. * @start: the value of share pool start * @size: the value of share pool @@ -3616,7 +3710,7 @@ static bool is_sp_dynamic_dvpp_addr(unsigned long addr); * Return false if parameter invalid or has been set up. * This functuon has no concurrent problem. */ -bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) +bool sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) { int ret; bool err = false; @@ -3667,6 +3761,12 @@ bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid)
return err; } +EXPORT_SYMBOL_GPL(sp_config_dvpp_range); + +bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) +{ + return sp_config_dvpp_range(start, size, device_id, pid); +} EXPORT_SYMBOL_GPL(mg_sp_config_dvpp_range);
static bool is_sp_reserve_addr(unsigned long addr) @@ -3690,16 +3790,22 @@ static bool is_sp_dynamic_dvpp_addr(unsigned long addr) }
/** - * mg_is_sharepool_addr() - Check if a user memory address belongs to share pool. + * is_sharepool_addr() - Check if a user memory address belongs to share pool. * @addr: the userspace address to be checked. * * Return true if addr belongs to share pool, or false vice versa. */ -bool mg_is_sharepool_addr(unsigned long addr) +bool is_sharepool_addr(unsigned long addr) { return sp_is_enabled() && ((is_sp_reserve_addr(addr) || is_sp_dynamic_dvpp_addr(addr))); } +EXPORT_SYMBOL_GPL(is_sharepool_addr); + +bool mg_is_sharepool_addr(unsigned long addr) +{ + return is_sharepool_addr(addr); +} EXPORT_SYMBOL_GPL(mg_is_sharepool_addr);
int sp_node_id(struct vm_area_struct *vma)