linux/arch/x86/um/vdso/vma.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Richard Weinberger <richrd@nod.at>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#include <linux/slab.h>
  10#include <linux/sched.h>
  11#include <linux/mm.h>
  12#include <asm/page.h>
  13#include <asm/elf.h>
  14#include <linux/init.h>
  15
  16static unsigned int __read_mostly vdso_enabled = 1;
  17unsigned long um_vdso_addr;
  18
  19extern unsigned long task_size;
  20extern char vdso_start[], vdso_end[];
  21
  22static struct page **vdsop;
  23
  24static int __init init_vdso(void)
  25{
  26        struct page *um_vdso;
  27
  28        BUG_ON(vdso_end - vdso_start > PAGE_SIZE);
  29
  30        um_vdso_addr = task_size - PAGE_SIZE;
  31
  32        vdsop = kmalloc(sizeof(struct page *), GFP_KERNEL);
  33        if (!vdsop)
  34                goto oom;
  35
  36        um_vdso = alloc_page(GFP_KERNEL);
  37        if (!um_vdso) {
  38                kfree(vdsop);
  39
  40                goto oom;
  41        }
  42
  43        copy_page(page_address(um_vdso), vdso_start);
  44        *vdsop = um_vdso;
  45
  46        return 0;
  47
  48oom:
  49        printk(KERN_ERR "Cannot allocate vdso\n");
  50        vdso_enabled = 0;
  51
  52        return -ENOMEM;
  53}
  54subsys_initcall(init_vdso);
  55
  56int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
  57{
  58        int err;
  59        struct mm_struct *mm = current->mm;
  60
  61        if (!vdso_enabled)
  62                return 0;
  63
  64        if (down_write_killable(&mm->mmap_sem))
  65                return -EINTR;
  66
  67        err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE,
  68                VM_READ|VM_EXEC|
  69                VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
  70                vdsop);
  71
  72        up_write(&mm->mmap_sem);
  73
  74        return err;
  75}
  76