diff mbox series

[RFC,2/3] um: clean up init_new_context()

Message ID 20230923003737.c4494349a21a.I909ad341512baae41901f4e5b8ccb57ce9fd0d6a@changeid
State Needs Review / ACK
Headers show
Series um: clean up mm creation - another attempt | expand

Commit Message

Johannes Berg Sept. 22, 2023, 10:37 p.m. UTC
From: Johannes Berg <johannes.berg@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.berg@intel.com>
---
 arch/um/kernel/skas/mmu.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
diff mbox series

Patch

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 = &current->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) {