void uml_setup_stubs(struct mm_struct *mm) { int err, ret; if (!skas_needs_stub) return; ret = init_stub_pte(mm, STUB_CODE, (unsigned long) &__syscall_stub_start); if (ret) goto out; ret = init_stub_pte(mm, STUB_DATA, mm->context.id.stack); if (ret) goto out; mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start); mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack); /* dup_mmap already holds mmap_sem */ err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC | VM_DONTCOPY, mm->context.stub_pages); if (err) { printk(KERN_ERR "install_special_mapping returned %d\n", err); goto out; } return; out: force_sigsegv(SIGSEGV, current); }
int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) { struct mmu_context_skas *from_mm = NULL; struct mmu_context_skas *to_mm = &mm->context.skas; unsigned long stack = 0; int ret = -ENOMEM; if(skas_needs_stub){ stack = get_zeroed_page(GFP_KERNEL); if(stack == 0) goto out; /* This zeros the entry that pgd_alloc didn't, needed since * we are about to reinitialize it, and want mm.nr_ptes to * be accurate. */ mm->pgd[USER_PTRS_PER_PGD] = __pgd(0); ret = init_stub_pte(mm, CONFIG_STUB_CODE, (unsigned long) &__syscall_stub_start); if(ret) goto out_free; ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); if(ret) goto out_free; mm->nr_ptes--; } to_mm->id.stack = stack; if(current->mm != NULL && current->mm != &init_mm) from_mm = ¤t->mm->context.skas; if(proc_mm){ ret = new_mm(stack); if(ret < 0){ printk("init_new_context_skas - new_mm failed, " "errno = %d\n", ret); goto out_free; } to_mm->id.u.mm_fd = ret; } else { 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); } ret = init_new_ldt(to_mm, from_mm); if(ret < 0){ printk("init_new_context_skas - init_ldt" " failed, errno = %d\n", ret); goto out_free; } return 0; out_free: if(to_mm->id.stack != 0) free_page(to_mm->id.stack); out: return ret; }