From: Guo Mengqi guomengqi3@huawei.com
ascend inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4MUV2 CVE: NA
when k2u is being executed ont the whole sharepool group, and one process coredumps, k2u will skip the coredumped process and continue on the rest processes in the group.
Signed-off-by: Guo Mengqi guomengqi3@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- mm/share_pool.c | 50 +++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-)
diff --git a/mm/share_pool.c b/mm/share_pool.c index c9079e6a40b1a..ac97a68a70264 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -678,8 +678,25 @@ static unsigned long sp_mmap(struct mm_struct *mm, struct file *file, struct sp_area *spa, unsigned long *populate, unsigned long prot); static void sp_munmap(struct mm_struct *mm, unsigned long addr, unsigned long size); + +#define K2U_NORMAL 0 +#define K2U_COREDUMP 1 + +struct sp_k2u_context { + unsigned long kva; + unsigned long kva_aligned; + unsigned long size; + unsigned long size_aligned; + unsigned long sp_flags; + int state; + int spg_id; + bool to_task; + struct timespec64 start; + struct timespec64 end; +}; + static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa, - struct mm_struct *mm, unsigned long prot); + struct mm_struct *mm, unsigned long prot, struct sp_k2u_context *kc);
static void free_sp_group_id(int spg_id) { @@ -1334,7 +1351,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) spin_unlock(&sp_area_lock);
if (spa->type == SPA_TYPE_K2SPG && spa->kva) { - addr = sp_remap_kva_to_vma(spa->kva, spa, mm, prot); + addr = sp_remap_kva_to_vma(spa->kva, spa, mm, prot, NULL); if (IS_ERR_VALUE(addr)) pr_warn("add group remap k2u failed %ld\n", addr);
@@ -2606,7 +2623,7 @@ static unsigned long __sp_remap_get_pfn(unsigned long kva)
/* when called by k2u to group, always make sure rw_lock of spg is down */ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa, - struct mm_struct *mm, unsigned long prot) + struct mm_struct *mm, unsigned long prot, struct sp_k2u_context *kc) { struct vm_area_struct *vma; unsigned long ret_addr; @@ -2618,6 +2635,8 @@ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa, if (unlikely(mm->core_state)) { pr_err("k2u mmap: encountered coredump, abort\n"); ret_addr = -EBUSY; + if (kc) + kc->state = K2U_COREDUMP; goto put_mm; }
@@ -2703,7 +2722,7 @@ static void *sp_make_share_kva_to_task(unsigned long kva, unsigned long size, un
spa->kva = kva;
- uva = (void *)sp_remap_kva_to_vma(kva, spa, current->mm, prot); + uva = (void *)sp_remap_kva_to_vma(kva, spa, current->mm, prot, NULL); __sp_area_drop(spa); if (IS_ERR(uva)) pr_err("remap k2u to task failed %ld\n", PTR_ERR(uva)); @@ -2731,6 +2750,8 @@ static void *sp_make_share_kva_to_spg(unsigned long kva, unsigned long size, struct mm_struct *mm; struct sp_group_node *spg_node; void *uva = ERR_PTR(-ENODEV); + struct sp_k2u_context kc; + unsigned long ret_addr = -ENODEV;
down_read(&spg->rw_lock); spa = sp_alloc_area(size, sp_flags, spg, SPA_TYPE_K2SPG, current->tgid); @@ -2745,12 +2766,17 @@ static void *sp_make_share_kva_to_spg(unsigned long kva, unsigned long size,
list_for_each_entry(spg_node, &spg->procs, proc_node) { mm = spg_node->master->mm; - uva = (void *)sp_remap_kva_to_vma(kva, spa, mm, spg_node->prot); - if (IS_ERR(uva)) { + kc.state = K2U_NORMAL; + ret_addr = sp_remap_kva_to_vma(kva, spa, mm, spg_node->prot, &kc); + if (IS_ERR_VALUE(ret_addr)) { + if (kc.state == K2U_COREDUMP) + continue; + uva = (void *)ret_addr; pr_err("remap k2u to spg failed %ld\n", PTR_ERR(uva)); __sp_free(spg, spa->va_start, spa_size(spa), mm); goto out; } + uva = (void *)ret_addr; }
out: @@ -2775,18 +2801,6 @@ static bool vmalloc_area_set_flag(unsigned long kva, unsigned long flags) return false; }
-struct sp_k2u_context { - unsigned long kva; - unsigned long kva_aligned; - unsigned long size; - unsigned long size_aligned; - unsigned long sp_flags; - int spg_id; - bool to_task; - struct timespec64 start; - struct timespec64 end; -}; - static void trace_sp_k2u_begin(struct sp_k2u_context *kc) { if (!sysctl_sp_perf_k2u)
From: Guo Mengqi guomengqi3@huawei.com
ascend inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4MUV2 CVE: NA
when sp_alloc is being executed ont the whole sharepool group, and one process coredumps, allocation will skip the coredumped process and continue on the rest processes in the group.
Signed-off-by: Guo Mengqi guomengqi3@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- mm/share_pool.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/mm/share_pool.c b/mm/share_pool.c index ac97a68a70264..428742f5d4044 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -2163,6 +2163,7 @@ static unsigned long sp_mmap(struct mm_struct *mm, struct file *file, #define ALLOC_NORMAL 1 #define ALLOC_RETRY 2 #define ALLOC_NOMEM 3 +#define ALLOC_COREDUMP 4
struct sp_alloc_context { struct sp_group *spg; @@ -2341,8 +2342,7 @@ static int sp_alloc_mmap(struct mm_struct *mm, struct sp_area *spa, down_write(&mm->mmap_sem); if (unlikely(mm->core_state)) { up_write(&mm->mmap_sem); - sp_alloc_unmap(mm, spa, spg_node); - ac->state = ALLOC_NOMEM; + ac->state = ALLOC_COREDUMP; pr_info("allocation encountered coredump\n"); return -EFAULT; } @@ -2484,7 +2484,8 @@ static int __sp_alloc_mmap_populate(struct mm_struct *mm, struct sp_area *spa, static int sp_alloc_mmap_populate(struct sp_area *spa, struct sp_alloc_context *ac) { - int ret; + int ret = -EINVAL; + int mmap_ret = 0; struct mm_struct *mm; struct sp_group_node *spg_node;
@@ -2494,9 +2495,19 @@ static int sp_alloc_mmap_populate(struct sp_area *spa, /* create mapping for each process in the group */ list_for_each_entry(spg_node, &spa->spg->procs, proc_node) { mm = spg_node->master->mm; - ret = __sp_alloc_mmap_populate(mm, spa, spg_node, ac); - if (ret) - return ret; + mmap_ret = __sp_alloc_mmap_populate(mm, spa, spg_node, ac); + if (mmap_ret) { + if (ac->state != ALLOC_COREDUMP) + return mmap_ret; + if (ac->spg == spg_none) { + sp_alloc_unmap(mm, spa, spg_node); + pr_err("dvpp allocation failed due to coredump"); + return mmap_ret; + } + ac->state = ALLOC_NORMAL; + continue; + } + ret = mmap_ret; } } return ret;