On Wed, Apr 14, 2021 at 7:59 AM Andrei Vagin <avagin@xxxxxxxxx> wrote: > This change introduces the new system call: > process_vm_exec(pid_t pid, struct sigcontext *uctx, unsigned long flags, > siginfo_t * uinfo, sigset_t *sigmask, size_t sizemask) > > process_vm_exec allows to execute the current process in an address > space of another process. [...] I still think that this whole API is fundamentally the wrong approach because it tries to shoehorn multiple usecases with different requirements into a single API. But that aside: > +static void swap_mm(struct mm_struct *prev_mm, struct mm_struct *target_mm) > +{ > + struct task_struct *tsk = current; > + struct mm_struct *active_mm; > + > + task_lock(tsk); > + /* Hold off tlb flush IPIs while switching mm's */ > + local_irq_disable(); > + > + sync_mm_rss(prev_mm); > + > + vmacache_flush(tsk); > + > + active_mm = tsk->active_mm; > + if (active_mm != target_mm) { > + mmgrab(target_mm); > + tsk->active_mm = target_mm; > + } > + tsk->mm = target_mm; I'm pretty sure you're not currently allowed to overwrite the ->mm pointer of a userspace thread. For example, zap_threads() assumes that all threads running under a process have the same ->mm. (And if you're fiddling with ->mm stuff, you should probably CC linux-mm@.) As far as I understand, only kthreads are allowed to do this (as implemented in kthread_use_mm()). > + switch_mm_irqs_off(active_mm, target_mm, tsk); > + local_irq_enable(); > + task_unlock(tsk); > +#ifdef finish_arch_post_lock_switch > + finish_arch_post_lock_switch(); > +#endif > + > + if (active_mm != target_mm) > + mmdrop(active_mm); > +}