From: Johannes Berg <johannes.b...@intel.com> This function gets a context that's already copied from the old context if making a copy, or memset to 0 if not. This means we don't need to play games with current, even if those games are OK now since dup_mm() is only ever called with current->mm as the source.
Also memset() our context to 0 since we don't have in there anything that we need to keep - except the LDT but we have to copy that separately, so make a temporary local copy. Signed-off-by: Johannes Berg <johannes.b...@intel.com> --- arch/um/kernel/skas/mmu.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 656fe16c9b63..ea0c37b92581 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -16,6 +16,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) { + struct mm_context _from_mm; struct mm_context *from_mm = NULL; struct mm_context *to_mm = &mm->context; unsigned long stack = 0; @@ -25,15 +26,26 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) if (stack == 0) goto out; + /* + * If the kernel wants a copy, it already copied the entire context. + * If not, it's all memset to 0. + * So we can detect here whether or not we should copy, and have the + * pid we should copy _from_ in our own context struct of the new mm. + */ + if (to_mm->id.u.pid) { + _from_mm = *to_mm; + from_mm = &_from_mm; + } + + memset(to_mm, 0, sizeof(*to_mm)); to_mm->id.stack = stack; - if (current->mm != NULL && current->mm != &init_mm) - from_mm = ¤t->mm->context; block_signals_trace(); if (from_mm) to_mm->id.u.pid = copy_context_skas0(stack, from_mm->id.u.pid); - else to_mm->id.u.pid = start_userspace(stack); + else + to_mm->id.u.pid = start_userspace(stack); unblock_signals_trace(); if (to_mm->id.u.pid < 0) { -- 2.41.0 _______________________________________________ linux-um mailing list linux-um@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-um