1/* 2 * arch/sh/kernel/vsyscall/vsyscall.c 3 * 4 * Copyright (C) 2006 Paul Mundt 5 * 6 * vDSO randomization 7 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar 8 * 9 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file "COPYING" in the main directory of this archive 11 * for more details. 12 */ 13#include <linux/mm.h> 14#include <linux/slab.h> 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/gfp.h> 18#include <linux/module.h> 19#include <linux/elf.h> 20#include <linux/sched.h> 21 22/* 23 * Should the kernel map a VDSO page into processes and pass its 24 * address down to glibc upon exec()? 25 */ 26unsigned int __read_mostly vdso_enabled = 1; 27EXPORT_SYMBOL_GPL(vdso_enabled); 28 29static int __init vdso_setup(char *s) 30{ 31 vdso_enabled = simple_strtoul(s, NULL, 0); 32 return 1; 33} 34__setup("vdso=", vdso_setup); 35 36/* 37 * These symbols are defined by vsyscall.o to mark the bounds 38 * of the ELF DSO images included therein. 39 */ 40extern const char vsyscall_trapa_start, vsyscall_trapa_end; 41static struct page *syscall_pages[1]; 42 43int __init vsyscall_init(void) 44{ 45 void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); 46 syscall_pages[0] = virt_to_page(syscall_page); 47 48 49 memcpy(syscall_page, 50 &vsyscall_trapa_start, 51 &vsyscall_trapa_end - &vsyscall_trapa_start); 52 53 return 0; 54} 55 56/* Setup a VMA at program startup for the vsyscall page */ 57int arch_setup_additional_pages(struct linux_binprm *bprm, 58 int executable_stack) 59{ 60 struct mm_struct *mm = current->mm; 61 unsigned long addr; 62 int ret; 63 64 down_write(&mm->mmap_sem); 65 addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); 66 if (IS_ERR_VALUE(addr)) { 67 ret = addr; 68 goto up_fail; 69 } 70 71 ret = install_special_mapping(mm, addr, PAGE_SIZE, 72 VM_READ | VM_EXEC | 73 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | 74 VM_ALWAYSDUMP, 75 syscall_pages); 76 if (unlikely(ret)) 77 goto up_fail; 78 79 current->mm->context.vdso = (void *)addr; 80 81up_fail: 82 up_write(&mm->mmap_sem); 83 return ret; 84} 85 86const char *arch_vma_name(struct vm_area_struct *vma) 87{ 88 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) 89 return "[vdso]"; 90 91 return NULL; 92} 93 94struct vm_area_struct *get_gate_vma(struct task_struct *task) 95{ 96 return NULL; 97} 98 99int in_gate_area(struct task_struct *task, unsigned long address) 100{ 101 return 0; 102} 103 104int in_gate_area_no_task(unsigned long address) 105{ 106 return 0; 107} 108