944 lines · 20.2 KB · Assembly
RawDownload
/* 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	4f4:.endm .macro LOCKDEP_HARDIRQS_ON_RESTORE#ifdef CONFIG_PROVE_LOCKING	/* a0 = saved PS */	ldq	$16, SP_OFF($sp) 	/* a1 = callsite IP for lockdep */	lda	$17, 1f 	jsr	$26, lockdep_on_restore	ldgp	$gp, 0($26)1:#endif.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, 8($sp)	ldq	$2, 16($sp)	ldq	$3, 24($sp)	ldq	$21, 152($sp)	ldq	$20, HAE_CACHE($19)	ldq	$4, 32($sp)	ldq	$5, 40($sp)	ldq	$6, 48($sp)	ldq	$7, 56($sp)	subq	$20, $21, $20	ldq	$8, 64($sp)	beq	$20, 99f	ldq	$20, HAE_REG($19)	stq	$21, HAE_CACHE($19)	stq	$21, 0($20)99:	ldq	$19, 72($sp)	ldq	$20, 80($sp)	ldq	$21, 88($sp)	ldq	$22, 96($sp)	ldq	$23, 104($sp)	ldq	$24, 112($sp)	ldq	$25, 120($sp)	ldq	$26, 128($sp)	ldq	$27, 136($sp)	ldq	$28, 144($sp)	addq	$sp, SP_OFF, $sp	.cfi_restore	$0	.cfi_restore	$1	.cfi_restore	$2	.cfi_restore	$3	.cfi_restore	$4	.cfi_restore	$5	.cfi_restore	$6	.cfi_restore	$7	.cfi_restore	$8	.cfi_restore	$19	.cfi_restore	$20	.cfi_restore	$21	.cfi_restore	$22	.cfi_restore	$23	.cfi_restore	$24	.cfi_restore	$25	.cfi_restore	$26	.cfi_restore	$27	.cfi_restore	$28	.cfi_adjust_cfa_offset	-SP_OFF.endm .macro	DO_SWITCH_STACK	bsr	$1, do_switch_stack	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE	.cfi_rel_offset	$9, 0	.cfi_rel_offset	$10, 8	.cfi_rel_offset	$11, 16	.cfi_rel_offset	$12, 24	.cfi_rel_offset	$13, 32	.cfi_rel_offset	$14, 40	.cfi_rel_offset	$15, 48.endm .macro	UNDO_SWITCH_STACK	bsr	$1, undo_switch_stack	.cfi_restore	$9	.cfi_restore	$10	.cfi_restore	$11	.cfi_restore	$12	.cfi_restore	$13	.cfi_restore	$14	.cfi_restore	$15	.cfi_adjust_cfa_offset	-SWITCH_STACK_SIZE.endm /* * Non-syscall kernel entry points. */ CFI_START_OSF_FRAME entInt	SAVE_ALL	lda	$8, 0x3fff	lda	$26, ret_from_sys_call	bic	$sp, $8, $8	mov	$sp, $19	jsr	$31, do_entIntCFI_END_OSF_FRAME entInt CFI_START_OSF_FRAME entArith	SAVE_ALL	lda	$8, 0x3fff	lda	$26, ret_from_sys_call	bic	$sp, $8, $8	mov	$sp, $18	jsr	$31, do_entArithCFI_END_OSF_FRAME entArith CFI_START_OSF_FRAME entMM	SAVE_ALL/* save $9 - $15 so the inline exception code can manipulate them.  */	subq	$sp, 64, $sp	.cfi_adjust_cfa_offset	64	stq	$9, 0($sp)	stq	$10, 8($sp)	stq	$11, 16($sp)	stq	$12, 24($sp)	stq	$13, 32($sp)	stq	$14, 40($sp)	stq	$15, 48($sp)	.cfi_rel_offset	$9, 0	.cfi_rel_offset	$10, 8	.cfi_rel_offset	$11, 16	.cfi_rel_offset	$12, 24	.cfi_rel_offset	$13, 32	.cfi_rel_offset	$14, 40	.cfi_rel_offset	$15, 48	addq	$sp, 64, $19/* handle the fault */	lda	$8, 0x3fff	bic	$sp, $8, $8	jsr	$26, do_page_fault/* reload the registers after the exception code played.  */	ldq	$9, 0($sp)	ldq	$10, 8($sp)	ldq	$11, 16($sp)	ldq	$12, 24($sp)	ldq	$13, 32($sp)	ldq	$14, 40($sp)	ldq	$15, 48($sp)	addq	$sp, 64, $sp	.cfi_restore	$9	.cfi_restore	$10	.cfi_restore	$11	.cfi_restore	$12	.cfi_restore	$13	.cfi_restore	$14	.cfi_restore	$15	.cfi_adjust_cfa_offset	-64/* finish up the syscall as normal.  */	br	ret_from_sys_callCFI_END_OSF_FRAME entMM CFI_START_OSF_FRAME entIF	SAVE_ALL	lda	$8, 0x3fff	lda	$26, ret_from_sys_call	bic	$sp, $8, $8	mov	$sp, $17	jsr	$31, do_entIFCFI_END_OSF_FRAME entIF CFI_START_OSF_FRAME entUna	lda	$sp, -256($sp)	.cfi_adjust_cfa_offset	256	stq	$0, 0($sp)	.cfi_rel_offset	$0, 0	.cfi_remember_state	ldq	$0, 256($sp)	/* get PS */	stq	$1, 8($sp)	stq	$2, 16($sp)	stq	$3, 24($sp)	and	$0, 8, $0		/* user mode? */	stq	$4, 32($sp)	bne	$0, entUnaUser	/* yup -> do user-level unaligned fault */	stq	$5, 40($sp)	stq	$6, 48($sp)	stq	$7, 56($sp)	stq	$8, 64($sp)	stq	$9, 72($sp)	stq	$10, 80($sp)	stq	$11, 88($sp)	stq	$12, 96($sp)	stq	$13, 104($sp)	stq	$14, 112($sp)	stq	$15, 120($sp)	/* 16-18 PAL-saved */	stq	$19, 152($sp)	stq	$20, 160($sp)	stq	$21, 168($sp)	stq	$22, 176($sp)	stq	$23, 184($sp)	stq	$24, 192($sp)	stq	$25, 200($sp)	stq	$26, 208($sp)	stq	$27, 216($sp)	stq	$28, 224($sp)	mov	$sp, $19	stq	$gp, 232($sp)	.cfi_rel_offset	$1, 1*8	.cfi_rel_offset	$2, 2*8	.cfi_rel_offset	$3, 3*8	.cfi_rel_offset	$4, 4*8	.cfi_rel_offset	$5, 5*8	.cfi_rel_offset	$6, 6*8	.cfi_rel_offset	$7, 7*8	.cfi_rel_offset	$8, 8*8	.cfi_rel_offset	$9, 9*8	.cfi_rel_offset	$10, 10*8	.cfi_rel_offset	$11, 11*8	.cfi_rel_offset	$12, 12*8	.cfi_rel_offset	$13, 13*8	.cfi_rel_offset	$14, 14*8	.cfi_rel_offset	$15, 15*8	.cfi_rel_offset	$19, 19*8	.cfi_rel_offset	$20, 20*8	.cfi_rel_offset	$21, 21*8	.cfi_rel_offset	$22, 22*8	.cfi_rel_offset	$23, 23*8	.cfi_rel_offset	$24, 24*8	.cfi_rel_offset	$25, 25*8	.cfi_rel_offset	$26, 26*8	.cfi_rel_offset	$27, 27*8	.cfi_rel_offset	$28, 28*8	.cfi_rel_offset	$29, 29*8	lda	$8, 0x3fff	stq	$31, 248($sp)	bic	$sp, $8, $8	jsr	$26, do_entUna	ldq	$0, 0($sp)	ldq	$1, 8($sp)	ldq	$2, 16($sp)	ldq	$3, 24($sp)	ldq	$4, 32($sp)	ldq	$5, 40($sp)	ldq	$6, 48($sp)	ldq	$7, 56($sp)	ldq	$8, 64($sp)	ldq	$9, 72($sp)	ldq	$10, 80($sp)	ldq	$11, 88($sp)	ldq	$12, 96($sp)	ldq	$13, 104($sp)	ldq	$14, 112($sp)	ldq	$15, 120($sp)	/* 16-18 PAL-saved */	ldq	$19, 152($sp)	ldq	$20, 160($sp)	ldq	$21, 168($sp)	ldq	$22, 176($sp)	ldq	$23, 184($sp)	ldq	$24, 192($sp)	ldq	$25, 200($sp)	ldq	$26, 208($sp)	ldq	$27, 216($sp)	ldq	$28, 224($sp)	ldq	$gp, 232($sp)	lda	$sp, 256($sp)	.cfi_restore	$1	.cfi_restore	$2	.cfi_restore	$3	.cfi_restore	$4	.cfi_restore	$5	.cfi_restore	$6	.cfi_restore	$7	.cfi_restore	$8	.cfi_restore	$9	.cfi_restore	$10	.cfi_restore	$11	.cfi_restore	$12	.cfi_restore	$13	.cfi_restore	$14	.cfi_restore	$15	.cfi_restore	$19	.cfi_restore	$20	.cfi_restore	$21	.cfi_restore	$22	.cfi_restore	$23	.cfi_restore	$24	.cfi_restore	$25	.cfi_restore	$26	.cfi_restore	$27	.cfi_restore	$28	.cfi_restore	$29	.cfi_adjust_cfa_offset	-256	LOCKDEP_HARDIRQS_ON_RESTORE	call_pal PAL_rti 	.align	4entUnaUser:	.cfi_restore_state	ldq	$0, 0($sp)	/* restore original $0 */	lda	$sp, 256($sp)	/* pop entUna's stack frame */	.cfi_restore	$0	.cfi_adjust_cfa_offset	-256	SAVE_ALL		/* setup normal kernel stack */	lda	$sp, -64($sp)	.cfi_adjust_cfa_offset	64	stq	$9, 0($sp)	stq	$10, 8($sp)	stq	$11, 16($sp)	stq	$12, 24($sp)	stq	$13, 32($sp)	stq	$14, 40($sp)	stq	$15, 48($sp)	.cfi_rel_offset	$9, 0	.cfi_rel_offset	$10, 8	.cfi_rel_offset	$11, 16	.cfi_rel_offset	$12, 24	.cfi_rel_offset	$13, 32	.cfi_rel_offset	$14, 40	.cfi_rel_offset	$15, 48	lda	$8, 0x3fff	addq	$sp, 64, $19	bic	$sp, $8, $8	jsr	$26, do_entUnaUser	ldq	$9, 0($sp)	ldq	$10, 8($sp)	ldq	$11, 16($sp)	ldq	$12, 24($sp)	ldq	$13, 32($sp)	ldq	$14, 40($sp)	ldq	$15, 48($sp)	lda	$sp, 64($sp)	.cfi_restore	$9	.cfi_restore	$10	.cfi_restore	$11	.cfi_restore	$12	.cfi_restore	$13	.cfi_restore	$14	.cfi_restore	$15	.cfi_adjust_cfa_offset	-64	br	ret_from_sys_callCFI_END_OSF_FRAME entUna CFI_START_OSF_FRAME entDbg	SAVE_ALL	lda	$8, 0x3fff	lda	$26, ret_from_sys_call	bic	$sp, $8, $8	mov	$sp, $16	jsr	$31, do_entDbgCFI_END_OSF_FRAME entDbg

Lines 1–500 of 944.