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 <linux/init.h>
  14
  15unsigned int __read_mostly vdso_enabled = 1;
  16unsigned long um_vdso_addr;
  17
  18extern unsigned long task_size;
  19extern char vdso_start[], vdso_end[];
  20
  21static struct page **vdsop;
  22
  23static int __init init_vdso(void)
  24{
  25        struct page *um_vdso;
  26
  27        BUG_ON(vdso_end - vdso_start > PAGE_SIZE);
  28
  29        um_vdso_addr = task_size - PAGE_SIZE;
  30
  31        vdsop = kmalloc(sizeof(struct page *), GFP_KERNEL);
  32        if (!vdsop)
  33                goto oom;
  34
  35        um_vdso = alloc_page(GFP_KERNEL);
  36        if (!um_vdso) {
  37                kfree(vdsop);
  38
  39                goto oom;
  40        }
  41
  42        copy_page(page_address(um_vdso), vdso_start);
  43        *vdsop = um_vdso;
  44
  45        return 0;
  46
  47oom:
  48        printk(KERN_ERR "Cannot allocate vdso\n");
  49        vdso_enabled = 0;
  50
  51        return -ENOMEM;
  52}
  53subsys_initcall(init_vdso);
  54
  55int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
  56{
  57        int err;
  58        struct mm_struct *mm = current->mm;
  59
  60        if (!vdso_enabled)
  61                return 0;
  62
  63        down_write(&mm->mmap_sem);
  64
  65        err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE,
  66                VM_READ|VM_EXEC|
  67                VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
  68                vdsop);
  69
  70        up_write(&mm->mmap_sem);
  71
  72        return err;
  73}
  74