+int
+spawn_process(struct thread** created, ptr_t entry, bool with_ustack)
+{
+ struct proc_info* kproc = alloc_process();
+ struct proc_mm* mm = vmspace(kproc);
+
+ procvm_initvms_mount(mm);
+
+ struct thread* kthread = create_thread(kproc, with_ustack);
+
+ if (!kthread) {
+ procvm_unmount(mm);
+ delete_process(kproc);
+ return -1;
+ }
+
+ commit_process(kproc);
+ start_thread(kthread, entry);
+
+ procvm_unmount(mm);
+
+ if (created) {
+ *created = kthread;
+ }
+
+ return 0;
+}
+
+int
+spawn_process_usr(struct thread** created, char* path,
+ const char** argv, const char** envp)
+{
+ // FIXME remote injection of user stack not yet implemented
+
+ struct proc_info* proc = alloc_process();
+ struct proc_mm* mm = vmspace(proc);
+
+ assert(!kernel_process(proc));
+
+ procvm_initvms_mount(mm);
+
+ int errno = 0;
+ struct thread* main_thread;
+ if (!(main_thread = create_thread(proc, true))) {
+ errno = ENOMEM;
+ goto fail;
+ }
+
+ struct exec_host container;
+ exec_init_container(&container, main_thread, VMS_MOUNT_1, argv, envp);
+ if ((errno = exec_load_byname(&container, path))) {
+ goto fail;
+ }
+
+ commit_process(proc);
+ start_thread(main_thread, container.exe.entry);
+
+ if (created) {
+ *created = main_thread;
+ }
+
+ procvm_unmount(mm);
+ return 0;
+
+fail:
+ procvm_unmount(mm);
+ delete_process(proc);
+ return errno;
+}
+
+
+ptr_t proc_vmroot() {
+ return __current->mm->vmroot;
+}
+