/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/alpha/kernel/entry.S
*
* Kernel entry-points.
*/
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/pal.h>
#include <asm/errno.h>
#include <asm/unistd.h>
#include <linux/errno.h>
.text
.set noat
.cfi_sections .debug_frame
.macro CFI_START_OSF_FRAME func
.align 4
.globl \func
.type \func,@function
\func:
.cfi_startproc simple
.cfi_return_column 64
.cfi_def_cfa $sp, 48
.cfi_rel_offset 64, 8
.cfi_rel_offset $gp, 16
.cfi_rel_offset $16, 24
.cfi_rel_offset $17, 32
.cfi_rel_offset $18, 40
.endm
.macro CFI_END_OSF_FRAME func
.cfi_endproc
.size \func, . - \func
.endm
/*
* SYSCALL_SKIP_RETURN_RESTART_GATE
*
* Used when syscall dispatch is skipped (seccomp/ptrace injected nr=-1).
* - Ensure we never return r0==-1 with a3==0 (success); convert to ENOSYS.
* - Gate whether syscall restart is allowed by preserving restart context
* only for ERESTART* returns. Result:
* $26 = 0 => restart allowed
* $26 = 1 => restart NOT allowed
* $18 = preserved syscall nr (regs->r2) if restart allowed, else 0
*/
.macro SYSCALL_SKIP_RETURN_RESTART_GATE
/* Fix up invalid "-1 success" return state. */
ldq $19, 72($sp) /* a3 */
bne $19, 1f /* already error => skip fixup */
ldq $20, 0($sp) /* r0 */
lda $21, -1($31)
cmpeq $20, $21, $22
beq $22, 1f /* r0 != -1 => skip fixup */
lda $20, ENOSYS($31)
stq $20, 0($sp) /* r0 = ENOSYS */
lda $19, 1($31)
stq $19, 72($sp) /* a3 = 1 */
1:
/* Restart gating: success is never restartable here. */
ldq $19, 72($sp) /* a3 */
beq $19, 3f /* success => not restartable */
ldq $20, 0($sp) /* r0 (positive errno if a3==1) */
lda $21, ERESTARTSYS($31)
cmpeq $20, $21, $22
bne $22, 2f
lda $21, ERESTARTNOINTR($31)
cmpeq $20, $21, $22
bne $22, 2f
lda $21, ERESTARTNOHAND($31)
cmpeq $20, $21, $22
bne $22, 2f
lda $21, ERESTART_RESTARTBLOCK($31)
cmpeq $20, $21, $22
bne $22, 2f
3: /* Not a restart code (or success) => restart NOT allowed. */
addq $31, 1, $26 /* $26=1 => restart NOT allowed */
mov 0, $18
br 4f
2: /* Restart allowed. */
ldq $18, 16($sp) /* preserved syscall nr (regs->r2) */
mov $31, $26 /* $26=0 => restart allowed */
br 4f
4:
.endm
/*
* This defines the normal kernel pt-regs layout.
*
* regs 9-15 preserved by C code
* regs 16-18 saved by PAL-code
* regs 29-30 saved and set up by PAL-code
* JRP - Save regs 16-18 in a special area of the stack, so that
* the palcode-provided values are available to the signal handler.
*/
.macro SAVE_ALL
subq $sp, SP_OFF, $sp
.cfi_adjust_cfa_offset SP_OFF
stq $0, 0($sp)
stq $1, 8($sp)
stq $2, 16($sp)
stq $3, 24($sp)
stq $4, 32($sp)
stq $28, 144($sp)
.cfi_rel_offset $0, 0
.cfi_rel_offset $1, 8
.cfi_rel_offset $2, 16
.cfi_rel_offset $3, 24
.cfi_rel_offset $4, 32
.cfi_rel_offset $28, 144
lda $2, alpha_mv
stq $5, 40($sp)
stq $6, 48($sp)
stq $7, 56($sp)
stq $8, 64($sp)
stq $19, 72($sp)
stq $20, 80($sp)
stq $21, 88($sp)
ldq $2, HAE_CACHE($2)
stq $22, 96($sp)
stq $23, 104($sp)
stq $24, 112($sp)
stq $25, 120($sp)
stq $26, 128($sp)
stq $27, 136($sp)
stq $2, 152($sp)
stq $16, 160($sp)
stq $17, 168($sp)
stq $18, 176($sp)
.cfi_rel_offset $5, 40
.cfi_rel_offset $6, 48
.cfi_rel_offset $7, 56
.cfi_rel_offset $8, 64
.cfi_rel_offset $19, 72
.cfi_rel_offset $20, 80
.cfi_rel_offset $21, 88
.cfi_rel_offset $22, 96
.cfi_rel_offset $23, 104
.cfi_rel_offset $24, 112
.cfi_rel_offset $25, 120
.cfi_rel_offset $26, 128
.cfi_rel_offset $27, 136
.endm
.macro RESTORE_ALL
lda $19, alpha_mv
ldq $0, 0($sp)
ldq $1