xref: /openbmc/linux/arch/arm64/kernel/entry.S (revision 680ef72a)
1/*
2 * Low-level exception handling code
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Authors:	Catalin Marinas <catalin.marinas@arm.com>
6 *		Will Deacon <will.deacon@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/init.h>
22#include <linux/linkage.h>
23
24#include <asm/alternative.h>
25#include <asm/assembler.h>
26#include <asm/asm-offsets.h>
27#include <asm/cpufeature.h>
28#include <asm/errno.h>
29#include <asm/esr.h>
30#include <asm/irq.h>
31#include <asm/processor.h>
32#include <asm/ptrace.h>
33#include <asm/thread_info.h>
34#include <asm/asm-uaccess.h>
35#include <asm/unistd.h>
36
37/*
38 * Context tracking subsystem.  Used to instrument transitions
39 * between user and kernel mode.
40 */
41	.macro ct_user_exit, syscall = 0
42#ifdef CONFIG_CONTEXT_TRACKING
43	bl	context_tracking_user_exit
44	.if \syscall == 1
45	/*
46	 * Save/restore needed during syscalls.  Restore syscall arguments from
47	 * the values already saved on stack during kernel_entry.
48	 */
49	ldp	x0, x1, [sp]
50	ldp	x2, x3, [sp, #S_X2]
51	ldp	x4, x5, [sp, #S_X4]
52	ldp	x6, x7, [sp, #S_X6]
53	.endif
54#endif
55	.endm
56
57	.macro ct_user_enter
58#ifdef CONFIG_CONTEXT_TRACKING
59	bl	context_tracking_user_enter
60#endif
61	.endm
62
63/*
64 * Bad Abort numbers
65 *-----------------
66 */
67#define BAD_SYNC	0
68#define BAD_IRQ		1
69#define BAD_FIQ		2
70#define BAD_ERROR	3
71
72	.macro kernel_ventry	label
73	.align 7
74	sub	sp, sp, #S_FRAME_SIZE
75#ifdef CONFIG_VMAP_STACK
76	/*
77	 * Test whether the SP has overflowed, without corrupting a GPR.
78	 * Task and IRQ stacks are aligned to (1 << THREAD_SHIFT).
79	 */
80	add	sp, sp, x0			// sp' = sp + x0
81	sub	x0, sp, x0			// x0' = sp' - x0 = (sp + x0) - x0 = sp
82	tbnz	x0, #THREAD_SHIFT, 0f
83	sub	x0, sp, x0			// x0'' = sp' - x0' = (sp + x0) - sp = x0
84	sub	sp, sp, x0			// sp'' = sp' - x0 = (sp + x0) - x0 = sp
85	b	\label
86
870:
88	/*
89	 * Either we've just detected an overflow, or we've taken an exception
90	 * while on the overflow stack. Either way, we won't return to
91	 * userspace, and can clobber EL0 registers to free up GPRs.
92	 */
93
94	/* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */
95	msr	tpidr_el0, x0
96
97	/* Recover the original x0 value and stash it in tpidrro_el0 */
98	sub	x0, sp, x0
99	msr	tpidrro_el0, x0
100
101	/* Switch to the overflow stack */
102	adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0
103
104	/*
105	 * Check whether we were already on the overflow stack. This may happen
106	 * after panic() re-enables interrupts.
107	 */
108	mrs	x0, tpidr_el0			// sp of interrupted context
109	sub	x0, sp, x0			// delta with top of overflow stack
110	tst	x0, #~(OVERFLOW_STACK_SIZE - 1)	// within range?
111	b.ne	__bad_stack			// no? -> bad stack pointer
112
113	/* We were already on the overflow stack. Restore sp/x0 and carry on. */
114	sub	sp, sp, x0
115	mrs	x0, tpidrro_el0
116#endif
117	b	\label
118	.endm
119
120	.macro	kernel_entry, el, regsize = 64
121	.if	\regsize == 32
122	mov	w0, w0				// zero upper 32 bits of x0
123	.endif
124	stp	x0, x1, [sp, #16 * 0]
125	stp	x2, x3, [sp, #16 * 1]
126	stp	x4, x5, [sp, #16 * 2]
127	stp	x6, x7, [sp, #16 * 3]
128	stp	x8, x9, [sp, #16 * 4]
129	stp	x10, x11, [sp, #16 * 5]
130	stp	x12, x13, [sp, #16 * 6]
131	stp	x14, x15, [sp, #16 * 7]
132	stp	x16, x17, [sp, #16 * 8]
133	stp	x18, x19, [sp, #16 * 9]
134	stp	x20, x21, [sp, #16 * 10]
135	stp	x22, x23, [sp, #16 * 11]
136	stp	x24, x25, [sp, #16 * 12]
137	stp	x26, x27, [sp, #16 * 13]
138	stp	x28, x29, [sp, #16 * 14]
139
140	.if	\el == 0
141	mrs	x21, sp_el0
142	ldr_this_cpu	tsk, __entry_task, x20	// Ensure MDSCR_EL1.SS is clear,
143	ldr	x19, [tsk, #TSK_TI_FLAGS]	// since we can unmask debug
144	disable_step_tsk x19, x20		// exceptions when scheduling.
145
146	mov	x29, xzr			// fp pointed to user-space
147	.else
148	add	x21, sp, #S_FRAME_SIZE
149	get_thread_info tsk
150	/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
151	ldr	x20, [tsk, #TSK_TI_ADDR_LIMIT]
152	str	x20, [sp, #S_ORIG_ADDR_LIMIT]
153	mov	x20, #TASK_SIZE_64
154	str	x20, [tsk, #TSK_TI_ADDR_LIMIT]
155	/* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
156	.endif /* \el == 0 */
157	mrs	x22, elr_el1
158	mrs	x23, spsr_el1
159	stp	lr, x21, [sp, #S_LR]
160
161	/*
162	 * In order to be able to dump the contents of struct pt_regs at the
163	 * time the exception was taken (in case we attempt to walk the call
164	 * stack later), chain it together with the stack frames.
165	 */
166	.if \el == 0
167	stp	xzr, xzr, [sp, #S_STACKFRAME]
168	.else
169	stp	x29, x22, [sp, #S_STACKFRAME]
170	.endif
171	add	x29, sp, #S_STACKFRAME
172
173#ifdef CONFIG_ARM64_SW_TTBR0_PAN
174	/*
175	 * Set the TTBR0 PAN bit in SPSR. When the exception is taken from
176	 * EL0, there is no need to check the state of TTBR0_EL1 since
177	 * accesses are always enabled.
178	 * Note that the meaning of this bit differs from the ARMv8.1 PAN
179	 * feature as all TTBR0_EL1 accesses are disabled, not just those to
180	 * user mappings.
181	 */
182alternative_if ARM64_HAS_PAN
183	b	1f				// skip TTBR0 PAN
184alternative_else_nop_endif
185
186	.if	\el != 0
187	mrs	x21, ttbr0_el1
188	tst	x21, #0xffff << 48		// Check for the reserved ASID
189	orr	x23, x23, #PSR_PAN_BIT		// Set the emulated PAN in the saved SPSR
190	b.eq	1f				// TTBR0 access already disabled
191	and	x23, x23, #~PSR_PAN_BIT		// Clear the emulated PAN in the saved SPSR
192	.endif
193
194	__uaccess_ttbr0_disable x21
1951:
196#endif
197
198	stp	x22, x23, [sp, #S_PC]
199
200	/* Not in a syscall by default (el0_svc overwrites for real syscall) */
201	.if	\el == 0
202	mov	w21, #NO_SYSCALL
203	str	w21, [sp, #S_SYSCALLNO]
204	.endif
205
206	/*
207	 * Set sp_el0 to current thread_info.
208	 */
209	.if	\el == 0
210	msr	sp_el0, tsk
211	.endif
212
213	/*
214	 * Registers that may be useful after this macro is invoked:
215	 *
216	 * x21 - aborted SP
217	 * x22 - aborted PC
218	 * x23 - aborted PSTATE
219	*/
220	.endm
221
222	.macro	kernel_exit, el
223	.if	\el != 0
224	disable_daif
225
226	/* Restore the task's original addr_limit. */
227	ldr	x20, [sp, #S_ORIG_ADDR_LIMIT]
228	str	x20, [tsk, #TSK_TI_ADDR_LIMIT]
229
230	/* No need to restore UAO, it will be restored from SPSR_EL1 */
231	.endif
232
233	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
234	.if	\el == 0
235	ct_user_enter
236	.endif
237
238#ifdef CONFIG_ARM64_SW_TTBR0_PAN
239	/*
240	 * Restore access to TTBR0_EL1. If returning to EL0, no need for SPSR
241	 * PAN bit checking.
242	 */
243alternative_if ARM64_HAS_PAN
244	b	2f				// skip TTBR0 PAN
245alternative_else_nop_endif
246
247	.if	\el != 0
248	tbnz	x22, #22, 1f			// Skip re-enabling TTBR0 access if the PSR_PAN_BIT is set
249	.endif
250
251	__uaccess_ttbr0_enable x0
252
253	.if	\el == 0
254	/*
255	 * Enable errata workarounds only if returning to user. The only
256	 * workaround currently required for TTBR0_EL1 changes are for the
257	 * Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache
258	 * corruption).
259	 */
260	post_ttbr0_update_workaround
261	.endif
2621:
263	.if	\el != 0
264	and	x22, x22, #~PSR_PAN_BIT		// ARMv8.0 CPUs do not understand this bit
265	.endif
2662:
267#endif
268
269	.if	\el == 0
270	ldr	x23, [sp, #S_SP]		// load return stack pointer
271	msr	sp_el0, x23
272#ifdef CONFIG_ARM64_ERRATUM_845719
273alternative_if ARM64_WORKAROUND_845719
274	tbz	x22, #4, 1f
275#ifdef CONFIG_PID_IN_CONTEXTIDR
276	mrs	x29, contextidr_el1
277	msr	contextidr_el1, x29
278#else
279	msr contextidr_el1, xzr
280#endif
2811:
282alternative_else_nop_endif
283#endif
284	.endif
285
286	msr	elr_el1, x21			// set up the return data
287	msr	spsr_el1, x22
288	ldp	x0, x1, [sp, #16 * 0]
289	ldp	x2, x3, [sp, #16 * 1]
290	ldp	x4, x5, [sp, #16 * 2]
291	ldp	x6, x7, [sp, #16 * 3]
292	ldp	x8, x9, [sp, #16 * 4]
293	ldp	x10, x11, [sp, #16 * 5]
294	ldp	x12, x13, [sp, #16 * 6]
295	ldp	x14, x15, [sp, #16 * 7]
296	ldp	x16, x17, [sp, #16 * 8]
297	ldp	x18, x19, [sp, #16 * 9]
298	ldp	x20, x21, [sp, #16 * 10]
299	ldp	x22, x23, [sp, #16 * 11]
300	ldp	x24, x25, [sp, #16 * 12]
301	ldp	x26, x27, [sp, #16 * 13]
302	ldp	x28, x29, [sp, #16 * 14]
303	ldr	lr, [sp, #S_LR]
304	add	sp, sp, #S_FRAME_SIZE		// restore sp
305	eret					// return to kernel
306	.endm
307
308	.macro	irq_stack_entry
309	mov	x19, sp			// preserve the original sp
310
311	/*
312	 * Compare sp with the base of the task stack.
313	 * If the top ~(THREAD_SIZE - 1) bits match, we are on a task stack,
314	 * and should switch to the irq stack.
315	 */
316	ldr	x25, [tsk, TSK_STACK]
317	eor	x25, x25, x19
318	and	x25, x25, #~(THREAD_SIZE - 1)
319	cbnz	x25, 9998f
320
321	ldr_this_cpu x25, irq_stack_ptr, x26
322	mov	x26, #IRQ_STACK_SIZE
323	add	x26, x25, x26
324
325	/* switch to the irq stack */
326	mov	sp, x26
3279998:
328	.endm
329
330	/*
331	 * x19 should be preserved between irq_stack_entry and
332	 * irq_stack_exit.
333	 */
334	.macro	irq_stack_exit
335	mov	sp, x19
336	.endm
337
338/*
339 * These are the registers used in the syscall handler, and allow us to
340 * have in theory up to 7 arguments to a function - x0 to x6.
341 *
342 * x7 is reserved for the system call number in 32-bit mode.
343 */
344wsc_nr	.req	w25		// number of system calls
345wscno	.req	w26		// syscall number
346xscno	.req	x26		// syscall number (zero-extended)
347stbl	.req	x27		// syscall table pointer
348tsk	.req	x28		// current thread_info
349
350/*
351 * Interrupt handling.
352 */
353	.macro	irq_handler
354	ldr_l	x1, handle_arch_irq
355	mov	x0, sp
356	irq_stack_entry
357	blr	x1
358	irq_stack_exit
359	.endm
360
361	.text
362
363/*
364 * Exception vectors.
365 */
366	.pushsection ".entry.text", "ax"
367
368	.align	11
369ENTRY(vectors)
370	kernel_ventry	el1_sync_invalid		// Synchronous EL1t
371	kernel_ventry	el1_irq_invalid			// IRQ EL1t
372	kernel_ventry	el1_fiq_invalid			// FIQ EL1t
373	kernel_ventry	el1_error_invalid		// Error EL1t
374
375	kernel_ventry	el1_sync			// Synchronous EL1h
376	kernel_ventry	el1_irq				// IRQ EL1h
377	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
378	kernel_ventry	el1_error			// Error EL1h
379
380	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
381	kernel_ventry	el0_irq				// IRQ 64-bit EL0
382	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
383	kernel_ventry	el0_error			// Error 64-bit EL0
384
385#ifdef CONFIG_COMPAT
386	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
387	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
388	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
389	kernel_ventry	el0_error_compat		// Error 32-bit EL0
390#else
391	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
392	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
393	kernel_ventry	el0_fiq_invalid			// FIQ 32-bit EL0
394	kernel_ventry	el0_error_invalid		// Error 32-bit EL0
395#endif
396END(vectors)
397
398#ifdef CONFIG_VMAP_STACK
399	/*
400	 * We detected an overflow in kernel_ventry, which switched to the
401	 * overflow stack. Stash the exception regs, and head to our overflow
402	 * handler.
403	 */
404__bad_stack:
405	/* Restore the original x0 value */
406	mrs	x0, tpidrro_el0
407
408	/*
409	 * Store the original GPRs to the new stack. The orginal SP (minus
410	 * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry.
411	 */
412	sub	sp, sp, #S_FRAME_SIZE
413	kernel_entry 1
414	mrs	x0, tpidr_el0
415	add	x0, x0, #S_FRAME_SIZE
416	str	x0, [sp, #S_SP]
417
418	/* Stash the regs for handle_bad_stack */
419	mov	x0, sp
420
421	/* Time to die */
422	bl	handle_bad_stack
423	ASM_BUG()
424#endif /* CONFIG_VMAP_STACK */
425
426/*
427 * Invalid mode handlers
428 */
429	.macro	inv_entry, el, reason, regsize = 64
430	kernel_entry \el, \regsize
431	mov	x0, sp
432	mov	x1, #\reason
433	mrs	x2, esr_el1
434	bl	bad_mode
435	ASM_BUG()
436	.endm
437
438el0_sync_invalid:
439	inv_entry 0, BAD_SYNC
440ENDPROC(el0_sync_invalid)
441
442el0_irq_invalid:
443	inv_entry 0, BAD_IRQ
444ENDPROC(el0_irq_invalid)
445
446el0_fiq_invalid:
447	inv_entry 0, BAD_FIQ
448ENDPROC(el0_fiq_invalid)
449
450el0_error_invalid:
451	inv_entry 0, BAD_ERROR
452ENDPROC(el0_error_invalid)
453
454#ifdef CONFIG_COMPAT
455el0_fiq_invalid_compat:
456	inv_entry 0, BAD_FIQ, 32
457ENDPROC(el0_fiq_invalid_compat)
458#endif
459
460el1_sync_invalid:
461	inv_entry 1, BAD_SYNC
462ENDPROC(el1_sync_invalid)
463
464el1_irq_invalid:
465	inv_entry 1, BAD_IRQ
466ENDPROC(el1_irq_invalid)
467
468el1_fiq_invalid:
469	inv_entry 1, BAD_FIQ
470ENDPROC(el1_fiq_invalid)
471
472el1_error_invalid:
473	inv_entry 1, BAD_ERROR
474ENDPROC(el1_error_invalid)
475
476/*
477 * EL1 mode handlers.
478 */
479	.align	6
480el1_sync:
481	kernel_entry 1
482	mrs	x1, esr_el1			// read the syndrome register
483	lsr	x24, x1, #ESR_ELx_EC_SHIFT	// exception class
484	cmp	x24, #ESR_ELx_EC_DABT_CUR	// data abort in EL1
485	b.eq	el1_da
486	cmp	x24, #ESR_ELx_EC_IABT_CUR	// instruction abort in EL1
487	b.eq	el1_ia
488	cmp	x24, #ESR_ELx_EC_SYS64		// configurable trap
489	b.eq	el1_undef
490	cmp	x24, #ESR_ELx_EC_SP_ALIGN	// stack alignment exception
491	b.eq	el1_sp_pc
492	cmp	x24, #ESR_ELx_EC_PC_ALIGN	// pc alignment exception
493	b.eq	el1_sp_pc
494	cmp	x24, #ESR_ELx_EC_UNKNOWN	// unknown exception in EL1
495	b.eq	el1_undef
496	cmp	x24, #ESR_ELx_EC_BREAKPT_CUR	// debug exception in EL1
497	b.ge	el1_dbg
498	b	el1_inv
499
500el1_ia:
501	/*
502	 * Fall through to the Data abort case
503	 */
504el1_da:
505	/*
506	 * Data abort handling
507	 */
508	mrs	x3, far_el1
509	inherit_daif	pstate=x23, tmp=x2
510	clear_address_tag x0, x3
511	mov	x2, sp				// struct pt_regs
512	bl	do_mem_abort
513
514	kernel_exit 1
515el1_sp_pc:
516	/*
517	 * Stack or PC alignment exception handling
518	 */
519	mrs	x0, far_el1
520	inherit_daif	pstate=x23, tmp=x2
521	mov	x2, sp
522	bl	do_sp_pc_abort
523	ASM_BUG()
524el1_undef:
525	/*
526	 * Undefined instruction
527	 */
528	inherit_daif	pstate=x23, tmp=x2
529	mov	x0, sp
530	bl	do_undefinstr
531	ASM_BUG()
532el1_dbg:
533	/*
534	 * Debug exception handling
535	 */
536	cmp	x24, #ESR_ELx_EC_BRK64		// if BRK64
537	cinc	x24, x24, eq			// set bit '0'
538	tbz	x24, #0, el1_inv		// EL1 only
539	mrs	x0, far_el1
540	mov	x2, sp				// struct pt_regs
541	bl	do_debug_exception
542	kernel_exit 1
543el1_inv:
544	// TODO: add support for undefined instructions in kernel mode
545	inherit_daif	pstate=x23, tmp=x2
546	mov	x0, sp
547	mov	x2, x1
548	mov	x1, #BAD_SYNC
549	bl	bad_mode
550	ASM_BUG()
551ENDPROC(el1_sync)
552
553	.align	6
554el1_irq:
555	kernel_entry 1
556	enable_da_f
557#ifdef CONFIG_TRACE_IRQFLAGS
558	bl	trace_hardirqs_off
559#endif
560
561	irq_handler
562
563#ifdef CONFIG_PREEMPT
564	ldr	w24, [tsk, #TSK_TI_PREEMPT]	// get preempt count
565	cbnz	w24, 1f				// preempt count != 0
566	ldr	x0, [tsk, #TSK_TI_FLAGS]	// get flags
567	tbz	x0, #TIF_NEED_RESCHED, 1f	// needs rescheduling?
568	bl	el1_preempt
5691:
570#endif
571#ifdef CONFIG_TRACE_IRQFLAGS
572	bl	trace_hardirqs_on
573#endif
574	kernel_exit 1
575ENDPROC(el1_irq)
576
577#ifdef CONFIG_PREEMPT
578el1_preempt:
579	mov	x24, lr
5801:	bl	preempt_schedule_irq		// irq en/disable is done inside
581	ldr	x0, [tsk, #TSK_TI_FLAGS]	// get new tasks TI_FLAGS
582	tbnz	x0, #TIF_NEED_RESCHED, 1b	// needs rescheduling?
583	ret	x24
584#endif
585
586/*
587 * EL0 mode handlers.
588 */
589	.align	6
590el0_sync:
591	kernel_entry 0
592	mrs	x25, esr_el1			// read the syndrome register
593	lsr	x24, x25, #ESR_ELx_EC_SHIFT	// exception class
594	cmp	x24, #ESR_ELx_EC_SVC64		// SVC in 64-bit state
595	b.eq	el0_svc
596	cmp	x24, #ESR_ELx_EC_DABT_LOW	// data abort in EL0
597	b.eq	el0_da
598	cmp	x24, #ESR_ELx_EC_IABT_LOW	// instruction abort in EL0
599	b.eq	el0_ia
600	cmp	x24, #ESR_ELx_EC_FP_ASIMD	// FP/ASIMD access
601	b.eq	el0_fpsimd_acc
602	cmp	x24, #ESR_ELx_EC_SVE		// SVE access
603	b.eq	el0_sve_acc
604	cmp	x24, #ESR_ELx_EC_FP_EXC64	// FP/ASIMD exception
605	b.eq	el0_fpsimd_exc
606	cmp	x24, #ESR_ELx_EC_SYS64		// configurable trap
607	b.eq	el0_sys
608	cmp	x24, #ESR_ELx_EC_SP_ALIGN	// stack alignment exception
609	b.eq	el0_sp_pc
610	cmp	x24, #ESR_ELx_EC_PC_ALIGN	// pc alignment exception
611	b.eq	el0_sp_pc
612	cmp	x24, #ESR_ELx_EC_UNKNOWN	// unknown exception in EL0
613	b.eq	el0_undef
614	cmp	x24, #ESR_ELx_EC_BREAKPT_LOW	// debug exception in EL0
615	b.ge	el0_dbg
616	b	el0_inv
617
618#ifdef CONFIG_COMPAT
619	.align	6
620el0_sync_compat:
621	kernel_entry 0, 32
622	mrs	x25, esr_el1			// read the syndrome register
623	lsr	x24, x25, #ESR_ELx_EC_SHIFT	// exception class
624	cmp	x24, #ESR_ELx_EC_SVC32		// SVC in 32-bit state
625	b.eq	el0_svc_compat
626	cmp	x24, #ESR_ELx_EC_DABT_LOW	// data abort in EL0
627	b.eq	el0_da
628	cmp	x24, #ESR_ELx_EC_IABT_LOW	// instruction abort in EL0
629	b.eq	el0_ia
630	cmp	x24, #ESR_ELx_EC_FP_ASIMD	// FP/ASIMD access
631	b.eq	el0_fpsimd_acc
632	cmp	x24, #ESR_ELx_EC_FP_EXC32	// FP/ASIMD exception
633	b.eq	el0_fpsimd_exc
634	cmp	x24, #ESR_ELx_EC_PC_ALIGN	// pc alignment exception
635	b.eq	el0_sp_pc
636	cmp	x24, #ESR_ELx_EC_UNKNOWN	// unknown exception in EL0
637	b.eq	el0_undef
638	cmp	x24, #ESR_ELx_EC_CP15_32	// CP15 MRC/MCR trap
639	b.eq	el0_undef
640	cmp	x24, #ESR_ELx_EC_CP15_64	// CP15 MRRC/MCRR trap
641	b.eq	el0_undef
642	cmp	x24, #ESR_ELx_EC_CP14_MR	// CP14 MRC/MCR trap
643	b.eq	el0_undef
644	cmp	x24, #ESR_ELx_EC_CP14_LS	// CP14 LDC/STC trap
645	b.eq	el0_undef
646	cmp	x24, #ESR_ELx_EC_CP14_64	// CP14 MRRC/MCRR trap
647	b.eq	el0_undef
648	cmp	x24, #ESR_ELx_EC_BREAKPT_LOW	// debug exception in EL0
649	b.ge	el0_dbg
650	b	el0_inv
651el0_svc_compat:
652	/*
653	 * AArch32 syscall handling
654	 */
655	ldr	x16, [tsk, #TSK_TI_FLAGS]	// load thread flags
656	adrp	stbl, compat_sys_call_table	// load compat syscall table pointer
657	mov	wscno, w7			// syscall number in w7 (r7)
658	mov     wsc_nr, #__NR_compat_syscalls
659	b	el0_svc_naked
660
661	.align	6
662el0_irq_compat:
663	kernel_entry 0, 32
664	b	el0_irq_naked
665
666el0_error_compat:
667	kernel_entry 0, 32
668	b	el0_error_naked
669#endif
670
671el0_da:
672	/*
673	 * Data abort handling
674	 */
675	mrs	x26, far_el1
676	enable_daif
677	ct_user_exit
678	clear_address_tag x0, x26
679	mov	x1, x25
680	mov	x2, sp
681	bl	do_mem_abort
682	b	ret_to_user
683el0_ia:
684	/*
685	 * Instruction abort handling
686	 */
687	mrs	x26, far_el1
688	enable_daif
689	ct_user_exit
690	mov	x0, x26
691	mov	x1, x25
692	mov	x2, sp
693	bl	do_mem_abort
694	b	ret_to_user
695el0_fpsimd_acc:
696	/*
697	 * Floating Point or Advanced SIMD access
698	 */
699	enable_daif
700	ct_user_exit
701	mov	x0, x25
702	mov	x1, sp
703	bl	do_fpsimd_acc
704	b	ret_to_user
705el0_sve_acc:
706	/*
707	 * Scalable Vector Extension access
708	 */
709	enable_daif
710	ct_user_exit
711	mov	x0, x25
712	mov	x1, sp
713	bl	do_sve_acc
714	b	ret_to_user
715el0_fpsimd_exc:
716	/*
717	 * Floating Point, Advanced SIMD or SVE exception
718	 */
719	enable_daif
720	ct_user_exit
721	mov	x0, x25
722	mov	x1, sp
723	bl	do_fpsimd_exc
724	b	ret_to_user
725el0_sp_pc:
726	/*
727	 * Stack or PC alignment exception handling
728	 */
729	mrs	x26, far_el1
730	enable_daif
731	ct_user_exit
732	mov	x0, x26
733	mov	x1, x25
734	mov	x2, sp
735	bl	do_sp_pc_abort
736	b	ret_to_user
737el0_undef:
738	/*
739	 * Undefined instruction
740	 */
741	enable_daif
742	ct_user_exit
743	mov	x0, sp
744	bl	do_undefinstr
745	b	ret_to_user
746el0_sys:
747	/*
748	 * System instructions, for trapped cache maintenance instructions
749	 */
750	enable_daif
751	ct_user_exit
752	mov	x0, x25
753	mov	x1, sp
754	bl	do_sysinstr
755	b	ret_to_user
756el0_dbg:
757	/*
758	 * Debug exception handling
759	 */
760	tbnz	x24, #0, el0_inv		// EL0 only
761	mrs	x0, far_el1
762	mov	x1, x25
763	mov	x2, sp
764	bl	do_debug_exception
765	enable_daif
766	ct_user_exit
767	b	ret_to_user
768el0_inv:
769	enable_daif
770	ct_user_exit
771	mov	x0, sp
772	mov	x1, #BAD_SYNC
773	mov	x2, x25
774	bl	bad_el0_sync
775	b	ret_to_user
776ENDPROC(el0_sync)
777
778	.align	6
779el0_irq:
780	kernel_entry 0
781el0_irq_naked:
782	enable_da_f
783#ifdef CONFIG_TRACE_IRQFLAGS
784	bl	trace_hardirqs_off
785#endif
786
787	ct_user_exit
788	irq_handler
789
790#ifdef CONFIG_TRACE_IRQFLAGS
791	bl	trace_hardirqs_on
792#endif
793	b	ret_to_user
794ENDPROC(el0_irq)
795
796el1_error:
797	kernel_entry 1
798	mrs	x1, esr_el1
799	enable_dbg
800	mov	x0, sp
801	bl	do_serror
802	kernel_exit 1
803ENDPROC(el1_error)
804
805el0_error:
806	kernel_entry 0
807el0_error_naked:
808	mrs	x1, esr_el1
809	enable_dbg
810	mov	x0, sp
811	bl	do_serror
812	enable_daif
813	ct_user_exit
814	b	ret_to_user
815ENDPROC(el0_error)
816
817
818/*
819 * This is the fast syscall return path.  We do as little as possible here,
820 * and this includes saving x0 back into the kernel stack.
821 */
822ret_fast_syscall:
823	disable_daif
824	str	x0, [sp, #S_X0]			// returned x0
825	ldr	x1, [tsk, #TSK_TI_FLAGS]	// re-check for syscall tracing
826	and	x2, x1, #_TIF_SYSCALL_WORK
827	cbnz	x2, ret_fast_syscall_trace
828	and	x2, x1, #_TIF_WORK_MASK
829	cbnz	x2, work_pending
830	enable_step_tsk x1, x2
831	kernel_exit 0
832ret_fast_syscall_trace:
833	enable_daif
834	b	__sys_trace_return_skipped	// we already saved x0
835
836/*
837 * Ok, we need to do extra processing, enter the slow path.
838 */
839work_pending:
840	mov	x0, sp				// 'regs'
841	bl	do_notify_resume
842#ifdef CONFIG_TRACE_IRQFLAGS
843	bl	trace_hardirqs_on		// enabled while in userspace
844#endif
845	ldr	x1, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
846	b	finish_ret_to_user
847/*
848 * "slow" syscall return path.
849 */
850ret_to_user:
851	disable_daif
852	ldr	x1, [tsk, #TSK_TI_FLAGS]
853	and	x2, x1, #_TIF_WORK_MASK
854	cbnz	x2, work_pending
855finish_ret_to_user:
856	enable_step_tsk x1, x2
857	kernel_exit 0
858ENDPROC(ret_to_user)
859
860/*
861 * SVC handler.
862 */
863	.align	6
864el0_svc:
865	ldr	x16, [tsk, #TSK_TI_FLAGS]	// load thread flags
866	adrp	stbl, sys_call_table		// load syscall table pointer
867	mov	wscno, w8			// syscall number in w8
868	mov	wsc_nr, #__NR_syscalls
869
870#ifdef CONFIG_ARM64_SVE
871alternative_if_not ARM64_SVE
872	b	el0_svc_naked
873alternative_else_nop_endif
874	tbz	x16, #TIF_SVE, el0_svc_naked	// Skip unless TIF_SVE set:
875	bic	x16, x16, #_TIF_SVE		// discard SVE state
876	str	x16, [tsk, #TSK_TI_FLAGS]
877
878	/*
879	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
880	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
881	 * happens if a context switch or kernel_neon_begin() or context
882	 * modification (sigreturn, ptrace) intervenes.
883	 * So, ensure that CPACR_EL1 is already correct for the fast-path case:
884	 */
885	mrs	x9, cpacr_el1
886	bic	x9, x9, #CPACR_EL1_ZEN_EL0EN	// disable SVE for el0
887	msr	cpacr_el1, x9			// synchronised by eret to el0
888#endif
889
890el0_svc_naked:					// compat entry point
891	stp	x0, xscno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
892	enable_daif
893	ct_user_exit 1
894
895	tst	x16, #_TIF_SYSCALL_WORK		// check for syscall hooks
896	b.ne	__sys_trace
897	cmp     wscno, wsc_nr			// check upper syscall limit
898	b.hs	ni_sys
899	ldr	x16, [stbl, xscno, lsl #3]	// address in the syscall table
900	blr	x16				// call sys_* routine
901	b	ret_fast_syscall
902ni_sys:
903	mov	x0, sp
904	bl	do_ni_syscall
905	b	ret_fast_syscall
906ENDPROC(el0_svc)
907
908	/*
909	 * This is the really slow path.  We're going to be doing context
910	 * switches, and waiting for our parent to respond.
911	 */
912__sys_trace:
913	cmp     wscno, #NO_SYSCALL		// user-issued syscall(-1)?
914	b.ne	1f
915	mov	x0, #-ENOSYS			// set default errno if so
916	str	x0, [sp, #S_X0]
9171:	mov	x0, sp
918	bl	syscall_trace_enter
919	cmp	w0, #NO_SYSCALL			// skip the syscall?
920	b.eq	__sys_trace_return_skipped
921	mov	wscno, w0			// syscall number (possibly new)
922	mov	x1, sp				// pointer to regs
923	cmp	wscno, wsc_nr			// check upper syscall limit
924	b.hs	__ni_sys_trace
925	ldp	x0, x1, [sp]			// restore the syscall args
926	ldp	x2, x3, [sp, #S_X2]
927	ldp	x4, x5, [sp, #S_X4]
928	ldp	x6, x7, [sp, #S_X6]
929	ldr	x16, [stbl, xscno, lsl #3]	// address in the syscall table
930	blr	x16				// call sys_* routine
931
932__sys_trace_return:
933	str	x0, [sp, #S_X0]			// save returned x0
934__sys_trace_return_skipped:
935	mov	x0, sp
936	bl	syscall_trace_exit
937	b	ret_to_user
938
939__ni_sys_trace:
940	mov	x0, sp
941	bl	do_ni_syscall
942	b	__sys_trace_return
943
944	.popsection				// .entry.text
945
946/*
947 * Special system call wrappers.
948 */
949ENTRY(sys_rt_sigreturn_wrapper)
950	mov	x0, sp
951	b	sys_rt_sigreturn
952ENDPROC(sys_rt_sigreturn_wrapper)
953
954/*
955 * Register switch for AArch64. The callee-saved registers need to be saved
956 * and restored. On entry:
957 *   x0 = previous task_struct (must be preserved across the switch)
958 *   x1 = next task_struct
959 * Previous and next are guaranteed not to be the same.
960 *
961 */
962ENTRY(cpu_switch_to)
963	mov	x10, #THREAD_CPU_CONTEXT
964	add	x8, x0, x10
965	mov	x9, sp
966	stp	x19, x20, [x8], #16		// store callee-saved registers
967	stp	x21, x22, [x8], #16
968	stp	x23, x24, [x8], #16
969	stp	x25, x26, [x8], #16
970	stp	x27, x28, [x8], #16
971	stp	x29, x9, [x8], #16
972	str	lr, [x8]
973	add	x8, x1, x10
974	ldp	x19, x20, [x8], #16		// restore callee-saved registers
975	ldp	x21, x22, [x8], #16
976	ldp	x23, x24, [x8], #16
977	ldp	x25, x26, [x8], #16
978	ldp	x27, x28, [x8], #16
979	ldp	x29, x9, [x8], #16
980	ldr	lr, [x8]
981	mov	sp, x9
982	msr	sp_el0, x1
983	ret
984ENDPROC(cpu_switch_to)
985NOKPROBE(cpu_switch_to)
986
987/*
988 * This is how we return from a fork.
989 */
990ENTRY(ret_from_fork)
991	bl	schedule_tail
992	cbz	x19, 1f				// not a kernel thread
993	mov	x0, x20
994	blr	x19
9951:	get_thread_info tsk
996	b	ret_to_user
997ENDPROC(ret_from_fork)
998NOKPROBE(ret_from_fork)
999