linux/arch/csky/kernel/vdso.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
   3
   4#include <linux/kernel.h>
   5#include <linux/err.h>
   6#include <linux/sched.h>
   7#include <linux/mm.h>
   8#include <linux/init.h>
   9#include <linux/binfmts.h>
  10#include <linux/elf.h>
  11#include <linux/vmalloc.h>
  12#include <linux/unistd.h>
  13#include <linux/uaccess.h>
  14
  15#include <asm/vdso.h>
  16#include <asm/cacheflush.h>
  17
  18static struct page *vdso_page;
  19
  20static int __init init_vdso(void)
  21{
  22        struct csky_vdso *vdso;
  23        int err = 0;
  24
  25        vdso_page = alloc_page(GFP_KERNEL);
  26        if (!vdso_page)
  27                panic("Cannot allocate vdso");
  28
  29        vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
  30        if (!vdso)
  31                panic("Cannot map vdso");
  32
  33        clear_page(vdso);
  34
  35        err = setup_vdso_page(vdso->rt_signal_retcode);
  36        if (err)
  37                panic("Cannot set signal return code, err: %x.", err);
  38
  39        dcache_wb_range((unsigned long)vdso, (unsigned long)vdso + 16);
  40
  41        vunmap(vdso);
  42
  43        return 0;
  44}
  45subsys_initcall(init_vdso);
  46
  47int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
  48{
  49        int ret;
  50        unsigned long addr;
  51        struct mm_struct *mm = current->mm;
  52
  53        mmap_write_lock(mm);
  54
  55        addr = get_unmapped_area(NULL, STACK_TOP, PAGE_SIZE, 0, 0);
  56        if (IS_ERR_VALUE(addr)) {
  57                ret = addr;
  58                goto up_fail;
  59        }
  60
  61        ret = install_special_mapping(
  62                        mm,
  63                        addr,
  64                        PAGE_SIZE,
  65                        VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
  66                        &vdso_page);
  67        if (ret)
  68                goto up_fail;
  69
  70        mm->context.vdso = (void *)addr;
  71
  72up_fail:
  73        mmap_write_unlock(mm);
  74        return ret;
  75}
  76
  77const char *arch_vma_name(struct vm_area_struct *vma)
  78{
  79        if (vma->vm_mm == NULL)
  80                return NULL;
  81
  82        if (vma->vm_start == (long)vma->vm_mm->context.vdso)
  83                return "[vdso]";
  84        else
  85                return NULL;
  86}
  87