mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.3 KiB
72 lines
1.3 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* Copyright (C) 2011 Richard Weinberger <[email protected]> |
|
*/ |
|
|
|
#include <linux/slab.h> |
|
#include <linux/sched.h> |
|
#include <linux/mm.h> |
|
#include <asm/page.h> |
|
#include <asm/elf.h> |
|
#include <linux/init.h> |
|
|
|
static unsigned int __read_mostly vdso_enabled = 1; |
|
unsigned long um_vdso_addr; |
|
|
|
extern unsigned long task_size; |
|
extern char vdso_start[], vdso_end[]; |
|
|
|
static struct page **vdsop; |
|
|
|
static int __init init_vdso(void) |
|
{ |
|
struct page *um_vdso; |
|
|
|
BUG_ON(vdso_end - vdso_start > PAGE_SIZE); |
|
|
|
um_vdso_addr = task_size - PAGE_SIZE; |
|
|
|
vdsop = kmalloc(sizeof(struct page *), GFP_KERNEL); |
|
if (!vdsop) |
|
goto oom; |
|
|
|
um_vdso = alloc_page(GFP_KERNEL); |
|
if (!um_vdso) { |
|
kfree(vdsop); |
|
|
|
goto oom; |
|
} |
|
|
|
copy_page(page_address(um_vdso), vdso_start); |
|
*vdsop = um_vdso; |
|
|
|
return 0; |
|
|
|
oom: |
|
printk(KERN_ERR "Cannot allocate vdso\n"); |
|
vdso_enabled = 0; |
|
|
|
return -ENOMEM; |
|
} |
|
subsys_initcall(init_vdso); |
|
|
|
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) |
|
{ |
|
int err; |
|
struct mm_struct *mm = current->mm; |
|
|
|
if (!vdso_enabled) |
|
return 0; |
|
|
|
if (mmap_write_lock_killable(mm)) |
|
return -EINTR; |
|
|
|
err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, |
|
VM_READ|VM_EXEC| |
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, |
|
vdsop); |
|
|
|
mmap_write_unlock(mm); |
|
|
|
return err; |
|
}
|
|
|