Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

csky: VDSO and rt_sigreturn

This patch adds files related to VDSO and our VDSO only support
rt_sigreturn.

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>

Guo Ren dd3ef10e e9564df7

+138
+17
arch/csky/abiv1/inc/abi/vdso.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #include <linux/uaccess.h> 4 + 5 + static inline int setup_vdso_page(unsigned short *ptr) 6 + { 7 + int err = 0; 8 + 9 + /* movi r1, 127 */ 10 + err |= __put_user(0x67f1, ptr + 0); 11 + /* addi r1, (139 - 127) */ 12 + err |= __put_user(0x20b1, ptr + 1); 13 + /* trap 0 */ 14 + err |= __put_user(0x0008, ptr + 2); 15 + 16 + return err; 17 + }
+23
arch/csky/abiv2/inc/abi/vdso.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __ABI_CSKY_VDSO_H 4 + #define __ABI_CSKY_VDSO_H 5 + 6 + #include <linux/uaccess.h> 7 + 8 + static inline int setup_vdso_page(unsigned short *ptr) 9 + { 10 + int err = 0; 11 + 12 + /* movi r7, 173 */ 13 + err |= __put_user(0xea07, ptr); 14 + err |= __put_user(0x008b, ptr+1); 15 + 16 + /* trap 0 */ 17 + err |= __put_user(0xc000, ptr+2); 18 + err |= __put_user(0x2020, ptr+3); 19 + 20 + return err; 21 + } 22 + 23 + #endif /* __ABI_CSKY_STRING_H */
+12
arch/csky/include/asm/vdso.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __ASM_CSKY_VDSO_H 4 + #define __ASM_CSKY_VDSO_H 5 + 6 + #include <abi/vdso.h> 7 + 8 + struct csky_vdso { 9 + unsigned short rt_signal_retcode[4]; 10 + }; 11 + 12 + #endif /* __ASM_CSKY_VDSO_H */
+86
arch/csky/kernel/vdso.c
··· 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 + 18 + static struct page *vdso_page; 19 + 20 + static 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 + } 45 + subsys_initcall(init_vdso); 46 + 47 + int 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 + down_write(&mm->mmap_sem); 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 + 72 + up_fail: 73 + up_write(&mm->mmap_sem); 74 + return ret; 75 + } 76 + 77 + const 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 + }