개념 설명 전체 · v6.18.37 / arch/arm64/kernel/entry.S

    1 /* SPDX-License-Identifier: GPL-2.0-only */
    2 /*
    3  * Low-level exception handling code
    4  *
    5  * Copyright (C) 2012 ARM Ltd.
    6  * Authors:	Catalin Marinas <catalin.marinas@arm.com>
    7  *		Will Deacon <will.deacon@arm.com>
    8  */
    9 
   10 #include <linux/arm-smccc.h>
   11 #include <linux/init.h>
   12 #include <linux/linkage.h>
   13 
   14 #include <asm/alternative.h>
   15 #include <asm/assembler.h>
   16 #include <asm/asm-offsets.h>
   17 #include <asm/asm_pointer_auth.h>
   18 #include <asm/bug.h>
   19 #include <asm/cpufeature.h>
   20 #include <asm/errno.h>
   21 #include <asm/esr.h>
   22 #include <asm/irq.h>
   23 #include <asm/memory.h>
   24 #include <asm/mmu.h>
   25 #include <asm/processor.h>
   26 #include <asm/ptrace.h>
   27 #include <asm/scs.h>
   28 #include <asm/stacktrace/frame.h>
   29 #include <asm/thread_info.h>
   30 #include <asm/asm-uaccess.h>
   31 #include <asm/unistd.h>
   32 
   33 	.macro	clear_gp_regs
   34 	.irp	n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
   35 	mov	x\n, xzr
   36 	.endr
   37 	.endm
   38 
   39 	.macro kernel_ventry, el:req, ht:req, regsize:req, label:req
   40 	.align 7
   41 .Lventry_start\@:
   42 	.if	\el == 0
   43 	/*
   44 	 * This must be the first instruction of the EL0 vector entries. It is
   45 	 * skipped by the trampoline vectors, to trigger the cleanup.
   46 	 */
   47 	b	.Lskip_tramp_vectors_cleanup\@
   48 	.if	\regsize == 64
   49 	mrs	x30, tpidrro_el0
   50 	msr	tpidrro_el0, xzr
   51 	.else
   52 	mov	x30, xzr
   53 	.endif
   54 .Lskip_tramp_vectors_cleanup\@:
   55 	.endif
   56 
   57 	sub	sp, sp, #PT_REGS_SIZE
   58 	/*
   59 	 * Test whether the SP has overflowed, without corrupting a GPR.
   60 	 * Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT)
   61 	 * should always be zero.
   62 	 */
   63 	add	sp, sp, x0			// sp' = sp + x0
   64 	sub	x0, sp, x0			// x0' = sp' - x0 = (sp + x0) - x0 = sp
   65 	tbnz	x0, #THREAD_SHIFT, 0f
   66 	sub	x0, sp, x0			// x0'' = sp' - x0' = (sp + x0) - sp = x0
   67 	sub	sp, sp, x0			// sp'' = sp' - x0 = (sp + x0) - x0 = sp
   68 	b	el\el\ht\()_\regsize\()_\label
   69 
   70 0:
   71 	/*
   72 	 * Either we've just detected an overflow, or we've taken an exception
   73 	 * while on the overflow stack. Either way, we won't return to
   74 	 * userspace, and can clobber EL0 registers to free up GPRs.
   75 	 */
   76 
   77 	/* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */
   78 	msr	tpidr_el0, x0
   79 
   80 	/* Recover the original x0 value and stash it in tpidrro_el0 */
   81 	sub	x0, sp, x0
   82 	msr	tpidrro_el0, x0
   83 
   84 	/* Switch to the overflow stack */
   85 	adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0
   86 
   87 	/*
   88 	 * Check whether we were already on the overflow stack. This may happen
   89 	 * after panic() re-enables interrupts.
   90 	 */
   91 	mrs	x0, tpidr_el0			// sp of interrupted context
   92 	sub	x0, sp, x0			// delta with top of overflow stack
   93 	tst	x0, #~(OVERFLOW_STACK_SIZE - 1)	// within range?
   94 	b.ne	__bad_stack			// no? -> bad stack pointer
   95 
   96 	/* We were already on the overflow stack. Restore sp/x0 and carry on. */
   97 	sub	sp, sp, x0
   98 	mrs	x0, tpidrro_el0
   99 	b	el\el\ht\()_\regsize\()_\label
  100 .org .Lventry_start\@ + 128	// Did we overflow the ventry slot?
  101 	.endm
  102 
  103 	.macro	tramp_alias, dst, sym
  104 	.set	.Lalias\@, TRAMP_VALIAS + \sym - .entry.tramp.text
  105 	movz	\dst, :abs_g2_s:.Lalias\@
  106 	movk	\dst, :abs_g1_nc:.Lalias\@
  107 	movk	\dst, :abs_g0_nc:.Lalias\@
  108 	.endm
  109 
  110 	/*
  111 	 * This macro corrupts x0-x3. It is the caller's duty  to save/restore
  112 	 * them if required.
  113 	 */
  114 	.macro	apply_ssbd, state, tmp1, tmp2
  115 alternative_cb	ARM64_ALWAYS_SYSTEM, spectre_v4_patch_fw_mitigation_enable
  116 	b	.L__asm_ssbd_skip\@		// Patched to NOP
  117 alternative_cb_end
  118 	ldr_this_cpu	\tmp2, arm64_ssbd_callback_required, \tmp1
  119 	cbz	\tmp2,	.L__asm_ssbd_skip\@
  120 	ldr	\tmp2, [tsk, #TSK_TI_FLAGS]
  121 	tbnz	\tmp2, #TIF_SSBD, .L__asm_ssbd_skip\@
  122 	mov	w0, #ARM_SMCCC_ARCH_WORKAROUND_2
  123 	mov	w1, #\state
  124 alternative_cb	ARM64_ALWAYS_SYSTEM, smccc_patch_fw_mitigation_conduit
  125 	nop					// Patched to SMC/HVC #0
  126 alternative_cb_end
  127 .L__asm_ssbd_skip\@:
  128 	.endm
  129 
  130 	/* Check for MTE asynchronous tag check faults */
  131 	.macro check_mte_async_tcf, tmp, ti_flags, thread_sctlr
  132 #ifdef CONFIG_ARM64_MTE
  133 	.arch_extension lse
  134 alternative_if_not ARM64_MTE
  135 	b	1f
  136 alternative_else_nop_endif
  137 	/*
  138 	 * Asynchronous tag check faults are only possible in ASYNC (2) or
  139 	 * ASYM (3) modes. In each of these modes bit 1 of SCTLR_EL1.TCF0 is
  140 	 * set, so skip the check if it is unset.
  141 	 */
  142 	tbz	\thread_sctlr, #(SCTLR_EL1_TCF0_SHIFT + 1), 1f
  143 	mrs_s	\tmp, SYS_TFSRE0_EL1
  144 	tbz	\tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f
  145 	/* Asynchronous TCF occurred for TTBR0 access, set the TI flag */
  146 	mov	\tmp, #_TIF_MTE_ASYNC_FAULT
  147 	add	\ti_flags, tsk, #TSK_TI_FLAGS
  148 	stset	\tmp, [\ti_flags]
  149 1:
  150 #endif
  151 	.endm
  152 
  153 	/* Clear the MTE asynchronous tag check faults */
  154 	.macro clear_mte_async_tcf thread_sctlr
  155 #ifdef CONFIG_ARM64_MTE
  156 alternative_if ARM64_MTE
  157 	/* See comment in check_mte_async_tcf above. */
  158 	tbz	\thread_sctlr, #(SCTLR_EL1_TCF0_SHIFT + 1), 1f
  159 	dsb	ish
  160 	msr_s	SYS_TFSRE0_EL1, xzr
  161 1:
  162 alternative_else_nop_endif
  163 #endif
  164 	.endm
  165 
  166 	.macro mte_set_gcr, mte_ctrl, tmp
  167 #ifdef CONFIG_ARM64_MTE
  168 	ubfx	\tmp, \mte_ctrl, #MTE_CTRL_GCR_USER_EXCL_SHIFT, #16
  169 	orr	\tmp, \tmp, #SYS_GCR_EL1_RRND
  170 	msr_s	SYS_GCR_EL1, \tmp
  171 #endif
  172 	.endm
  173 
  174 	.macro mte_set_kernel_gcr, tmp, tmp2
  175 #ifdef CONFIG_KASAN_HW_TAGS
  176 alternative_cb	ARM64_ALWAYS_SYSTEM, kasan_hw_tags_enable
  177 	b	1f
  178 alternative_cb_end
  179 	mov	\tmp, KERNEL_GCR_EL1
  180 	msr_s	SYS_GCR_EL1, \tmp
  181 1:
  182 #endif
  183 	.endm
  184 
  185 	.macro mte_set_user_gcr, tsk, tmp, tmp2
  186 #ifdef CONFIG_KASAN_HW_TAGS
  187 alternative_cb	ARM64_ALWAYS_SYSTEM, kasan_hw_tags_enable
  188 	b	1f
  189 alternative_cb_end
  190 	ldr	\tmp, [\tsk, #THREAD_MTE_CTRL]
  191 
  192 	mte_set_gcr \tmp, \tmp2
  193 1:
  194 #endif
  195 	.endm
  196 
  197 	.macro	kernel_entry, el, regsize = 64
  198 	.if	\el == 0
  199 	alternative_insn nop, SET_PSTATE_DIT(1), ARM64_HAS_DIT
  200 	.endif
  201 	.if	\regsize == 32
  202 	mov	w0, w0				// zero upper 32 bits of x0
  203 	.endif
  204 	stp	x0, x1, [sp, #16 * 0]
  205 	stp	x2, x3, [sp, #16 * 1]
  206 	stp	x4, x5, [sp, #16 * 2]
  207 	stp	x6, x7, [sp, #16 * 3]
  208 	stp	x8, x9, [sp, #16 * 4]
  209 	stp	x10, x11, [sp, #16 * 5]
  210 	stp	x12, x13, [sp, #16 * 6]
  211 	stp	x14, x15, [sp, #16 * 7]
  212 	stp	x16, x17, [sp, #16 * 8]
  213 	stp	x18, x19, [sp, #16 * 9]
  214 	stp	x20, x21, [sp, #16 * 10]
  215 	stp	x22, x23, [sp, #16 * 11]
  216 	stp	x24, x25, [sp, #16 * 12]
  217 	stp	x26, x27, [sp, #16 * 13]
  218 	stp	x28, x29, [sp, #16 * 14]
  219 
  220 	.if	\el == 0
  221 	clear_gp_regs
  222 	mrs	x21, sp_el0
  223 	ldr_this_cpu	tsk, __entry_task, x20
  224 	msr	sp_el0, tsk
  225 
  226 	/*
  227 	 * Ensure MDSCR_EL1.SS is clear, since we can unmask debug exceptions
  228 	 * when scheduling.
  229 	 */
  230 	ldr	x19, [tsk, #TSK_TI_FLAGS]
  231 	disable_step_tsk x19, x20
  232 
  233 	/* Check for asynchronous tag check faults in user space */
  234 	ldr	x0, [tsk, THREAD_SCTLR_USER]
  235 	check_mte_async_tcf x22, x23, x0
  236 
  237 #ifdef CONFIG_ARM64_PTR_AUTH
  238 alternative_if ARM64_HAS_ADDRESS_AUTH
  239 	/*
  240 	 * Enable IA for in-kernel PAC if the task had it disabled. Although
  241 	 * this could be implemented with an unconditional MRS which would avoid
  242 	 * a load, this was measured to be slower on Cortex-A75 and Cortex-A76.
  243 	 *
  244 	 * Install the kernel IA key only if IA was enabled in the task. If IA
  245 	 * was disabled on kernel exit then we would have left the kernel IA
  246 	 * installed so there is no need to install it again.
  247 	 */
  248 	tbz	x0, SCTLR_ELx_ENIA_SHIFT, 1f
  249 	__ptrauth_keys_install_kernel_nosync tsk, x20, x22, x23
  250 	b	2f
  251 1:
  252 	mrs	x0, sctlr_el1
  253 	orr	x0, x0, SCTLR_ELx_ENIA
  254 	msr	sctlr_el1, x0
  255 2:
  256 alternative_else_nop_endif
  257 #endif
  258 
  259 	apply_ssbd 1, x22, x23
  260 
  261 	mte_set_kernel_gcr x22, x23
  262 
  263 	/*
  264 	 * Any non-self-synchronizing system register updates required for
  265 	 * kernel entry should be placed before this point.
  266 	 */
  267 alternative_if ARM64_MTE
  268 	isb
  269 	b	1f
  270 alternative_else_nop_endif
  271 alternative_if ARM64_HAS_ADDRESS_AUTH
  272 	isb
  273 alternative_else_nop_endif
  274 1:
  275 
  276 	scs_load_current
  277 	.else
  278 	add	x21, sp, #PT_REGS_SIZE
  279 	get_current_task tsk
  280 	.endif /* \el == 0 */
  281 	mrs	x22, elr_el1
  282 	mrs	x23, spsr_el1
  283 	stp	lr, x21, [sp, #S_LR]
  284 
  285 	/*
  286 	 * Create a metadata frame record. The unwinder will use this to
  287 	 * identify and unwind exception boundaries.
  288 	 */
  289 	stp	xzr, xzr, [sp, #S_STACKFRAME]
  290 	.if \el == 0
  291 	mov	x0, #FRAME_META_TYPE_FINAL
  292 	.else
  293 	mov	x0, #FRAME_META_TYPE_PT_REGS
  294 	.endif
  295 	str	x0, [sp, #S_STACKFRAME_TYPE]
  296 	add	x29, sp, #S_STACKFRAME
  297 
  298 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
  299 alternative_if_not ARM64_HAS_PAN
  300 	bl	__swpan_entry_el\el
  301 alternative_else_nop_endif
  302 #endif
  303 
  304 	stp	x22, x23, [sp, #S_PC]
  305 
  306 	/* Not in a syscall by default (el0_svc overwrites for real syscall) */
  307 	.if	\el == 0
  308 	mov	w21, #NO_SYSCALL
  309 	str	w21, [sp, #S_SYSCALLNO]
  310 	.endif
  311 
  312 #ifdef CONFIG_ARM64_PSEUDO_NMI
  313 alternative_if_not ARM64_HAS_GIC_PRIO_MASKING
  314 	b	.Lskip_pmr_save\@
  315 alternative_else_nop_endif
  316 
  317 	mrs_s	x20, SYS_ICC_PMR_EL1
  318 	str	w20, [sp, #S_PMR]
  319 	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
  320 	msr_s	SYS_ICC_PMR_EL1, x20
  321 
  322 .Lskip_pmr_save\@:
  323 #endif
  324 
  325 	/*
  326 	 * Registers that may be useful after this macro is invoked:
  327 	 *
  328 	 * x20 - ICC_PMR_EL1
  329 	 * x21 - aborted SP
  330 	 * x22 - aborted PC
  331 	 * x23 - aborted PSTATE
  332 	*/
  333 	.endm
  334 
  335 	.macro	kernel_exit, el
  336 	.if	\el != 0
  337 	disable_daif
  338 	.endif
  339 
  340 #ifdef CONFIG_ARM64_PSEUDO_NMI
  341 alternative_if_not ARM64_HAS_GIC_PRIO_MASKING
  342 	b	.Lskip_pmr_restore\@
  343 alternative_else_nop_endif
  344 
  345 	ldr	w20, [sp, #S_PMR]
  346 	msr_s	SYS_ICC_PMR_EL1, x20
  347 
  348 	/* Ensure priority change is seen by redistributor */
  349 alternative_if_not ARM64_HAS_GIC_PRIO_RELAXED_SYNC
  350 	dsb	sy
  351 alternative_else_nop_endif
  352 
  353 .Lskip_pmr_restore\@:
  354 #endif
  355 
  356 	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
  357 
  358 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
  359 alternative_if_not ARM64_HAS_PAN
  360 	bl	__swpan_exit_el\el
  361 alternative_else_nop_endif
  362 #endif
  363 
  364 	.if	\el == 0
  365 	ldr	x23, [sp, #S_SP]		// load return stack pointer
  366 	msr	sp_el0, x23
  367 	tst	x22, #PSR_MODE32_BIT		// native task?
  368 	b.eq	3f
  369 
  370 #ifdef CONFIG_ARM64_ERRATUM_845719
  371 alternative_if ARM64_WORKAROUND_845719
  372 #ifdef CONFIG_PID_IN_CONTEXTIDR
  373 	mrs	x29, contextidr_el1
  374 	msr	contextidr_el1, x29
  375 #else
  376 	msr contextidr_el1, xzr
  377 #endif
  378 alternative_else_nop_endif
  379 #endif
  380 3:
  381 	scs_save tsk
  382 
  383 	/* Ignore asynchronous tag check faults in the uaccess routines */
  384 	ldr	x0, [tsk, THREAD_SCTLR_USER]
  385 	clear_mte_async_tcf x0
  386 
  387 #ifdef CONFIG_ARM64_PTR_AUTH
  388 alternative_if ARM64_HAS_ADDRESS_AUTH
  389 	/*
  390 	 * IA was enabled for in-kernel PAC. Disable it now if needed, or
  391 	 * alternatively install the user's IA. All other per-task keys and
  392 	 * SCTLR bits were updated on task switch.
  393 	 *
  394 	 * No kernel C function calls after this.
  395 	 */
  396 	tbz	x0, SCTLR_ELx_ENIA_SHIFT, 1f
  397 	__ptrauth_keys_install_user tsk, x0, x1, x2
  398 	b	2f
  399 1:
  400 	mrs	x0, sctlr_el1
  401 	bic	x0, x0, SCTLR_ELx_ENIA
  402 	msr	sctlr_el1, x0
  403 2:
  404 alternative_else_nop_endif
  405 #endif
  406 
  407 	mte_set_user_gcr tsk, x0, x1
  408 
  409 	apply_ssbd 0, x0, x1
  410 	.endif
  411 
  412 	msr	elr_el1, x21			// set up the return data
  413 	msr	spsr_el1, x22
  414 	ldp	x0, x1, [sp, #16 * 0]
  415 	ldp	x2, x3, [sp, #16 * 1]
  416 	ldp	x4, x5, [sp, #16 * 2]
  417 	ldp	x6, x7, [sp, #16 * 3]
  418 	ldp	x8, x9, [sp, #16 * 4]
  419 	ldp	x10, x11, [sp, #16 * 5]
  420 	ldp	x12, x13, [sp, #16 * 6]
  421 	ldp	x14, x15, [sp, #16 * 7]
  422 	ldp	x16, x17, [sp, #16 * 8]
  423 	ldp	x18, x19, [sp, #16 * 9]
  424 	ldp	x20, x21, [sp, #16 * 10]
  425 	ldp	x22, x23, [sp, #16 * 11]
  426 	ldp	x24, x25, [sp, #16 * 12]
  427 	ldp	x26, x27, [sp, #16 * 13]
  428 	ldp	x28, x29, [sp, #16 * 14]
  429 
  430 	.if	\el == 0
  431 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
  432 	alternative_insn "b .L_skip_tramp_exit_\@", nop, ARM64_UNMAP_KERNEL_AT_EL0
  433 
  434 	msr	far_el1, x29
  435 
  436 	ldr_this_cpu	x30, this_cpu_vector, x29
  437 	tramp_alias	x29, tramp_exit
  438 	msr		vbar_el1, x30		// install vector table
  439 	ldr		lr, [sp, #S_LR]		// restore x30
  440 	add		sp, sp, #PT_REGS_SIZE	// restore sp
  441 	br		x29
  442 
  443 .L_skip_tramp_exit_\@:
  444 #endif
  445 	.endif
  446 
  447 	ldr	lr, [sp, #S_LR]
  448 	add	sp, sp, #PT_REGS_SIZE		// restore sp
  449 
  450 	.if \el == 0
  451 	/* This must be after the last explicit memory access */
  452 alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
  453 	tlbi	vale1, xzr
  454 	dsb	nsh
  455 alternative_else_nop_endif
  456 	.else
  457 	/* Ensure any device/NC reads complete */
  458 	alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412
  459 	.endif
  460 
  461 	eret
  462 	sb
  463 	.endm
  464 
  465 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
  466 	/*
  467 	 * Set the TTBR0 PAN bit in SPSR. When the exception is taken from
  468 	 * EL0, there is no need to check the state of TTBR0_EL1 since
  469 	 * accesses are always enabled.
  470 	 * Note that the meaning of this bit differs from the ARMv8.1 PAN
  471 	 * feature as all TTBR0_EL1 accesses are disabled, not just those to
  472 	 * user mappings.
  473 	 */
  474 SYM_CODE_START_LOCAL(__swpan_entry_el1)
  475 	mrs	x21, ttbr0_el1
  476 	tst	x21, #TTBR_ASID_MASK		// Check for the reserved ASID
  477 	orr	x23, x23, #PSR_PAN_BIT		// Set the emulated PAN in the saved SPSR
  478 	b.eq	1f				// TTBR0 access already disabled
  479 	and	x23, x23, #~PSR_PAN_BIT		// Clear the emulated PAN in the saved SPSR
  480 SYM_INNER_LABEL(__swpan_entry_el0, SYM_L_LOCAL)
  481 	__uaccess_ttbr0_disable x21
  482 1:	ret
  483 SYM_CODE_END(__swpan_entry_el1)
  484 
  485 	/*
  486 	 * Restore access to TTBR0_EL1. If returning to EL0, no need for SPSR
  487 	 * PAN bit checking.
  488 	 */
  489 SYM_CODE_START_LOCAL(__swpan_exit_el1)
  490 	tbnz	x22, #22, 1f			// Skip re-enabling TTBR0 access if the PSR_PAN_BIT is set
  491 	__uaccess_ttbr0_enable x0, x1
  492 1:	and	x22, x22, #~PSR_PAN_BIT		// ARMv8.0 CPUs do not understand this bit
  493 	ret
  494 SYM_CODE_END(__swpan_exit_el1)
  495 
  496 SYM_CODE_START_LOCAL(__swpan_exit_el0)
  497 	__uaccess_ttbr0_enable x0, x1
  498 	/*
  499 	 * Enable errata workarounds only if returning to user. The only
  500 	 * workaround currently required for TTBR0_EL1 changes are for the
  501 	 * Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache
  502 	 * corruption).
  503 	 */
  504 	b	post_ttbr_update_workaround
  505 SYM_CODE_END(__swpan_exit_el0)
  506 #endif
  507 
  508 /* GPRs used by entry code */
  509 tsk	.req	x28		// current thread_info
  510 
  511 	.text
  512 
  513 /*
  514  * Exception vectors.
  515  */
  516 	.pushsection ".entry.text", "ax"
  517 
  518 	.align	11
  519 SYM_CODE_START(vectors)
  520 	kernel_ventry	1, t, 64, sync		// Synchronous EL1t
  521 	kernel_ventry	1, t, 64, irq		// IRQ EL1t
  522 	kernel_ventry	1, t, 64, fiq		// FIQ EL1t
  523 	kernel_ventry	1, t, 64, error		// Error EL1t
  524 
  525 	kernel_ventry	1, h, 64, sync		// Synchronous EL1h
  526 	kernel_ventry	1, h, 64, irq		// IRQ EL1h
  527 	kernel_ventry	1, h, 64, fiq		// FIQ EL1h
  528 	kernel_ventry	1, h, 64, error		// Error EL1h
  529 
  530 	kernel_ventry	0, t, 64, sync		// Synchronous 64-bit EL0
  531 	kernel_ventry	0, t, 64, irq		// IRQ 64-bit EL0
  532 	kernel_ventry	0, t, 64, fiq		// FIQ 64-bit EL0
  533 	kernel_ventry	0, t, 64, error		// Error 64-bit EL0
  534 
  535 	kernel_ventry	0, t, 32, sync		// Synchronous 32-bit EL0
  536 	kernel_ventry	0, t, 32, irq		// IRQ 32-bit EL0
  537 	kernel_ventry	0, t, 32, fiq		// FIQ 32-bit EL0
  538 	kernel_ventry	0, t, 32, error		// Error 32-bit EL0
  539 SYM_CODE_END(vectors)
  540 
  541 SYM_CODE_START_LOCAL(__bad_stack)
  542 	/*
  543 	 * We detected an overflow in kernel_ventry, which switched to the
  544 	 * overflow stack. Stash the exception regs, and head to our overflow
  545 	 * handler.
  546 	 */
  547 
  548 	/* Restore the original x0 value */
  549 	mrs	x0, tpidrro_el0
  550 
  551 	/*
  552 	 * Store the original GPRs to the new stack. The orginal SP (minus
  553 	 * PT_REGS_SIZE) was stashed in tpidr_el0 by kernel_ventry.
  554 	 */
  555 	sub	sp, sp, #PT_REGS_SIZE
  556 	kernel_entry 1
  557 	mrs	x0, tpidr_el0
  558 	add	x0, x0, #PT_REGS_SIZE
  559 	str	x0, [sp, #S_SP]
  560 
  561 	/* Stash the regs for handle_bad_stack */
  562 	mov	x0, sp
  563 
  564 	/* Time to die */
  565 	bl	handle_bad_stack
  566 	ASM_BUG()
  567 SYM_CODE_END(__bad_stack)
  568 
  569 
  570 	.macro entry_handler el:req, ht:req, regsize:req, label:req
  571 SYM_CODE_START_LOCAL(el\el\ht\()_\regsize\()_\label)
  572 	kernel_entry \el, \regsize
  573 	mov	x0, sp
  574 	bl	el\el\ht\()_\regsize\()_\label\()_handler
  575 	.if \el == 0
  576 	b	ret_to_user
  577 	.else
  578 	b	ret_to_kernel
  579 	.endif
  580 SYM_CODE_END(el\el\ht\()_\regsize\()_\label)
  581 	.endm
  582 
  583 /*
  584  * Early exception handlers
  585  */
  586 	entry_handler	1, t, 64, sync
  587 	entry_handler	1, t, 64, irq
  588 	entry_handler	1, t, 64, fiq
  589 	entry_handler	1, t, 64, error
  590 
  591 	entry_handler	1, h, 64, sync
  592 	entry_handler	1, h, 64, irq
  593 	entry_handler	1, h, 64, fiq
  594 	entry_handler	1, h, 64, error
  595 
  596 	entry_handler	0, t, 64, sync
  597 	entry_handler	0, t, 64, irq
  598 	entry_handler	0, t, 64, fiq
  599 	entry_handler	0, t, 64, error
  600 
  601 	entry_handler	0, t, 32, sync
  602 	entry_handler	0, t, 32, irq
  603 	entry_handler	0, t, 32, fiq
  604 	entry_handler	0, t, 32, error
  605 
  606 SYM_CODE_START_LOCAL(ret_to_kernel)
  607 	kernel_exit 1
  608 SYM_CODE_END(ret_to_kernel)
  609 
  610 SYM_CODE_START_LOCAL(ret_to_user)
  611 	ldr	x19, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
  612 	enable_step_tsk x19, x2
  613 #ifdef CONFIG_KSTACK_ERASE
  614 	bl	stackleak_erase_on_task_stack
  615 #endif
  616 	kernel_exit 0
  617 SYM_CODE_END(ret_to_user)
  618 
  619 	.popsection				// .entry.text
  620 
  621 	// Move from tramp_pg_dir to swapper_pg_dir
  622 	.macro tramp_map_kernel, tmp
  623 	mrs	\tmp, ttbr1_el1
  624 	add	\tmp, \tmp, #TRAMP_SWAPPER_OFFSET
  625 	bic	\tmp, \tmp, #USER_ASID_FLAG
  626 	msr	ttbr1_el1, \tmp
  627 #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
  628 alternative_if ARM64_WORKAROUND_QCOM_FALKOR_E1003
  629 	/* ASID already in \tmp[63:48] */
  630 	movk	\tmp, #:abs_g2_nc:(TRAMP_VALIAS >> 12)
  631 	movk	\tmp, #:abs_g1_nc:(TRAMP_VALIAS >> 12)
  632 	/* 2MB boundary containing the vectors, so we nobble the walk cache */
  633 	movk	\tmp, #:abs_g0_nc:((TRAMP_VALIAS & ~(SZ_2M - 1)) >> 12)
  634 	isb
  635 	tlbi	vae1, \tmp
  636 	dsb	nsh
  637 alternative_else_nop_endif
  638 #endif /* CONFIG_QCOM_FALKOR_ERRATUM_1003 */
  639 	.endm
  640 
  641 	// Move from swapper_pg_dir to tramp_pg_dir
  642 	.macro tramp_unmap_kernel, tmp
  643 	mrs	\tmp, ttbr1_el1
  644 	sub	\tmp, \tmp, #TRAMP_SWAPPER_OFFSET
  645 	orr	\tmp, \tmp, #USER_ASID_FLAG
  646 	msr	ttbr1_el1, \tmp
  647 	/*
  648 	 * We avoid running the post_ttbr_update_workaround here because
  649 	 * it's only needed by Cavium ThunderX, which requires KPTI to be
  650 	 * disabled.
  651 	 */
  652 	.endm
  653 
  654 	.macro		tramp_data_read_var	dst, var
  655 #ifdef CONFIG_RELOCATABLE
  656 	ldr		\dst, .L__tramp_data_\var
  657 	.ifndef		.L__tramp_data_\var
  658 	.pushsection	".entry.tramp.rodata", "a", %progbits
  659 	.align		3
  660 .L__tramp_data_\var:
  661 	.quad		\var
  662 	.popsection
  663 	.endif
  664 #else
  665 	/*
  666 	 * As !RELOCATABLE implies !RANDOMIZE_BASE the address is always a
  667 	 * compile time constant (and hence not secret and not worth hiding).
  668 	 *
  669 	 * As statically allocated kernel code and data always live in the top
  670 	 * 47 bits of the address space we can sign-extend bit 47 and avoid an
  671 	 * instruction to load the upper 16 bits (which must be 0xFFFF).
  672 	 */
  673 	movz		\dst, :abs_g2_s:\var
  674 	movk		\dst, :abs_g1_nc:\var
  675 	movk		\dst, :abs_g0_nc:\var
  676 #endif
  677 	.endm
  678 
  679 #define BHB_MITIGATION_NONE	0
  680 #define BHB_MITIGATION_LOOP	1
  681 #define BHB_MITIGATION_FW	2
  682 #define BHB_MITIGATION_INSN	3
  683 
  684 	.macro tramp_ventry, vector_start, regsize, kpti, bhb
  685 	.align	7
  686 1:
  687 	.if	\regsize == 64
  688 	msr	tpidrro_el0, x30	// Restored in kernel_ventry
  689 	.endif
  690 
  691 	.if	\bhb == BHB_MITIGATION_LOOP
  692 	/*
  693 	 * This sequence must appear before the first indirect branch. i.e. the
  694 	 * ret out of tramp_ventry. It appears here because x30 is free.
  695 	 */
  696 	__mitigate_spectre_bhb_loop	x30
  697 	.endif // \bhb == BHB_MITIGATION_LOOP
  698 
  699 	.if	\bhb == BHB_MITIGATION_INSN
  700 	clearbhb
  701 	isb
  702 	.endif // \bhb == BHB_MITIGATION_INSN
  703 
  704 	.if	\kpti == 1
  705 	/*
  706 	 * Defend against branch aliasing attacks by pushing a dummy
  707 	 * entry onto the return stack and using a RET instruction to
  708 	 * enter the full-fat kernel vectors.
  709 	 */
  710 	bl	2f
  711 	b	.
  712 2:
  713 	tramp_map_kernel	x30
  714 alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
  715 	tramp_data_read_var	x30, vectors
  716 alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM
  717 	prfm	plil1strm, [x30, #(1b - \vector_start)]
  718 alternative_else_nop_endif
  719 
  720 	msr	vbar_el1, x30
  721 	isb
  722 	.else
  723 	adr_l	x30, vectors
  724 	.endif // \kpti == 1
  725 
  726 	.if	\bhb == BHB_MITIGATION_FW
  727 	/*
  728 	 * The firmware sequence must appear before the first indirect branch.
  729 	 * i.e. the ret out of tramp_ventry. But it also needs the stack to be
  730 	 * mapped to save/restore the registers the SMC clobbers.
  731 	 */
  732 	__mitigate_spectre_bhb_fw
  733 	.endif // \bhb == BHB_MITIGATION_FW
  734 
  735 	add	x30, x30, #(1b - \vector_start + 4)
  736 	ret
  737 .org 1b + 128	// Did we overflow the ventry slot?
  738 	.endm
  739 
  740 	.macro	generate_tramp_vector,	kpti, bhb
  741 .Lvector_start\@:
  742 	.space	0x400
  743 
  744 	.rept	4
  745 	tramp_ventry	.Lvector_start\@, 64, \kpti, \bhb
  746 	.endr
  747 	.rept	4
  748 	tramp_ventry	.Lvector_start\@, 32, \kpti, \bhb
  749 	.endr
  750 	.endm
  751 
  752 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
  753 /*
  754  * Exception vectors trampoline.
  755  * The order must match __bp_harden_el1_vectors and the
  756  * arm64_bp_harden_el1_vectors enum.
  757  */
  758 	.pushsection ".entry.tramp.text", "ax"
  759 	.align	11
  760 SYM_CODE_START_LOCAL_NOALIGN(tramp_vectors)
  761 #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
  762 	generate_tramp_vector	kpti=1, bhb=BHB_MITIGATION_LOOP
  763 	generate_tramp_vector	kpti=1, bhb=BHB_MITIGATION_FW
  764 	generate_tramp_vector	kpti=1, bhb=BHB_MITIGATION_INSN
  765 #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
  766 	generate_tramp_vector	kpti=1, bhb=BHB_MITIGATION_NONE
  767 SYM_CODE_END(tramp_vectors)
  768 
  769 SYM_CODE_START_LOCAL(tramp_exit)
  770 	tramp_unmap_kernel	x29
  771 	mrs		x29, far_el1		// restore x29
  772 	eret
  773 	sb
  774 SYM_CODE_END(tramp_exit)
  775 	.popsection				// .entry.tramp.text
  776 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
  777 
  778 /*
  779  * Exception vectors for spectre mitigations on entry from EL1 when
  780  * kpti is not in use.
  781  */
  782 	.macro generate_el1_vector, bhb
  783 .Lvector_start\@:
  784 	kernel_ventry	1, t, 64, sync		// Synchronous EL1t
  785 	kernel_ventry	1, t, 64, irq		// IRQ EL1t
  786 	kernel_ventry	1, t, 64, fiq		// FIQ EL1h
  787 	kernel_ventry	1, t, 64, error		// Error EL1t
  788 
  789 	kernel_ventry	1, h, 64, sync		// Synchronous EL1h
  790 	kernel_ventry	1, h, 64, irq		// IRQ EL1h
  791 	kernel_ventry	1, h, 64, fiq		// FIQ EL1h
  792 	kernel_ventry	1, h, 64, error		// Error EL1h
  793 
  794 	.rept	4
  795 	tramp_ventry	.Lvector_start\@, 64, 0, \bhb
  796 	.endr
  797 	.rept 4
  798 	tramp_ventry	.Lvector_start\@, 32, 0, \bhb
  799 	.endr
  800 	.endm
  801 
  802 /* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */
  803 	.pushsection ".entry.text", "ax"
  804 	.align	11
  805 SYM_CODE_START(__bp_harden_el1_vectors)
  806 #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
  807 	generate_el1_vector	bhb=BHB_MITIGATION_LOOP
  808 	generate_el1_vector	bhb=BHB_MITIGATION_FW
  809 	generate_el1_vector	bhb=BHB_MITIGATION_INSN
  810 #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
  811 SYM_CODE_END(__bp_harden_el1_vectors)
  812 	.popsection
  813 
  814 
  815 /*
  816  * Register switch for AArch64. The callee-saved registers need to be saved
  817  * and restored. On entry:
  818  *   x0 = previous task_struct (must be preserved across the switch)
  819  *   x1 = next task_struct
  820  * Previous and next are guaranteed not to be the same.
  821  *
  822  */
  823 SYM_FUNC_START(cpu_switch_to)
  824 	save_and_disable_daif x11
  825 	mov	x10, #THREAD_CPU_CONTEXT
  826 	add	x8, x0, x10
  827 	mov	x9, sp
  828 	stp	x19, x20, [x8], #16		// store callee-saved registers
  829 	stp	x21, x22, [x8], #16
  830 	stp	x23, x24, [x8], #16
  831 	stp	x25, x26, [x8], #16
  832 	stp	x27, x28, [x8], #16
  833 	stp	x29, x9, [x8], #16
  834 	str	lr, [x8]
  835 	add	x8, x1, x10
  836 	ldp	x19, x20, [x8], #16		// restore callee-saved registers
  837 	ldp	x21, x22, [x8], #16
  838 	ldp	x23, x24, [x8], #16
  839 	ldp	x25, x26, [x8], #16
  840 	ldp	x27, x28, [x8], #16
  841 	ldp	x29, x9, [x8], #16
  842 	ldr	lr, [x8]
  843 	mov	sp, x9
  844 	msr	sp_el0, x1
  845 	ptrauth_keys_install_kernel x1, x8, x9, x10
  846 	scs_save x0
  847 	scs_load_current
  848 	restore_irq x11
  849 	ret
  850 SYM_FUNC_END(cpu_switch_to)
  851 NOKPROBE(cpu_switch_to)
  852 
  853 /*
  854  * This is how we return from a fork.
  855  */
  856 SYM_CODE_START(ret_from_fork)
  857 	bl	schedule_tail
  858 	cbz	x19, 1f				// not a kernel thread
  859 	mov	x0, x20
  860 	blr	x19
  861 1:	get_current_task tsk
  862 	mov	x0, sp
  863 	bl	asm_exit_to_user_mode
  864 	b	ret_to_user
  865 SYM_CODE_END(ret_from_fork)
  866 NOKPROBE(ret_from_fork)
  867 
  868 /*
  869  * void call_on_irq_stack(struct pt_regs *regs,
  870  * 		          void (*func)(struct pt_regs *));
  871  *
  872  * Calls func(regs) using this CPU's irq stack and shadow irq stack.
  873  */
  874 SYM_FUNC_START(call_on_irq_stack)
  875 	save_and_disable_daif x9
  876 #ifdef CONFIG_SHADOW_CALL_STACK
  877 	get_current_task x16
  878 	scs_save x16
  879 	ldr_this_cpu scs_sp, irq_shadow_call_stack_ptr, x17
  880 #endif
  881 
  882 	/* Create a frame record to save our LR and SP (implicit in FP) */
  883 	stp	x29, x30, [sp, #-16]!
  884 	mov	x29, sp
  885 
  886 	ldr_this_cpu x16, irq_stack_ptr, x17
  887 
  888 	/* Move to the new stack and call the function there */
  889 	add	sp, x16, #IRQ_STACK_SIZE
  890 	restore_irq x9
  891 	blr	x1
  892 
  893 	save_and_disable_daif x9
  894 	/*
  895 	 * Restore the SP from the FP, and restore the FP and LR from the frame
  896 	 * record.
  897 	 */
  898 	mov	sp, x29
  899 	ldp	x29, x30, [sp], #16
  900 	scs_load_current
  901 	restore_irq x9
  902 	ret
  903 SYM_FUNC_END(call_on_irq_stack)
  904 NOKPROBE(call_on_irq_stack)
  905 
  906 #ifdef CONFIG_ARM_SDE_INTERFACE
  907 
  908 #include <asm/sdei.h>
  909 #include <uapi/linux/arm_sdei.h>
  910 
  911 .macro sdei_handler_exit exit_mode
  912 	/* On success, this call never returns... */
  913 	cmp	\exit_mode, #SDEI_EXIT_SMC
  914 	b.ne	99f
  915 	smc	#0
  916 	b	.
  917 99:	hvc	#0
  918 	b	.
  919 .endm
  920 
  921 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
  922 /*
  923  * The regular SDEI entry point may have been unmapped along with the rest of
  924  * the kernel. This trampoline restores the kernel mapping to make the x1 memory
  925  * argument accessible.
  926  *
  927  * This clobbers x4, __sdei_handler() will restore this from firmware's
  928  * copy.
  929  */
  930 .pushsection ".entry.tramp.text", "ax"
  931 SYM_CODE_START(__sdei_asm_entry_trampoline)
  932 	mrs	x4, ttbr1_el1
  933 	tbz	x4, #USER_ASID_BIT, 1f
  934 
  935 	tramp_map_kernel tmp=x4
  936 	isb
  937 	mov	x4, xzr
  938 
  939 	/*
  940 	 * Remember whether to unmap the kernel on exit.
  941 	 */
  942 1:	str	x4, [x1, #(SDEI_EVENT_INTREGS + S_SDEI_TTBR1)]
  943 	tramp_data_read_var     x4, __sdei_asm_handler
  944 	br	x4
  945 SYM_CODE_END(__sdei_asm_entry_trampoline)
  946 NOKPROBE(__sdei_asm_entry_trampoline)
  947 
  948 /*
  949  * Make the exit call and restore the original ttbr1_el1
  950  *
  951  * x0 & x1: setup for the exit API call
  952  * x2: exit_mode
  953  * x4: struct sdei_registered_event argument from registration time.
  954  */
  955 SYM_CODE_START(__sdei_asm_exit_trampoline)
  956 	ldr	x4, [x4, #(SDEI_EVENT_INTREGS + S_SDEI_TTBR1)]
  957 	cbnz	x4, 1f
  958 
  959 	tramp_unmap_kernel	tmp=x4
  960 
  961 1:	sdei_handler_exit exit_mode=x2
  962 SYM_CODE_END(__sdei_asm_exit_trampoline)
  963 NOKPROBE(__sdei_asm_exit_trampoline)
  964 .popsection		// .entry.tramp.text
  965 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
  966 
  967 /*
  968  * Software Delegated Exception entry point.
  969  *
  970  * x0: Event number
  971  * x1: struct sdei_registered_event argument from registration time.
  972  * x2: interrupted PC
  973  * x3: interrupted PSTATE
  974  * x4: maybe clobbered by the trampoline
  975  *
  976  * Firmware has preserved x0->x17 for us, we must save/restore the rest to
  977  * follow SMC-CC. We save (or retrieve) all the registers as the handler may
  978  * want them.
  979  */
  980 SYM_CODE_START(__sdei_asm_handler)
  981 	stp     x2, x3, [x1, #SDEI_EVENT_INTREGS + S_PC]
  982 	stp     x4, x5, [x1, #SDEI_EVENT_INTREGS + 16 * 2]
  983 	stp     x6, x7, [x1, #SDEI_EVENT_INTREGS + 16 * 3]
  984 	stp     x8, x9, [x1, #SDEI_EVENT_INTREGS + 16 * 4]
  985 	stp     x10, x11, [x1, #SDEI_EVENT_INTREGS + 16 * 5]
  986 	stp     x12, x13, [x1, #SDEI_EVENT_INTREGS + 16 * 6]
  987 	stp     x14, x15, [x1, #SDEI_EVENT_INTREGS + 16 * 7]
  988 	stp     x16, x17, [x1, #SDEI_EVENT_INTREGS + 16 * 8]
  989 	stp     x18, x19, [x1, #SDEI_EVENT_INTREGS + 16 * 9]
  990 	stp     x20, x21, [x1, #SDEI_EVENT_INTREGS + 16 * 10]
  991 	stp     x22, x23, [x1, #SDEI_EVENT_INTREGS + 16 * 11]
  992 	stp     x24, x25, [x1, #SDEI_EVENT_INTREGS + 16 * 12]
  993 	stp     x26, x27, [x1, #SDEI_EVENT_INTREGS + 16 * 13]
  994 	stp     x28, x29, [x1, #SDEI_EVENT_INTREGS + 16 * 14]
  995 	mov	x4, sp
  996 	stp     lr, x4, [x1, #SDEI_EVENT_INTREGS + S_LR]
  997 
  998 	mov	x19, x1
  999 
 1000 	/* Store the registered-event for crash_smp_send_stop() */
 1001 	ldrb	w4, [x19, #SDEI_EVENT_PRIORITY]
 1002 	cbnz	w4, 1f
 1003 	adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6
 1004 	b	2f
 1005 1:	adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6
 1006 2:	str	x19, [x5]
 1007 
 1008 	/*
 1009 	 * entry.S may have been using sp as a scratch register, find whether
 1010 	 * this is a normal or critical event and switch to the appropriate
 1011 	 * stack for this CPU.
 1012 	 */
 1013 	cbnz	w4, 1f
 1014 	ldr_this_cpu dst=x5, sym=sdei_stack_normal_ptr, tmp=x6
 1015 	b	2f
 1016 1:	ldr_this_cpu dst=x5, sym=sdei_stack_critical_ptr, tmp=x6
 1017 2:	mov	x6, #SDEI_STACK_SIZE
 1018 	add	x5, x5, x6
 1019 	mov	sp, x5
 1020 
 1021 #ifdef CONFIG_SHADOW_CALL_STACK
 1022 	/* Use a separate shadow call stack for normal and critical events */
 1023 	cbnz	w4, 3f
 1024 	ldr_this_cpu dst=scs_sp, sym=sdei_shadow_call_stack_normal_ptr, tmp=x6
 1025 	b	4f
 1026 3:	ldr_this_cpu dst=scs_sp, sym=sdei_shadow_call_stack_critical_ptr, tmp=x6
 1027 4:
 1028 #endif
 1029 
 1030 	/*
 1031 	 * We may have interrupted userspace, or a guest, or exit-from or
 1032 	 * return-to either of these. We can't trust sp_el0, restore it.
 1033 	 */
 1034 	mrs	x28, sp_el0
 1035 	ldr_this_cpu	dst=x0, sym=__entry_task, tmp=x1
 1036 	msr	sp_el0, x0
 1037 
 1038 	/* If we interrupted the kernel point to the previous stack/frame. */
 1039 	and     x0, x3, #0xc
 1040 	mrs     x1, CurrentEL
 1041 	cmp     x0, x1
 1042 	csel	x29, x29, xzr, eq	// fp, or zero
 1043 	csel	x4, x2, xzr, eq		// elr, or zero
 1044 
 1045 	stp	x29, x4, [sp, #-16]!
 1046 	mov	x29, sp
 1047 
 1048 	add	x0, x19, #SDEI_EVENT_INTREGS
 1049 	mov	x1, x19
 1050 	bl	__sdei_handler
 1051 
 1052 	msr	sp_el0, x28
 1053 	/* restore regs >x17 that we clobbered */
 1054 	mov	x4, x19         // keep x4 for __sdei_asm_exit_trampoline
 1055 	ldp	x28, x29, [x4, #SDEI_EVENT_INTREGS + 16 * 14]
 1056 	ldp	x18, x19, [x4, #SDEI_EVENT_INTREGS + 16 * 9]
 1057 	ldp	lr, x1, [x4, #SDEI_EVENT_INTREGS + S_LR]
 1058 	mov	sp, x1
 1059 
 1060 	mov	x1, x0			// address to complete_and_resume
 1061 	/* x0 = (x0 <= SDEI_EV_FAILED) ?
 1062 	 * EVENT_COMPLETE:EVENT_COMPLETE_AND_RESUME
 1063 	 */
 1064 	cmp	x0, #SDEI_EV_FAILED
 1065 	mov_q	x2, SDEI_1_0_FN_SDEI_EVENT_COMPLETE
 1066 	mov_q	x3, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME
 1067 	csel	x0, x2, x3, ls
 1068 
 1069 	ldr_l	x2, sdei_exit_mode
 1070 
 1071 	/* Clear the registered-event seen by crash_smp_send_stop() */
 1072 	ldrb	w3, [x4, #SDEI_EVENT_PRIORITY]
 1073 	cbnz	w3, 1f
 1074 	adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6
 1075 	b	2f
 1076 1:	adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6
 1077 2:	str	xzr, [x5]
 1078 
 1079 alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
 1080 	sdei_handler_exit exit_mode=x2
 1081 alternative_else_nop_endif
 1082 
 1083 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 1084 	tramp_alias	dst=x5, sym=__sdei_asm_exit_trampoline
 1085 	br	x5
 1086 #endif
 1087 SYM_CODE_END(__sdei_asm_handler)
 1088 NOKPROBE(__sdei_asm_handler)
 1089 
 1090 SYM_CODE_START(__sdei_handler_abort)
 1091 	mov_q	x0, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME
 1092 	adr	x1, 1f
 1093 	ldr_l	x2, sdei_exit_mode
 1094 	sdei_handler_exit exit_mode=x2
 1095 	// exit the handler and jump to the next instruction.
 1096 	// Exit will stomp x0-x17, PSTATE, ELR_ELx, and SPSR_ELx.
 1097 1:	ret
 1098 SYM_CODE_END(__sdei_handler_abort)
 1099 NOKPROBE(__sdei_handler_abort)
 1100 #endif /* CONFIG_ARM_SDE_INTERFACE */