1*1802d0beSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 2574e2b51SVictor Kamensky/* 3574e2b51SVictor Kamensky * sigreturn_codes.S - code sinpets for sigreturn syscalls 4574e2b51SVictor Kamensky * 5574e2b51SVictor Kamensky * Created by: Victor Kamensky, 2013-08-13 6574e2b51SVictor Kamensky * Copyright: (C) 2013 Linaro Limited 7574e2b51SVictor Kamensky */ 8574e2b51SVictor Kamensky 95c165953SNicolas Pitre#include <asm/assembler.h> 105c165953SNicolas Pitre#include <asm/asm-offsets.h> 11574e2b51SVictor Kamensky#include <asm/unistd.h> 12574e2b51SVictor Kamensky 13574e2b51SVictor Kamensky/* 14574e2b51SVictor Kamensky * For ARM syscalls, we encode the syscall number into the instruction. 15574e2b51SVictor Kamensky * With EABI, the syscall number has to be loaded into r7. As result 16574e2b51SVictor Kamensky * ARM syscall sequence snippet will have move and svc in .arm encoding 17574e2b51SVictor Kamensky * 18574e2b51SVictor Kamensky * For Thumb syscalls, we pass the syscall number via r7. We therefore 19574e2b51SVictor Kamensky * need two 16-bit instructions in .thumb encoding 20574e2b51SVictor Kamensky * 21574e2b51SVictor Kamensky * Please note sigreturn_codes code are not executed in place. Instead 22574e2b51SVictor Kamensky * they just copied by kernel into appropriate places. Code inside of 23574e2b51SVictor Kamensky * arch/arm/kernel/signal.c is very sensitive to layout of these code 24574e2b51SVictor Kamensky * snippets. 25574e2b51SVictor Kamensky */ 26574e2b51SVictor Kamensky 2750913336SVictor Kamensky/* 2850913336SVictor Kamensky * In CPU_THUMBONLY case kernel arm opcodes are not allowed. 2950913336SVictor Kamensky * Note in this case codes skips those instructions but it uses .org 3050913336SVictor Kamensky * directive to keep correct layout of sigreturn_codes array. 3150913336SVictor Kamensky */ 3250913336SVictor Kamensky#ifndef CONFIG_CPU_THUMBONLY 3350913336SVictor Kamensky#define ARM_OK(code...) code 3450913336SVictor Kamensky#else 3550913336SVictor Kamensky#define ARM_OK(code...) 3650913336SVictor Kamensky#endif 3750913336SVictor Kamensky 3850913336SVictor Kamensky .macro arm_slot n 3950913336SVictor Kamensky .org sigreturn_codes + 12 * (\n) 4050913336SVictor KamenskyARM_OK( .arm ) 4150913336SVictor Kamensky .endm 4250913336SVictor Kamensky 4350913336SVictor Kamensky .macro thumb_slot n 4450913336SVictor Kamensky .org sigreturn_codes + 12 * (\n) + 8 4550913336SVictor Kamensky .thumb 4650913336SVictor Kamensky .endm 4750913336SVictor Kamensky 485c165953SNicolas Pitre .macro arm_fdpic_slot n 495c165953SNicolas Pitre .org sigreturn_codes + 24 + 20 * (\n) 505c165953SNicolas PitreARM_OK( .arm ) 515c165953SNicolas Pitre .endm 525c165953SNicolas Pitre 535c165953SNicolas Pitre .macro thumb_fdpic_slot n 545c165953SNicolas Pitre .org sigreturn_codes + 24 + 20 * (\n) + 12 555c165953SNicolas Pitre .thumb 565c165953SNicolas Pitre .endm 575c165953SNicolas Pitre 585c165953SNicolas Pitre 59574e2b51SVictor Kamensky#if __LINUX_ARM_ARCH__ <= 4 60574e2b51SVictor Kamensky /* 61574e2b51SVictor Kamensky * Note we manually set minimally required arch that supports 62574e2b51SVictor Kamensky * required thumb opcodes for early arch versions. It is OK 63574e2b51SVictor Kamensky * for this file to be used in combination with other 64574e2b51SVictor Kamensky * lower arch variants, since these code snippets are only 65574e2b51SVictor Kamensky * used as input data. 66574e2b51SVictor Kamensky */ 67574e2b51SVictor Kamensky .arch armv4t 68574e2b51SVictor Kamensky#endif 69574e2b51SVictor Kamensky 70574e2b51SVictor Kamensky .section .rodata 71574e2b51SVictor Kamensky .global sigreturn_codes 72574e2b51SVictor Kamensky .type sigreturn_codes, #object 73574e2b51SVictor Kamensky 7450913336SVictor Kamensky .align 75574e2b51SVictor Kamensky 76574e2b51SVictor Kamenskysigreturn_codes: 77574e2b51SVictor Kamensky 78574e2b51SVictor Kamensky /* ARM sigreturn syscall code snippet */ 7950913336SVictor Kamensky arm_slot 0 8050913336SVictor KamenskyARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) ) 8150913336SVictor KamenskyARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) 82574e2b51SVictor Kamensky 83574e2b51SVictor Kamensky /* Thumb sigreturn syscall code snippet */ 8450913336SVictor Kamensky thumb_slot 0 85574e2b51SVictor Kamensky movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) 86574e2b51SVictor Kamensky swi #0 87574e2b51SVictor Kamensky 88574e2b51SVictor Kamensky /* ARM sigreturn_rt syscall code snippet */ 8950913336SVictor Kamensky arm_slot 1 9050913336SVictor KamenskyARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) ) 9150913336SVictor KamenskyARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) 92574e2b51SVictor Kamensky 93574e2b51SVictor Kamensky /* Thumb sigreturn_rt syscall code snippet */ 9450913336SVictor Kamensky thumb_slot 1 95574e2b51SVictor Kamensky movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) 96574e2b51SVictor Kamensky swi #0 97574e2b51SVictor Kamensky 985c165953SNicolas Pitre /* ARM sigreturn restorer FDPIC bounce code snippet */ 995c165953SNicolas Pitre arm_fdpic_slot 0 1005c165953SNicolas PitreARM_OK( ldr r3, [sp, #SIGFRAME_RC3_OFFSET] ) 1015c165953SNicolas PitreARM_OK( ldmia r3, {r3, r9} ) 1025c165953SNicolas Pitre#ifdef CONFIG_ARM_THUMB 1035c165953SNicolas PitreARM_OK( bx r3 ) 1045c165953SNicolas Pitre#else 1055c165953SNicolas PitreARM_OK( ret r3 ) 1065c165953SNicolas Pitre#endif 1075c165953SNicolas Pitre 1085c165953SNicolas Pitre /* Thumb sigreturn restorer FDPIC bounce code snippet */ 1095c165953SNicolas Pitre thumb_fdpic_slot 0 1105c165953SNicolas Pitre ldr r3, [sp, #SIGFRAME_RC3_OFFSET] 1115c165953SNicolas Pitre ldmia r3, {r2, r3} 1125c165953SNicolas Pitre mov r9, r3 1135c165953SNicolas Pitre bx r2 1145c165953SNicolas Pitre 1155c165953SNicolas Pitre /* ARM sigreturn_rt restorer FDPIC bounce code snippet */ 1165c165953SNicolas Pitre arm_fdpic_slot 1 1175c165953SNicolas PitreARM_OK( ldr r3, [sp, #RT_SIGFRAME_RC3_OFFSET] ) 1185c165953SNicolas PitreARM_OK( ldmia r3, {r3, r9} ) 1195c165953SNicolas Pitre#ifdef CONFIG_ARM_THUMB 1205c165953SNicolas PitreARM_OK( bx r3 ) 1215c165953SNicolas Pitre#else 1225c165953SNicolas PitreARM_OK( ret r3 ) 1235c165953SNicolas Pitre#endif 1245c165953SNicolas Pitre 1255c165953SNicolas Pitre /* Thumb sigreturn_rt restorer FDPIC bounce code snippet */ 1265c165953SNicolas Pitre thumb_fdpic_slot 1 1275c165953SNicolas Pitre ldr r3, [sp, #RT_SIGFRAME_RC3_OFFSET] 1285c165953SNicolas Pitre ldmia r3, {r2, r3} 1295c165953SNicolas Pitre mov r9, r3 1305c165953SNicolas Pitre bx r2 1315c165953SNicolas Pitre 132574e2b51SVictor Kamensky /* 1335c165953SNicolas Pitre * Note on additional space: setup_return in signal.c 1345c165953SNicolas Pitre * always copies the same number of words regardless whether 1355c165953SNicolas Pitre * it is thumb case or not, so we need one additional padding 1365c165953SNicolas Pitre * word after the last entry. 137574e2b51SVictor Kamensky */ 138574e2b51SVictor Kamensky .space 4 139574e2b51SVictor Kamensky 140574e2b51SVictor Kamensky .size sigreturn_codes, . - sigreturn_codes 141