1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * sigreturn_codes.S - code sinpets for sigreturn syscalls 4 * 5 * Created by: Victor Kamensky, 2013-08-13 6 * Copyright: (C) 2013 Linaro Limited 7 */ 8 9#include <asm/assembler.h> 10#include <asm/asm-offsets.h> 11#include <asm/unistd.h> 12 13/* 14 * For ARM syscalls, we encode the syscall number into the instruction. 15 * With EABI, the syscall number has to be loaded into r7. As result 16 * ARM syscall sequence snippet will have move and svc in .arm encoding 17 * 18 * For Thumb syscalls, we pass the syscall number via r7. We therefore 19 * need two 16-bit instructions in .thumb encoding 20 * 21 * Please note sigreturn_codes code are not executed in place. Instead 22 * they just copied by kernel into appropriate places. Code inside of 23 * arch/arm/kernel/signal.c is very sensitive to layout of these code 24 * snippets. 25 */ 26 27/* 28 * In CPU_THUMBONLY case kernel arm opcodes are not allowed. 29 * Note in this case codes skips those instructions but it uses .org 30 * directive to keep correct layout of sigreturn_codes array. 31 */ 32#ifndef CONFIG_CPU_THUMBONLY 33#define ARM_OK(code...) code 34#else 35#define ARM_OK(code...) 36#endif 37 38 .macro arm_slot n 39 .org sigreturn_codes + 12 * (\n) 40ARM_OK( .arm ) 41 .endm 42 43 .macro thumb_slot n 44 .org sigreturn_codes + 12 * (\n) + 8 45 .thumb 46 .endm 47 48 .macro arm_fdpic_slot n 49 .org sigreturn_codes + 24 + 20 * (\n) 50ARM_OK( .arm ) 51 .endm 52 53 .macro thumb_fdpic_slot n 54 .org sigreturn_codes + 24 + 20 * (\n) + 12 55 .thumb 56 .endm 57 58 59#if __LINUX_ARM_ARCH__ <= 4 60 /* 61 * Note we manually set minimally required arch that supports 62 * required thumb opcodes for early arch versions. It is OK 63 * for this file to be used in combination with other 64 * lower arch variants, since these code snippets are only 65 * used as input data. 66 */ 67 .arch armv4t 68#endif 69 70 .section .rodata 71 .global sigreturn_codes 72 .type sigreturn_codes, #object 73 74 .align 75 76sigreturn_codes: 77 78 /* ARM sigreturn syscall code snippet */ 79 arm_slot 0 80ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) ) 81ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) 82 83 /* Thumb sigreturn syscall code snippet */ 84 thumb_slot 0 85 movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) 86 swi #0 87 88 /* ARM sigreturn_rt syscall code snippet */ 89 arm_slot 1 90ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) ) 91ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) 92 93 /* Thumb sigreturn_rt syscall code snippet */ 94 thumb_slot 1 95 movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) 96 swi #0 97 98 /* ARM sigreturn restorer FDPIC bounce code snippet */ 99 arm_fdpic_slot 0 100ARM_OK( ldr r3, [sp, #SIGFRAME_RC3_OFFSET] ) 101ARM_OK( ldmia r3, {r3, r9} ) 102#ifdef CONFIG_ARM_THUMB 103ARM_OK( bx r3 ) 104#else 105ARM_OK( ret r3 ) 106#endif 107 108 /* Thumb sigreturn restorer FDPIC bounce code snippet */ 109 thumb_fdpic_slot 0 110 ldr r3, [sp, #SIGFRAME_RC3_OFFSET] 111 ldmia r3, {r2, r3} 112 mov r9, r3 113 bx r2 114 115 /* ARM sigreturn_rt restorer FDPIC bounce code snippet */ 116 arm_fdpic_slot 1 117ARM_OK( ldr r3, [sp, #RT_SIGFRAME_RC3_OFFSET] ) 118ARM_OK( ldmia r3, {r3, r9} ) 119#ifdef CONFIG_ARM_THUMB 120ARM_OK( bx r3 ) 121#else 122ARM_OK( ret r3 ) 123#endif 124 125 /* Thumb sigreturn_rt restorer FDPIC bounce code snippet */ 126 thumb_fdpic_slot 1 127 ldr r3, [sp, #RT_SIGFRAME_RC3_OFFSET] 128 ldmia r3, {r2, r3} 129 mov r9, r3 130 bx r2 131 132 /* 133 * Note on additional space: setup_return in signal.c 134 * always copies the same number of words regardless whether 135 * it is thumb case or not, so we need one additional padding 136 * word after the last entry. 137 */ 138 .space 4 139 140 .size sigreturn_codes, . - sigreturn_codes 141