On Tue, Apr 21, 2009 at 02:33:24PM -0700, David Daney wrote: > This is a preliminary patch to add a vdso to all user processes. ... > diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c > new file mode 100644 > index 0000000..a1f38a6 ... > +static void __init install_trampoline(u32 *tramp, unsigned int sigreturn) > +{ > + tramp[0] = 0x24020000 + sigreturn; /* li v0, sigreturn */ > + tramp[1] = 0x0000000c; /* syscall */ > +} We can do away with magic constants by building on asm/inst.h: static void __init install_trampoline(union mips_instruction *tramp, short sigreturn) { static struct i_format li_sigreturn = { /* li, v0, sigreturn */ .opcode = addiu_op, .rs = 0, /* zero */ .rt = 2, /* v0 */ }; static struct r_format syscall = { /* syscall */ .opcode = spec_op, .func = syscall_op }; tramp[0].i_format = li_sigreturn; tramp[0].i_format.simmediate = sigreturn; tramp[1].r_format = syscall; } Admittedly, this isn't really a proper use of the r_format structure. The right way is to add another structure to asm/inst.h and use that: #ifdef __MIPSEB__ ... struct syscall_format { unsigned int opcode : 6; unsigned int code : 20; unsigned int func : 6; }; ... #else ... struct syscall_format { unsigned int func : 6; unsigned int code : 20; unsigned int opcode : 6; }; ... #endif Then we could do the syscall the right way by using syscall_format instead of r_format... ... > +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) > +{ > + int ret; > + unsigned long addr; > + struct mm_struct *mm = current->mm; > + > + down_write(&mm->mmap_sem); > + > + addr = vdso_addr(mm->start_stack); > + > + addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0); > + if (IS_ERR_VALUE(addr)) { > + ret = addr; > + goto up_fail; > + } > + > + ret = install_special_mapping(mm, addr, PAGE_SIZE, > + VM_READ|VM_EXEC| > + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| > + VM_ALWAYSDUMP, > + &vdso_page); > + > + if (ret) > + goto up_fail; > + > + mm->context.vdso = (void *)addr; > + > +up_fail: It seems that this is an unexpected condition that probably indicates a failure of the expected state of the process at this point. Perhaps a pr_err() or pr_warning() would be appropriate? > + up_write(&mm->mmap_sem); > + return ret; > +}