-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a preliminary patch to add a vdso to all user processes. Still missing are ELF headers and .eh_frame information. But it is enough to allow us to move signal trampolines off of the stack. Note that emulation of branch delay slots in the FPU emulator still requires the stack. We allocate a single page (the vdso) and write all possible signal trampolines into it. The stack is moved down by one page and the vdso is mapped into this space. Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/975/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
- Loading branch information
David Daney
authored and
Ralf Baechle
committed
Apr 12, 2010
1 parent
58b9e22
commit c52d0d3
Showing
8 changed files
with
165 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
#ifndef __ASM_MMU_H | ||
#define __ASM_MMU_H | ||
|
||
typedef unsigned long mm_context_t[NR_CPUS]; | ||
typedef struct { | ||
unsigned long asid[NR_CPUS]; | ||
void *vdso; | ||
} mm_context_t; | ||
|
||
#endif /* __ASM_MMU_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
* | ||
* Copyright (C) 2009 Cavium Networks | ||
*/ | ||
|
||
#ifndef __ASM_VDSO_H | ||
#define __ASM_VDSO_H | ||
|
||
#include <linux/types.h> | ||
|
||
|
||
#ifdef CONFIG_32BIT | ||
struct mips_vdso { | ||
u32 signal_trampoline[2]; | ||
u32 rt_signal_trampoline[2]; | ||
}; | ||
#else /* !CONFIG_32BIT */ | ||
struct mips_vdso { | ||
u32 o32_signal_trampoline[2]; | ||
u32 o32_rt_signal_trampoline[2]; | ||
u32 rt_signal_trampoline[2]; | ||
u32 n32_rt_signal_trampoline[2]; | ||
}; | ||
#endif /* CONFIG_32BIT */ | ||
|
||
#endif /* __ASM_VDSO_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
* | ||
* Copyright (C) 2009, 2010 Cavium Networks, Inc. | ||
*/ | ||
|
||
|
||
#include <linux/kernel.h> | ||
#include <linux/err.h> | ||
#include <linux/sched.h> | ||
#include <linux/mm.h> | ||
#include <linux/init.h> | ||
#include <linux/binfmts.h> | ||
#include <linux/elf.h> | ||
#include <linux/vmalloc.h> | ||
#include <linux/unistd.h> | ||
|
||
#include <asm/vdso.h> | ||
#include <asm/uasm.h> | ||
|
||
/* | ||
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | ||
*/ | ||
#define __NR_O32_sigreturn 4119 | ||
#define __NR_O32_rt_sigreturn 4193 | ||
#define __NR_N32_rt_sigreturn 6211 | ||
|
||
static struct page *vdso_page; | ||
|
||
static void __init install_trampoline(u32 *tramp, unsigned int sigreturn) | ||
{ | ||
uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */ | ||
uasm_i_syscall(&tramp, 0); | ||
} | ||
|
||
static int __init init_vdso(void) | ||
{ | ||
struct mips_vdso *vdso; | ||
|
||
vdso_page = alloc_page(GFP_KERNEL); | ||
if (!vdso_page) | ||
panic("Cannot allocate vdso"); | ||
|
||
vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL); | ||
if (!vdso) | ||
panic("Cannot map vdso"); | ||
clear_page(vdso); | ||
|
||
install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn); | ||
#ifdef CONFIG_32BIT | ||
install_trampoline(vdso->signal_trampoline, __NR_sigreturn); | ||
#else | ||
install_trampoline(vdso->n32_rt_signal_trampoline, | ||
__NR_N32_rt_sigreturn); | ||
install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn); | ||
install_trampoline(vdso->o32_rt_signal_trampoline, | ||
__NR_O32_rt_sigreturn); | ||
#endif | ||
|
||
vunmap(vdso); | ||
|
||
pr_notice("init_vdso successfull\n"); | ||
|
||
return 0; | ||
} | ||
device_initcall(init_vdso); | ||
|
||
static unsigned long vdso_addr(unsigned long start) | ||
{ | ||
return STACK_TOP; | ||
} | ||
|
||
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: | ||
up_write(&mm->mmap_sem); | ||
return ret; | ||
} | ||
|
||
const char *arch_vma_name(struct vm_area_struct *vma) | ||
{ | ||
if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) | ||
return "[vdso]"; | ||
return NULL; | ||
} |