GNU Linux-libre 5.4.274-gnu1
[releases.git] / 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/cpufeature.h>
18 #include <asm/errno.h>
19 #include <asm/esr.h>
20 #include <asm/irq.h>
21 #include <asm/memory.h>
22 #include <asm/mmu.h>
23 #include <asm/processor.h>
24 #include <asm/ptrace.h>
25 #include <asm/thread_info.h>
26 #include <asm/asm-uaccess.h>
27 #include <asm/unistd.h>
28
29 /*
30  * Context tracking subsystem.  Used to instrument transitions
31  * between user and kernel mode.
32  */
33         .macro ct_user_exit_irqoff
34 #ifdef CONFIG_CONTEXT_TRACKING
35         bl      enter_from_user_mode
36 #endif
37         .endm
38
39         .macro ct_user_enter
40 #ifdef CONFIG_CONTEXT_TRACKING
41         bl      context_tracking_user_enter
42 #endif
43         .endm
44
45         .macro  clear_gp_regs
46         .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
47         mov     x\n, xzr
48         .endr
49         .endm
50
51 /*
52  * Bad Abort numbers
53  *-----------------
54  */
55 #define BAD_SYNC        0
56 #define BAD_IRQ         1
57 #define BAD_FIQ         2
58 #define BAD_ERROR       3
59
60         .macro kernel_ventry, el, label, regsize = 64
61         .align 7
62 .Lventry_start\@:
63         .if     \el == 0
64         /*
65          * This must be the first instruction of the EL0 vector entries. It is
66          * skipped by the trampoline vectors, to trigger the cleanup.
67          */
68         b       .Lskip_tramp_vectors_cleanup\@
69         .if     \regsize == 64
70         mrs     x30, tpidrro_el0
71         msr     tpidrro_el0, xzr
72         .else
73         mov     x30, xzr
74         .endif
75 .Lskip_tramp_vectors_cleanup\@:
76         .endif
77
78         sub     sp, sp, #S_FRAME_SIZE
79 #ifdef CONFIG_VMAP_STACK
80         /*
81          * Test whether the SP has overflowed, without corrupting a GPR.
82          * Task and IRQ stacks are aligned to (1 << THREAD_SHIFT).
83          */
84         add     sp, sp, x0                      // sp' = sp + x0
85         sub     x0, sp, x0                      // x0' = sp' - x0 = (sp + x0) - x0 = sp
86         tbnz    x0, #THREAD_SHIFT, 0f
87         sub     x0, sp, x0                      // x0'' = sp' - x0' = (sp + x0) - sp = x0
88         sub     sp, sp, x0                      // sp'' = sp' - x0 = (sp + x0) - x0 = sp
89         b       el\()\el\()_\label
90
91 0:
92         /*
93          * Either we've just detected an overflow, or we've taken an exception
94          * while on the overflow stack. Either way, we won't return to
95          * userspace, and can clobber EL0 registers to free up GPRs.
96          */
97
98         /* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */
99         msr     tpidr_el0, x0
100
101         /* Recover the original x0 value and stash it in tpidrro_el0 */
102         sub     x0, sp, x0
103         msr     tpidrro_el0, x0
104
105         /* Switch to the overflow stack */
106         adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0
107
108         /*
109          * Check whether we were already on the overflow stack. This may happen
110          * after panic() re-enables interrupts.
111          */
112         mrs     x0, tpidr_el0                   // sp of interrupted context
113         sub     x0, sp, x0                      // delta with top of overflow stack
114         tst     x0, #~(OVERFLOW_STACK_SIZE - 1) // within range?
115         b.ne    __bad_stack                     // no? -> bad stack pointer
116
117         /* We were already on the overflow stack. Restore sp/x0 and carry on. */
118         sub     sp, sp, x0
119         mrs     x0, tpidrro_el0
120 #endif
121         b       el\()\el\()_\label
122 .org .Lventry_start\@ + 128     // Did we overflow the ventry slot?
123         .endm
124
125         .macro tramp_alias, dst, sym, tmp
126         mov_q   \dst, TRAMP_VALIAS
127         adr_l   \tmp, \sym
128         add     \dst, \dst, \tmp
129         adr_l   \tmp, .entry.tramp.text
130         sub     \dst, \dst, \tmp
131         .endm
132
133         // This macro corrupts x0-x3. It is the caller's duty
134         // to save/restore them if required.
135         .macro  apply_ssbd, state, tmp1, tmp2
136 #ifdef CONFIG_ARM64_SSBD
137 alternative_cb  arm64_enable_wa2_handling
138         b       .L__asm_ssbd_skip\@
139 alternative_cb_end
140         ldr_this_cpu    \tmp2, arm64_ssbd_callback_required, \tmp1
141         cbz     \tmp2,  .L__asm_ssbd_skip\@
142         ldr     \tmp2, [tsk, #TSK_TI_FLAGS]
143         tbnz    \tmp2, #TIF_SSBD, .L__asm_ssbd_skip\@
144         mov     w0, #ARM_SMCCC_ARCH_WORKAROUND_2
145         mov     w1, #\state
146 alternative_cb  arm64_update_smccc_conduit
147         nop                                     // Patched to SMC/HVC #0
148 alternative_cb_end
149 .L__asm_ssbd_skip\@:
150 #endif
151         .endm
152
153         .macro  kernel_entry, el, regsize = 64
154         .if     \regsize == 32
155         mov     w0, w0                          // zero upper 32 bits of x0
156         .endif
157         stp     x0, x1, [sp, #16 * 0]
158         stp     x2, x3, [sp, #16 * 1]
159         stp     x4, x5, [sp, #16 * 2]
160         stp     x6, x7, [sp, #16 * 3]
161         stp     x8, x9, [sp, #16 * 4]
162         stp     x10, x11, [sp, #16 * 5]
163         stp     x12, x13, [sp, #16 * 6]
164         stp     x14, x15, [sp, #16 * 7]
165         stp     x16, x17, [sp, #16 * 8]
166         stp     x18, x19, [sp, #16 * 9]
167         stp     x20, x21, [sp, #16 * 10]
168         stp     x22, x23, [sp, #16 * 11]
169         stp     x24, x25, [sp, #16 * 12]
170         stp     x26, x27, [sp, #16 * 13]
171         stp     x28, x29, [sp, #16 * 14]
172
173         .if     \el == 0
174         clear_gp_regs
175         mrs     x21, sp_el0
176         ldr_this_cpu    tsk, __entry_task, x20  // Ensure MDSCR_EL1.SS is clear,
177         ldr     x19, [tsk, #TSK_TI_FLAGS]       // since we can unmask debug
178         disable_step_tsk x19, x20               // exceptions when scheduling.
179
180         apply_ssbd 1, x22, x23
181
182         .else
183         add     x21, sp, #S_FRAME_SIZE
184         get_current_task tsk
185         /* Save the task's original addr_limit and set USER_DS */
186         ldr     x20, [tsk, #TSK_TI_ADDR_LIMIT]
187         str     x20, [sp, #S_ORIG_ADDR_LIMIT]
188         mov     x20, #USER_DS
189         str     x20, [tsk, #TSK_TI_ADDR_LIMIT]
190         /* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
191         .endif /* \el == 0 */
192         mrs     x22, elr_el1
193         mrs     x23, spsr_el1
194         stp     lr, x21, [sp, #S_LR]
195
196         /*
197          * In order to be able to dump the contents of struct pt_regs at the
198          * time the exception was taken (in case we attempt to walk the call
199          * stack later), chain it together with the stack frames.
200          */
201         .if \el == 0
202         stp     xzr, xzr, [sp, #S_STACKFRAME]
203         .else
204         stp     x29, x22, [sp, #S_STACKFRAME]
205         .endif
206         add     x29, sp, #S_STACKFRAME
207
208 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
209         /*
210          * Set the TTBR0 PAN bit in SPSR. When the exception is taken from
211          * EL0, there is no need to check the state of TTBR0_EL1 since
212          * accesses are always enabled.
213          * Note that the meaning of this bit differs from the ARMv8.1 PAN
214          * feature as all TTBR0_EL1 accesses are disabled, not just those to
215          * user mappings.
216          */
217 alternative_if ARM64_HAS_PAN
218         b       1f                              // skip TTBR0 PAN
219 alternative_else_nop_endif
220
221         .if     \el != 0
222         mrs     x21, ttbr0_el1
223         tst     x21, #TTBR_ASID_MASK            // Check for the reserved ASID
224         orr     x23, x23, #PSR_PAN_BIT          // Set the emulated PAN in the saved SPSR
225         b.eq    1f                              // TTBR0 access already disabled
226         and     x23, x23, #~PSR_PAN_BIT         // Clear the emulated PAN in the saved SPSR
227         .endif
228
229         __uaccess_ttbr0_disable x21
230 1:
231 #endif
232
233         stp     x22, x23, [sp, #S_PC]
234
235         /* Not in a syscall by default (el0_svc overwrites for real syscall) */
236         .if     \el == 0
237         mov     w21, #NO_SYSCALL
238         str     w21, [sp, #S_SYSCALLNO]
239         .endif
240
241         /*
242          * Set sp_el0 to current thread_info.
243          */
244         .if     \el == 0
245         msr     sp_el0, tsk
246         .endif
247
248         /* Save pmr */
249 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
250         mrs_s   x20, SYS_ICC_PMR_EL1
251         str     x20, [sp, #S_PMR_SAVE]
252 alternative_else_nop_endif
253
254         /*
255          * Registers that may be useful after this macro is invoked:
256          *
257          * x20 - ICC_PMR_EL1
258          * x21 - aborted SP
259          * x22 - aborted PC
260          * x23 - aborted PSTATE
261         */
262         .endm
263
264         .macro  kernel_exit, el
265         .if     \el != 0
266         disable_daif
267
268         /* Restore the task's original addr_limit. */
269         ldr     x20, [sp, #S_ORIG_ADDR_LIMIT]
270         str     x20, [tsk, #TSK_TI_ADDR_LIMIT]
271
272         /* No need to restore UAO, it will be restored from SPSR_EL1 */
273         .endif
274
275         /* Restore pmr */
276 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
277         ldr     x20, [sp, #S_PMR_SAVE]
278         msr_s   SYS_ICC_PMR_EL1, x20
279         /* Ensure priority change is seen by redistributor */
280         dsb     sy
281 alternative_else_nop_endif
282
283         ldp     x21, x22, [sp, #S_PC]           // load ELR, SPSR
284         .if     \el == 0
285         ct_user_enter
286         .endif
287
288 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
289         /*
290          * Restore access to TTBR0_EL1. If returning to EL0, no need for SPSR
291          * PAN bit checking.
292          */
293 alternative_if ARM64_HAS_PAN
294         b       2f                              // skip TTBR0 PAN
295 alternative_else_nop_endif
296
297         .if     \el != 0
298         tbnz    x22, #22, 1f                    // Skip re-enabling TTBR0 access if the PSR_PAN_BIT is set
299         .endif
300
301         __uaccess_ttbr0_enable x0, x1
302
303         .if     \el == 0
304         /*
305          * Enable errata workarounds only if returning to user. The only
306          * workaround currently required for TTBR0_EL1 changes are for the
307          * Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache
308          * corruption).
309          */
310         bl      post_ttbr_update_workaround
311         .endif
312 1:
313         .if     \el != 0
314         and     x22, x22, #~PSR_PAN_BIT         // ARMv8.0 CPUs do not understand this bit
315         .endif
316 2:
317 #endif
318
319         .if     \el == 0
320         ldr     x23, [sp, #S_SP]                // load return stack pointer
321         msr     sp_el0, x23
322         tst     x22, #PSR_MODE32_BIT            // native task?
323         b.eq    3f
324
325 #ifdef CONFIG_ARM64_ERRATUM_845719
326 alternative_if ARM64_WORKAROUND_845719
327 #ifdef CONFIG_PID_IN_CONTEXTIDR
328         mrs     x29, contextidr_el1
329         msr     contextidr_el1, x29
330 #else
331         msr contextidr_el1, xzr
332 #endif
333 alternative_else_nop_endif
334 #endif
335 3:
336 #ifdef CONFIG_ARM64_ERRATUM_1418040
337 alternative_if_not ARM64_WORKAROUND_1418040
338         b       4f
339 alternative_else_nop_endif
340         /*
341          * if (x22.mode32 == cntkctl_el1.el0vcten)
342          *     cntkctl_el1.el0vcten = ~cntkctl_el1.el0vcten
343          */
344         mrs     x1, cntkctl_el1
345         eon     x0, x1, x22, lsr #3
346         tbz     x0, #1, 4f
347         eor     x1, x1, #2      // ARCH_TIMER_USR_VCT_ACCESS_EN
348         msr     cntkctl_el1, x1
349 4:
350 #endif
351         apply_ssbd 0, x0, x1
352         .endif
353
354         msr     elr_el1, x21                    // set up the return data
355         msr     spsr_el1, x22
356         ldp     x0, x1, [sp, #16 * 0]
357         ldp     x2, x3, [sp, #16 * 1]
358         ldp     x4, x5, [sp, #16 * 2]
359         ldp     x6, x7, [sp, #16 * 3]
360         ldp     x8, x9, [sp, #16 * 4]
361         ldp     x10, x11, [sp, #16 * 5]
362         ldp     x12, x13, [sp, #16 * 6]
363         ldp     x14, x15, [sp, #16 * 7]
364         ldp     x16, x17, [sp, #16 * 8]
365         ldp     x18, x19, [sp, #16 * 9]
366         ldp     x20, x21, [sp, #16 * 10]
367         ldp     x22, x23, [sp, #16 * 11]
368         ldp     x24, x25, [sp, #16 * 12]
369         ldp     x26, x27, [sp, #16 * 13]
370         ldp     x28, x29, [sp, #16 * 14]
371
372         .if     \el == 0
373 alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
374         ldr     lr, [sp, #S_LR]
375         add     sp, sp, #S_FRAME_SIZE           // restore sp
376         eret
377 alternative_else_nop_endif
378 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
379         bne     5f
380         msr     far_el1, x29
381         tramp_alias     x30, tramp_exit_native, x29
382         br      x30
383 5:
384         tramp_alias     x30, tramp_exit_compat, x29
385         br      x30
386 #endif
387         .else
388         ldr     lr, [sp, #S_LR]
389         add     sp, sp, #S_FRAME_SIZE           // restore sp
390         eret
391         .endif
392         sb
393         .endm
394
395         .macro  irq_stack_entry
396         mov     x19, sp                 // preserve the original sp
397
398         /*
399          * Compare sp with the base of the task stack.
400          * If the top ~(THREAD_SIZE - 1) bits match, we are on a task stack,
401          * and should switch to the irq stack.
402          */
403         ldr     x25, [tsk, TSK_STACK]
404         eor     x25, x25, x19
405         and     x25, x25, #~(THREAD_SIZE - 1)
406         cbnz    x25, 9998f
407
408         ldr_this_cpu x25, irq_stack_ptr, x26
409         mov     x26, #IRQ_STACK_SIZE
410         add     x26, x25, x26
411
412         /* switch to the irq stack */
413         mov     sp, x26
414 9998:
415         .endm
416
417         /*
418          * x19 should be preserved between irq_stack_entry and
419          * irq_stack_exit.
420          */
421         .macro  irq_stack_exit
422         mov     sp, x19
423         .endm
424
425 /* GPRs used by entry code */
426 tsk     .req    x28             // current thread_info
427
428 /*
429  * Interrupt handling.
430  */
431         .macro  irq_handler
432         ldr_l   x1, handle_arch_irq
433         mov     x0, sp
434         irq_stack_entry
435         blr     x1
436         irq_stack_exit
437         .endm
438
439 #ifdef CONFIG_ARM64_PSEUDO_NMI
440         /*
441          * Set res to 0 if irqs were unmasked in interrupted context.
442          * Otherwise set res to non-0 value.
443          */
444         .macro  test_irqs_unmasked res:req, pmr:req
445 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
446         sub     \res, \pmr, #GIC_PRIO_IRQON
447 alternative_else
448         mov     \res, xzr
449 alternative_endif
450         .endm
451 #endif
452
453         .macro  gic_prio_kentry_setup, tmp:req
454 #ifdef CONFIG_ARM64_PSEUDO_NMI
455         alternative_if ARM64_HAS_IRQ_PRIO_MASKING
456         mov     \tmp, #(GIC_PRIO_PSR_I_SET | GIC_PRIO_IRQON)
457         msr_s   SYS_ICC_PMR_EL1, \tmp
458         alternative_else_nop_endif
459 #endif
460         .endm
461
462         .macro  gic_prio_irq_setup, pmr:req, tmp:req
463 #ifdef CONFIG_ARM64_PSEUDO_NMI
464         alternative_if ARM64_HAS_IRQ_PRIO_MASKING
465         orr     \tmp, \pmr, #GIC_PRIO_PSR_I_SET
466         msr_s   SYS_ICC_PMR_EL1, \tmp
467         alternative_else_nop_endif
468 #endif
469         .endm
470
471         .text
472
473 /*
474  * Exception vectors.
475  */
476         .pushsection ".entry.text", "ax"
477
478         .align  11
479 ENTRY(vectors)
480         kernel_ventry   1, sync_invalid                 // Synchronous EL1t
481         kernel_ventry   1, irq_invalid                  // IRQ EL1t
482         kernel_ventry   1, fiq_invalid                  // FIQ EL1t
483         kernel_ventry   1, error_invalid                // Error EL1t
484
485         kernel_ventry   1, sync                         // Synchronous EL1h
486         kernel_ventry   1, irq                          // IRQ EL1h
487         kernel_ventry   1, fiq_invalid                  // FIQ EL1h
488         kernel_ventry   1, error                        // Error EL1h
489
490         kernel_ventry   0, sync                         // Synchronous 64-bit EL0
491         kernel_ventry   0, irq                          // IRQ 64-bit EL0
492         kernel_ventry   0, fiq_invalid                  // FIQ 64-bit EL0
493         kernel_ventry   0, error                        // Error 64-bit EL0
494
495 #ifdef CONFIG_COMPAT
496         kernel_ventry   0, sync_compat, 32              // Synchronous 32-bit EL0
497         kernel_ventry   0, irq_compat, 32               // IRQ 32-bit EL0
498         kernel_ventry   0, fiq_invalid_compat, 32       // FIQ 32-bit EL0
499         kernel_ventry   0, error_compat, 32             // Error 32-bit EL0
500 #else
501         kernel_ventry   0, sync_invalid, 32             // Synchronous 32-bit EL0
502         kernel_ventry   0, irq_invalid, 32              // IRQ 32-bit EL0
503         kernel_ventry   0, fiq_invalid, 32              // FIQ 32-bit EL0
504         kernel_ventry   0, error_invalid, 32            // Error 32-bit EL0
505 #endif
506 END(vectors)
507
508 #ifdef CONFIG_VMAP_STACK
509         /*
510          * We detected an overflow in kernel_ventry, which switched to the
511          * overflow stack. Stash the exception regs, and head to our overflow
512          * handler.
513          */
514 __bad_stack:
515         /* Restore the original x0 value */
516         mrs     x0, tpidrro_el0
517
518         /*
519          * Store the original GPRs to the new stack. The orginal SP (minus
520          * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry.
521          */
522         sub     sp, sp, #S_FRAME_SIZE
523         kernel_entry 1
524         mrs     x0, tpidr_el0
525         add     x0, x0, #S_FRAME_SIZE
526         str     x0, [sp, #S_SP]
527
528         /* Stash the regs for handle_bad_stack */
529         mov     x0, sp
530
531         /* Time to die */
532         bl      handle_bad_stack
533         ASM_BUG()
534 #endif /* CONFIG_VMAP_STACK */
535
536 /*
537  * Invalid mode handlers
538  */
539         .macro  inv_entry, el, reason, regsize = 64
540         kernel_entry \el, \regsize
541         mov     x0, sp
542         mov     x1, #\reason
543         mrs     x2, esr_el1
544         bl      bad_mode
545         ASM_BUG()
546         .endm
547
548 el0_sync_invalid:
549         inv_entry 0, BAD_SYNC
550 ENDPROC(el0_sync_invalid)
551
552 el0_irq_invalid:
553         inv_entry 0, BAD_IRQ
554 ENDPROC(el0_irq_invalid)
555
556 el0_fiq_invalid:
557         inv_entry 0, BAD_FIQ
558 ENDPROC(el0_fiq_invalid)
559
560 el0_error_invalid:
561         inv_entry 0, BAD_ERROR
562 ENDPROC(el0_error_invalid)
563
564 #ifdef CONFIG_COMPAT
565 el0_fiq_invalid_compat:
566         inv_entry 0, BAD_FIQ, 32
567 ENDPROC(el0_fiq_invalid_compat)
568 #endif
569
570 el1_sync_invalid:
571         inv_entry 1, BAD_SYNC
572 ENDPROC(el1_sync_invalid)
573
574 el1_irq_invalid:
575         inv_entry 1, BAD_IRQ
576 ENDPROC(el1_irq_invalid)
577
578 el1_fiq_invalid:
579         inv_entry 1, BAD_FIQ
580 ENDPROC(el1_fiq_invalid)
581
582 el1_error_invalid:
583         inv_entry 1, BAD_ERROR
584 ENDPROC(el1_error_invalid)
585
586 /*
587  * EL1 mode handlers.
588  */
589         .align  6
590 el1_sync:
591         kernel_entry 1
592         mrs     x1, esr_el1                     // read the syndrome register
593         lsr     x24, x1, #ESR_ELx_EC_SHIFT      // exception class
594         cmp     x24, #ESR_ELx_EC_DABT_CUR       // data abort in EL1
595         b.eq    el1_da
596         cmp     x24, #ESR_ELx_EC_IABT_CUR       // instruction abort in EL1
597         b.eq    el1_ia
598         cmp     x24, #ESR_ELx_EC_SYS64          // configurable trap
599         b.eq    el1_undef
600         cmp     x24, #ESR_ELx_EC_PC_ALIGN       // pc alignment exception
601         b.eq    el1_pc
602         cmp     x24, #ESR_ELx_EC_UNKNOWN        // unknown exception in EL1
603         b.eq    el1_undef
604         cmp     x24, #ESR_ELx_EC_BREAKPT_CUR    // debug exception in EL1
605         b.ge    el1_dbg
606         b       el1_inv
607
608 el1_ia:
609         /*
610          * Fall through to the Data abort case
611          */
612 el1_da:
613         /*
614          * Data abort handling
615          */
616         mrs     x3, far_el1
617         inherit_daif    pstate=x23, tmp=x2
618         untagged_addr   x0, x3
619         mov     x2, sp                          // struct pt_regs
620         bl      do_mem_abort
621
622         kernel_exit 1
623 el1_pc:
624         /*
625          * PC alignment exception handling. We don't handle SP alignment faults,
626          * since we will have hit a recursive exception when trying to push the
627          * initial pt_regs.
628          */
629         mrs     x0, far_el1
630         inherit_daif    pstate=x23, tmp=x2
631         mov     x2, sp
632         bl      do_sp_pc_abort
633         ASM_BUG()
634 el1_undef:
635         /*
636          * Undefined instruction
637          */
638         inherit_daif    pstate=x23, tmp=x2
639         mov     x0, sp
640         bl      do_undefinstr
641         kernel_exit 1
642 el1_dbg:
643         /*
644          * Debug exception handling
645          */
646         cmp     x24, #ESR_ELx_EC_BRK64          // if BRK64
647         cinc    x24, x24, eq                    // set bit '0'
648         tbz     x24, #0, el1_inv                // EL1 only
649         gic_prio_kentry_setup tmp=x3
650         mrs     x0, far_el1
651         mov     x2, sp                          // struct pt_regs
652         bl      do_debug_exception
653         kernel_exit 1
654 el1_inv:
655         // TODO: add support for undefined instructions in kernel mode
656         inherit_daif    pstate=x23, tmp=x2
657         mov     x0, sp
658         mov     x2, x1
659         mov     x1, #BAD_SYNC
660         bl      bad_mode
661         ASM_BUG()
662 ENDPROC(el1_sync)
663
664         .align  6
665 el1_irq:
666         kernel_entry 1
667         gic_prio_irq_setup pmr=x20, tmp=x1
668         enable_da_f
669
670 #ifdef CONFIG_ARM64_PSEUDO_NMI
671         test_irqs_unmasked      res=x0, pmr=x20
672         cbz     x0, 1f
673         bl      asm_nmi_enter
674 1:
675 #endif
676
677 #ifdef CONFIG_TRACE_IRQFLAGS
678         bl      trace_hardirqs_off
679 #endif
680
681         irq_handler
682
683 #ifdef CONFIG_PREEMPT
684         ldr     x24, [tsk, #TSK_TI_PREEMPT]     // get preempt count
685 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
686         /*
687          * DA_F were cleared at start of handling. If anything is set in DAIF,
688          * we come back from an NMI, so skip preemption
689          */
690         mrs     x0, daif
691         orr     x24, x24, x0
692 alternative_else_nop_endif
693         cbnz    x24, 1f                         // preempt count != 0 || NMI return path
694         bl      arm64_preempt_schedule_irq      // irq en/disable is done inside
695 1:
696 #endif
697
698 #ifdef CONFIG_ARM64_PSEUDO_NMI
699         /*
700          * When using IRQ priority masking, we can get spurious interrupts while
701          * PMR is set to GIC_PRIO_IRQOFF. An NMI might also have occurred in a
702          * section with interrupts disabled. Skip tracing in those cases.
703          */
704         test_irqs_unmasked      res=x0, pmr=x20
705         cbz     x0, 1f
706         bl      asm_nmi_exit
707 1:
708 #endif
709
710 #ifdef CONFIG_TRACE_IRQFLAGS
711 #ifdef CONFIG_ARM64_PSEUDO_NMI
712         test_irqs_unmasked      res=x0, pmr=x20
713         cbnz    x0, 1f
714 #endif
715         bl      trace_hardirqs_on
716 1:
717 #endif
718
719         kernel_exit 1
720 ENDPROC(el1_irq)
721
722 /*
723  * EL0 mode handlers.
724  */
725         .align  6
726 el0_sync:
727         kernel_entry 0
728         mrs     x25, esr_el1                    // read the syndrome register
729         lsr     x24, x25, #ESR_ELx_EC_SHIFT     // exception class
730         cmp     x24, #ESR_ELx_EC_SVC64          // SVC in 64-bit state
731         b.eq    el0_svc
732         cmp     x24, #ESR_ELx_EC_DABT_LOW       // data abort in EL0
733         b.eq    el0_da
734         cmp     x24, #ESR_ELx_EC_IABT_LOW       // instruction abort in EL0
735         b.eq    el0_ia
736         cmp     x24, #ESR_ELx_EC_FP_ASIMD       // FP/ASIMD access
737         b.eq    el0_fpsimd_acc
738         cmp     x24, #ESR_ELx_EC_SVE            // SVE access
739         b.eq    el0_sve_acc
740         cmp     x24, #ESR_ELx_EC_FP_EXC64       // FP/ASIMD exception
741         b.eq    el0_fpsimd_exc
742         cmp     x24, #ESR_ELx_EC_SYS64          // configurable trap
743         ccmp    x24, #ESR_ELx_EC_WFx, #4, ne
744         b.eq    el0_sys
745         cmp     x24, #ESR_ELx_EC_SP_ALIGN       // stack alignment exception
746         b.eq    el0_sp
747         cmp     x24, #ESR_ELx_EC_PC_ALIGN       // pc alignment exception
748         b.eq    el0_pc
749         cmp     x24, #ESR_ELx_EC_UNKNOWN        // unknown exception in EL0
750         b.eq    el0_undef
751         cmp     x24, #ESR_ELx_EC_BREAKPT_LOW    // debug exception in EL0
752         b.ge    el0_dbg
753         b       el0_inv
754
755 #ifdef CONFIG_COMPAT
756         .align  6
757 el0_sync_compat:
758         kernel_entry 0, 32
759         mrs     x25, esr_el1                    // read the syndrome register
760         lsr     x24, x25, #ESR_ELx_EC_SHIFT     // exception class
761         cmp     x24, #ESR_ELx_EC_SVC32          // SVC in 32-bit state
762         b.eq    el0_svc_compat
763         cmp     x24, #ESR_ELx_EC_DABT_LOW       // data abort in EL0
764         b.eq    el0_da
765         cmp     x24, #ESR_ELx_EC_IABT_LOW       // instruction abort in EL0
766         b.eq    el0_ia
767         cmp     x24, #ESR_ELx_EC_FP_ASIMD       // FP/ASIMD access
768         b.eq    el0_fpsimd_acc
769         cmp     x24, #ESR_ELx_EC_FP_EXC32       // FP/ASIMD exception
770         b.eq    el0_fpsimd_exc
771         cmp     x24, #ESR_ELx_EC_PC_ALIGN       // pc alignment exception
772         b.eq    el0_pc
773         cmp     x24, #ESR_ELx_EC_UNKNOWN        // unknown exception in EL0
774         b.eq    el0_undef
775         cmp     x24, #ESR_ELx_EC_CP15_32        // CP15 MRC/MCR trap
776         b.eq    el0_cp15
777         cmp     x24, #ESR_ELx_EC_CP15_64        // CP15 MRRC/MCRR trap
778         b.eq    el0_cp15
779         cmp     x24, #ESR_ELx_EC_CP14_MR        // CP14 MRC/MCR trap
780         b.eq    el0_undef
781         cmp     x24, #ESR_ELx_EC_CP14_LS        // CP14 LDC/STC trap
782         b.eq    el0_undef
783         cmp     x24, #ESR_ELx_EC_CP14_64        // CP14 MRRC/MCRR trap
784         b.eq    el0_undef
785         cmp     x24, #ESR_ELx_EC_BREAKPT_LOW    // debug exception in EL0
786         b.ge    el0_dbg
787         b       el0_inv
788 el0_svc_compat:
789         gic_prio_kentry_setup tmp=x1
790         mov     x0, sp
791         bl      el0_svc_compat_handler
792         b       ret_to_user
793
794         .align  6
795 el0_irq_compat:
796         kernel_entry 0, 32
797         b       el0_irq_naked
798
799 el0_error_compat:
800         kernel_entry 0, 32
801         b       el0_error_naked
802
803 el0_cp15:
804         /*
805          * Trapped CP15 (MRC, MCR, MRRC, MCRR) instructions
806          */
807         ct_user_exit_irqoff
808         enable_daif
809         mov     x0, x25
810         mov     x1, sp
811         bl      do_cp15instr
812         b       ret_to_user
813 #endif
814
815 el0_da:
816         /*
817          * Data abort handling
818          */
819         mrs     x26, far_el1
820         ct_user_exit_irqoff
821         enable_daif
822         untagged_addr   x0, x26
823         mov     x1, x25
824         mov     x2, sp
825         bl      do_mem_abort
826         b       ret_to_user
827 el0_ia:
828         /*
829          * Instruction abort handling
830          */
831         mrs     x26, far_el1
832         gic_prio_kentry_setup tmp=x0
833         ct_user_exit_irqoff
834         enable_da_f
835 #ifdef CONFIG_TRACE_IRQFLAGS
836         bl      trace_hardirqs_off
837 #endif
838         mov     x0, x26
839         mov     x1, x25
840         mov     x2, sp
841         bl      do_el0_ia_bp_hardening
842         b       ret_to_user
843 el0_fpsimd_acc:
844         /*
845          * Floating Point or Advanced SIMD access
846          */
847         ct_user_exit_irqoff
848         enable_daif
849         mov     x0, x25
850         mov     x1, sp
851         bl      do_fpsimd_acc
852         b       ret_to_user
853 el0_sve_acc:
854         /*
855          * Scalable Vector Extension access
856          */
857         ct_user_exit_irqoff
858         enable_daif
859         mov     x0, x25
860         mov     x1, sp
861         bl      do_sve_acc
862         b       ret_to_user
863 el0_fpsimd_exc:
864         /*
865          * Floating Point, Advanced SIMD or SVE exception
866          */
867         ct_user_exit_irqoff
868         enable_daif
869         mov     x0, x25
870         mov     x1, sp
871         bl      do_fpsimd_exc
872         b       ret_to_user
873 el0_sp:
874         ldr     x26, [sp, #S_SP]
875         b       el0_sp_pc
876 el0_pc:
877         mrs     x26, far_el1
878 el0_sp_pc:
879         /*
880          * Stack or PC alignment exception handling
881          */
882         gic_prio_kentry_setup tmp=x0
883         ct_user_exit_irqoff
884         enable_da_f
885 #ifdef CONFIG_TRACE_IRQFLAGS
886         bl      trace_hardirqs_off
887 #endif
888         mov     x0, x26
889         mov     x1, x25
890         mov     x2, sp
891         bl      do_sp_pc_abort
892         b       ret_to_user
893 el0_undef:
894         /*
895          * Undefined instruction
896          */
897         ct_user_exit_irqoff
898         enable_daif
899         mov     x0, sp
900         bl      do_undefinstr
901         b       ret_to_user
902 el0_sys:
903         /*
904          * System instructions, for trapped cache maintenance instructions
905          */
906         ct_user_exit_irqoff
907         enable_daif
908         mov     x0, x25
909         mov     x1, sp
910         bl      do_sysinstr
911         b       ret_to_user
912 el0_dbg:
913         /*
914          * Debug exception handling
915          */
916         tbnz    x24, #0, el0_inv                // EL0 only
917         mrs     x24, far_el1
918         gic_prio_kentry_setup tmp=x3
919         ct_user_exit_irqoff
920         mov     x0, x24
921         mov     x1, x25
922         mov     x2, sp
923         bl      do_debug_exception
924         enable_da_f
925         b       ret_to_user
926 el0_inv:
927         ct_user_exit_irqoff
928         enable_daif
929         mov     x0, sp
930         mov     x1, #BAD_SYNC
931         mov     x2, x25
932         bl      bad_el0_sync
933         b       ret_to_user
934 ENDPROC(el0_sync)
935
936         .align  6
937 el0_irq:
938         kernel_entry 0
939 el0_irq_naked:
940         gic_prio_irq_setup pmr=x20, tmp=x0
941         ct_user_exit_irqoff
942         enable_da_f
943
944 #ifdef CONFIG_TRACE_IRQFLAGS
945         bl      trace_hardirqs_off
946 #endif
947
948 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
949         tbz     x22, #55, 1f
950         bl      do_el0_irq_bp_hardening
951 1:
952 #endif
953         irq_handler
954
955 #ifdef CONFIG_TRACE_IRQFLAGS
956         bl      trace_hardirqs_on
957 #endif
958         b       ret_to_user
959 ENDPROC(el0_irq)
960
961 el1_error:
962         kernel_entry 1
963         mrs     x1, esr_el1
964         gic_prio_kentry_setup tmp=x2
965         enable_dbg
966         mov     x0, sp
967         bl      do_serror
968         kernel_exit 1
969 ENDPROC(el1_error)
970
971 el0_error:
972         kernel_entry 0
973 el0_error_naked:
974         mrs     x25, esr_el1
975         gic_prio_kentry_setup tmp=x2
976         ct_user_exit_irqoff
977         enable_dbg
978         mov     x0, sp
979         mov     x1, x25
980         bl      do_serror
981         enable_da_f
982         b       ret_to_user
983 ENDPROC(el0_error)
984
985 /*
986  * Ok, we need to do extra processing, enter the slow path.
987  */
988 work_pending:
989         mov     x0, sp                          // 'regs'
990         bl      do_notify_resume
991 #ifdef CONFIG_TRACE_IRQFLAGS
992         bl      trace_hardirqs_on               // enabled while in userspace
993 #endif
994         ldr     x1, [tsk, #TSK_TI_FLAGS]        // re-check for single-step
995         b       finish_ret_to_user
996 /*
997  * "slow" syscall return path.
998  */
999 ret_to_user:
1000         disable_daif
1001         gic_prio_kentry_setup tmp=x3
1002         ldr     x1, [tsk, #TSK_TI_FLAGS]
1003         and     x2, x1, #_TIF_WORK_MASK
1004         cbnz    x2, work_pending
1005 finish_ret_to_user:
1006         enable_step_tsk x1, x2
1007 #ifdef CONFIG_GCC_PLUGIN_STACKLEAK
1008         bl      stackleak_erase
1009 #endif
1010         kernel_exit 0
1011 ENDPROC(ret_to_user)
1012
1013 /*
1014  * SVC handler.
1015  */
1016         .align  6
1017 el0_svc:
1018         gic_prio_kentry_setup tmp=x1
1019         mov     x0, sp
1020         bl      el0_svc_handler
1021         b       ret_to_user
1022 ENDPROC(el0_svc)
1023
1024         .popsection                             // .entry.text
1025
1026         // Move from tramp_pg_dir to swapper_pg_dir
1027         .macro tramp_map_kernel, tmp
1028         mrs     \tmp, ttbr1_el1
1029         add     \tmp, \tmp, #(2 * PAGE_SIZE)
1030         bic     \tmp, \tmp, #USER_ASID_FLAG
1031         msr     ttbr1_el1, \tmp
1032 #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
1033 alternative_if ARM64_WORKAROUND_QCOM_FALKOR_E1003
1034         /* ASID already in \tmp[63:48] */
1035         movk    \tmp, #:abs_g2_nc:(TRAMP_VALIAS >> 12)
1036         movk    \tmp, #:abs_g1_nc:(TRAMP_VALIAS >> 12)
1037         /* 2MB boundary containing the vectors, so we nobble the walk cache */
1038         movk    \tmp, #:abs_g0_nc:((TRAMP_VALIAS & ~(SZ_2M - 1)) >> 12)
1039         isb
1040         tlbi    vae1, \tmp
1041         dsb     nsh
1042 alternative_else_nop_endif
1043 #endif /* CONFIG_QCOM_FALKOR_ERRATUM_1003 */
1044         .endm
1045
1046         // Move from swapper_pg_dir to tramp_pg_dir
1047         .macro tramp_unmap_kernel, tmp
1048         mrs     \tmp, ttbr1_el1
1049         sub     \tmp, \tmp, #(2 * PAGE_SIZE)
1050         orr     \tmp, \tmp, #USER_ASID_FLAG
1051         msr     ttbr1_el1, \tmp
1052         /*
1053          * We avoid running the post_ttbr_update_workaround here because
1054          * it's only needed by Cavium ThunderX, which requires KPTI to be
1055          * disabled.
1056          */
1057         .endm
1058
1059         .macro tramp_data_page  dst
1060         adr_l   \dst, .entry.tramp.text
1061         sub     \dst, \dst, PAGE_SIZE
1062         .endm
1063
1064         .macro tramp_data_read_var      dst, var
1065 #ifdef CONFIG_RANDOMIZE_BASE
1066         tramp_data_page         \dst
1067         add     \dst, \dst, #:lo12:__entry_tramp_data_\var
1068         ldr     \dst, [\dst]
1069 #else
1070         ldr     \dst, =\var
1071 #endif
1072         .endm
1073
1074 #define BHB_MITIGATION_NONE     0
1075 #define BHB_MITIGATION_LOOP     1
1076 #define BHB_MITIGATION_FW       2
1077 #define BHB_MITIGATION_INSN     3
1078
1079         .macro tramp_ventry, vector_start, regsize, kpti, bhb
1080         .align  7
1081 1:
1082         .if     \regsize == 64
1083         msr     tpidrro_el0, x30        // Restored in kernel_ventry
1084         .endif
1085
1086         .if     \bhb == BHB_MITIGATION_LOOP
1087         /*
1088          * This sequence must appear before the first indirect branch. i.e. the
1089          * ret out of tramp_ventry. It appears here because x30 is free.
1090          */
1091         __mitigate_spectre_bhb_loop     x30
1092         .endif // \bhb == BHB_MITIGATION_LOOP
1093
1094         .if     \bhb == BHB_MITIGATION_INSN
1095         clearbhb
1096         isb
1097         .endif // \bhb == BHB_MITIGATION_INSN
1098
1099         .if     \kpti == 1
1100         /*
1101          * Defend against branch aliasing attacks by pushing a dummy
1102          * entry onto the return stack and using a RET instruction to
1103          * enter the full-fat kernel vectors.
1104          */
1105         bl      2f
1106         b       .
1107 2:
1108         tramp_map_kernel        x30
1109 alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
1110         tramp_data_read_var     x30, vectors
1111 alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM
1112         prfm    plil1strm, [x30, #(1b - \vector_start)]
1113 alternative_else_nop_endif
1114
1115         msr     vbar_el1, x30
1116         isb
1117         .else
1118         ldr     x30, =vectors
1119         .endif // \kpti == 1
1120
1121         .if     \bhb == BHB_MITIGATION_FW
1122         /*
1123          * The firmware sequence must appear before the first indirect branch.
1124          * i.e. the ret out of tramp_ventry. But it also needs the stack to be
1125          * mapped to save/restore the registers the SMC clobbers.
1126          */
1127         __mitigate_spectre_bhb_fw
1128         .endif // \bhb == BHB_MITIGATION_FW
1129
1130         add     x30, x30, #(1b - \vector_start + 4)
1131         ret
1132 .org 1b + 128   // Did we overflow the ventry slot?
1133         .endm
1134
1135         .macro tramp_exit, regsize = 64
1136         tramp_data_read_var     x30, this_cpu_vector
1137 alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
1138         mrs     x29, tpidr_el1
1139 alternative_else
1140         mrs     x29, tpidr_el2
1141 alternative_endif
1142         ldr     x30, [x30, x29]
1143
1144         msr     vbar_el1, x30
1145         ldr     lr, [sp, #S_LR]
1146         tramp_unmap_kernel      x29
1147         .if     \regsize == 64
1148         mrs     x29, far_el1
1149         .endif
1150         add     sp, sp, #S_FRAME_SIZE           // restore sp
1151         eret
1152         sb
1153         .endm
1154
1155         .macro  generate_tramp_vector,  kpti, bhb
1156 .Lvector_start\@:
1157         .space  0x400
1158
1159         .rept   4
1160         tramp_ventry    .Lvector_start\@, 64, \kpti, \bhb
1161         .endr
1162         .rept   4
1163         tramp_ventry    .Lvector_start\@, 32, \kpti, \bhb
1164         .endr
1165         .endm
1166
1167 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
1168 /*
1169  * Exception vectors trampoline.
1170  * The order must match __bp_harden_el1_vectors and the
1171  * arm64_bp_harden_el1_vectors enum.
1172  */
1173         .pushsection ".entry.tramp.text", "ax"
1174         .align  11
1175 ENTRY(tramp_vectors)
1176 #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
1177         generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_LOOP
1178         generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_FW
1179         generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_INSN
1180 #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
1181         generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_NONE
1182 END(tramp_vectors)
1183
1184 ENTRY(tramp_exit_native)
1185         tramp_exit
1186 END(tramp_exit_native)
1187
1188 ENTRY(tramp_exit_compat)
1189         tramp_exit      32
1190 END(tramp_exit_compat)
1191
1192         .ltorg
1193         .popsection                             // .entry.tramp.text
1194 #ifdef CONFIG_RANDOMIZE_BASE
1195         .pushsection ".rodata", "a"
1196         .align PAGE_SHIFT
1197         .globl  __entry_tramp_data_start
1198 __entry_tramp_data_start:
1199 __entry_tramp_data_vectors:
1200         .quad   vectors
1201 #ifdef CONFIG_ARM_SDE_INTERFACE
1202 __entry_tramp_data___sdei_asm_handler:
1203         .quad   __sdei_asm_handler
1204 #endif /* CONFIG_ARM_SDE_INTERFACE */
1205 __entry_tramp_data_this_cpu_vector:
1206         .quad   this_cpu_vector
1207         .popsection                             // .rodata
1208 #endif /* CONFIG_RANDOMIZE_BASE */
1209 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
1210
1211 /*
1212  * Exception vectors for spectre mitigations on entry from EL1 when
1213  * kpti is not in use.
1214  */
1215         .macro generate_el1_vector, bhb
1216 .Lvector_start\@:
1217         kernel_ventry   1, sync_invalid                 // Synchronous EL1t
1218         kernel_ventry   1, irq_invalid                  // IRQ EL1t
1219         kernel_ventry   1, fiq_invalid                  // FIQ EL1t
1220         kernel_ventry   1, error_invalid                // Error EL1t
1221
1222         kernel_ventry   1, sync                         // Synchronous EL1h
1223         kernel_ventry   1, irq                          // IRQ EL1h
1224         kernel_ventry   1, fiq_invalid                  // FIQ EL1h
1225         kernel_ventry   1, error                        // Error EL1h
1226
1227         .rept   4
1228         tramp_ventry    .Lvector_start\@, 64, 0, \bhb
1229         .endr
1230         .rept 4
1231         tramp_ventry    .Lvector_start\@, 32, 0, \bhb
1232         .endr
1233         .endm
1234
1235 /* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */
1236         .pushsection ".entry.text", "ax"
1237         .align  11
1238 SYM_CODE_START(__bp_harden_el1_vectors)
1239 #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
1240         generate_el1_vector     bhb=BHB_MITIGATION_LOOP
1241         generate_el1_vector     bhb=BHB_MITIGATION_FW
1242         generate_el1_vector     bhb=BHB_MITIGATION_INSN
1243 #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
1244 SYM_CODE_END(__bp_harden_el1_vectors)
1245         .popsection
1246
1247
1248 /*
1249  * Register switch for AArch64. The callee-saved registers need to be saved
1250  * and restored. On entry:
1251  *   x0 = previous task_struct (must be preserved across the switch)
1252  *   x1 = next task_struct
1253  * Previous and next are guaranteed not to be the same.
1254  *
1255  */
1256 ENTRY(cpu_switch_to)
1257         mov     x10, #THREAD_CPU_CONTEXT
1258         add     x8, x0, x10
1259         mov     x9, sp
1260         stp     x19, x20, [x8], #16             // store callee-saved registers
1261         stp     x21, x22, [x8], #16
1262         stp     x23, x24, [x8], #16
1263         stp     x25, x26, [x8], #16
1264         stp     x27, x28, [x8], #16
1265         stp     x29, x9, [x8], #16
1266         str     lr, [x8]
1267         add     x8, x1, x10
1268         ldp     x19, x20, [x8], #16             // restore callee-saved registers
1269         ldp     x21, x22, [x8], #16
1270         ldp     x23, x24, [x8], #16
1271         ldp     x25, x26, [x8], #16
1272         ldp     x27, x28, [x8], #16
1273         ldp     x29, x9, [x8], #16
1274         ldr     lr, [x8]
1275         mov     sp, x9
1276         msr     sp_el0, x1
1277         ret
1278 ENDPROC(cpu_switch_to)
1279 NOKPROBE(cpu_switch_to)
1280
1281 /*
1282  * This is how we return from a fork.
1283  */
1284 ENTRY(ret_from_fork)
1285         bl      schedule_tail
1286         cbz     x19, 1f                         // not a kernel thread
1287         mov     x0, x20
1288         blr     x19
1289 1:      get_current_task tsk
1290         b       ret_to_user
1291 ENDPROC(ret_from_fork)
1292 NOKPROBE(ret_from_fork)
1293
1294 #ifdef CONFIG_ARM_SDE_INTERFACE
1295
1296 #include <asm/sdei.h>
1297 #include <uapi/linux/arm_sdei.h>
1298
1299 .macro sdei_handler_exit exit_mode
1300         /* On success, this call never returns... */
1301         cmp     \exit_mode, #SDEI_EXIT_SMC
1302         b.ne    99f
1303         smc     #0
1304         b       .
1305 99:     hvc     #0
1306         b       .
1307 .endm
1308
1309 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
1310 /*
1311  * The regular SDEI entry point may have been unmapped along with the rest of
1312  * the kernel. This trampoline restores the kernel mapping to make the x1 memory
1313  * argument accessible.
1314  *
1315  * This clobbers x4, __sdei_handler() will restore this from firmware's
1316  * copy.
1317  */
1318 .ltorg
1319 .pushsection ".entry.tramp.text", "ax"
1320 ENTRY(__sdei_asm_entry_trampoline)
1321         mrs     x4, ttbr1_el1
1322         tbz     x4, #USER_ASID_BIT, 1f
1323
1324         tramp_map_kernel tmp=x4
1325         isb
1326         mov     x4, xzr
1327
1328         /*
1329          * Use reg->interrupted_regs.addr_limit to remember whether to unmap
1330          * the kernel on exit.
1331          */
1332 1:      str     x4, [x1, #(SDEI_EVENT_INTREGS + S_ORIG_ADDR_LIMIT)]
1333
1334         tramp_data_read_var     x4, __sdei_asm_handler
1335         br      x4
1336 ENDPROC(__sdei_asm_entry_trampoline)
1337 NOKPROBE(__sdei_asm_entry_trampoline)
1338
1339 /*
1340  * Make the exit call and restore the original ttbr1_el1
1341  *
1342  * x0 & x1: setup for the exit API call
1343  * x2: exit_mode
1344  * x4: struct sdei_registered_event argument from registration time.
1345  */
1346 ENTRY(__sdei_asm_exit_trampoline)
1347         ldr     x4, [x4, #(SDEI_EVENT_INTREGS + S_ORIG_ADDR_LIMIT)]
1348         cbnz    x4, 1f
1349
1350         tramp_unmap_kernel      tmp=x4
1351
1352 1:      sdei_handler_exit exit_mode=x2
1353 ENDPROC(__sdei_asm_exit_trampoline)
1354 NOKPROBE(__sdei_asm_exit_trampoline)
1355         .ltorg
1356 .popsection             // .entry.tramp.text
1357 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
1358
1359 /*
1360  * Software Delegated Exception entry point.
1361  *
1362  * x0: Event number
1363  * x1: struct sdei_registered_event argument from registration time.
1364  * x2: interrupted PC
1365  * x3: interrupted PSTATE
1366  * x4: maybe clobbered by the trampoline
1367  *
1368  * Firmware has preserved x0->x17 for us, we must save/restore the rest to
1369  * follow SMC-CC. We save (or retrieve) all the registers as the handler may
1370  * want them.
1371  */
1372 ENTRY(__sdei_asm_handler)
1373         stp     x2, x3, [x1, #SDEI_EVENT_INTREGS + S_PC]
1374         stp     x4, x5, [x1, #SDEI_EVENT_INTREGS + 16 * 2]
1375         stp     x6, x7, [x1, #SDEI_EVENT_INTREGS + 16 * 3]
1376         stp     x8, x9, [x1, #SDEI_EVENT_INTREGS + 16 * 4]
1377         stp     x10, x11, [x1, #SDEI_EVENT_INTREGS + 16 * 5]
1378         stp     x12, x13, [x1, #SDEI_EVENT_INTREGS + 16 * 6]
1379         stp     x14, x15, [x1, #SDEI_EVENT_INTREGS + 16 * 7]
1380         stp     x16, x17, [x1, #SDEI_EVENT_INTREGS + 16 * 8]
1381         stp     x18, x19, [x1, #SDEI_EVENT_INTREGS + 16 * 9]
1382         stp     x20, x21, [x1, #SDEI_EVENT_INTREGS + 16 * 10]
1383         stp     x22, x23, [x1, #SDEI_EVENT_INTREGS + 16 * 11]
1384         stp     x24, x25, [x1, #SDEI_EVENT_INTREGS + 16 * 12]
1385         stp     x26, x27, [x1, #SDEI_EVENT_INTREGS + 16 * 13]
1386         stp     x28, x29, [x1, #SDEI_EVENT_INTREGS + 16 * 14]
1387         mov     x4, sp
1388         stp     lr, x4, [x1, #SDEI_EVENT_INTREGS + S_LR]
1389
1390         mov     x19, x1
1391
1392 #ifdef CONFIG_VMAP_STACK
1393         /*
1394          * entry.S may have been using sp as a scratch register, find whether
1395          * this is a normal or critical event and switch to the appropriate
1396          * stack for this CPU.
1397          */
1398         ldrb    w4, [x19, #SDEI_EVENT_PRIORITY]
1399         cbnz    w4, 1f
1400         ldr_this_cpu dst=x5, sym=sdei_stack_normal_ptr, tmp=x6
1401         b       2f
1402 1:      ldr_this_cpu dst=x5, sym=sdei_stack_critical_ptr, tmp=x6
1403 2:      mov     x6, #SDEI_STACK_SIZE
1404         add     x5, x5, x6
1405         mov     sp, x5
1406 #endif
1407
1408         /*
1409          * We may have interrupted userspace, or a guest, or exit-from or
1410          * return-to either of these. We can't trust sp_el0, restore it.
1411          */
1412         mrs     x28, sp_el0
1413         ldr_this_cpu    dst=x0, sym=__entry_task, tmp=x1
1414         msr     sp_el0, x0
1415
1416         /* If we interrupted the kernel point to the previous stack/frame. */
1417         and     x0, x3, #0xc
1418         mrs     x1, CurrentEL
1419         cmp     x0, x1
1420         csel    x29, x29, xzr, eq       // fp, or zero
1421         csel    x4, x2, xzr, eq         // elr, or zero
1422
1423         stp     x29, x4, [sp, #-16]!
1424         mov     x29, sp
1425
1426         add     x0, x19, #SDEI_EVENT_INTREGS
1427         mov     x1, x19
1428         bl      __sdei_handler
1429
1430         msr     sp_el0, x28
1431         /* restore regs >x17 that we clobbered */
1432         mov     x4, x19         // keep x4 for __sdei_asm_exit_trampoline
1433         ldp     x28, x29, [x4, #SDEI_EVENT_INTREGS + 16 * 14]
1434         ldp     x18, x19, [x4, #SDEI_EVENT_INTREGS + 16 * 9]
1435         ldp     lr, x1, [x4, #SDEI_EVENT_INTREGS + S_LR]
1436         mov     sp, x1
1437
1438         mov     x1, x0                  // address to complete_and_resume
1439         /* x0 = (x0 <= 1) ? EVENT_COMPLETE:EVENT_COMPLETE_AND_RESUME */
1440         cmp     x0, #1
1441         mov_q   x2, SDEI_1_0_FN_SDEI_EVENT_COMPLETE
1442         mov_q   x3, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME
1443         csel    x0, x2, x3, ls
1444
1445         ldr_l   x2, sdei_exit_mode
1446
1447 alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
1448         sdei_handler_exit exit_mode=x2
1449 alternative_else_nop_endif
1450
1451 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
1452         tramp_alias     dst=x5, sym=__sdei_asm_exit_trampoline, tmp=x3
1453         br      x5
1454 #endif
1455 ENDPROC(__sdei_asm_handler)
1456 NOKPROBE(__sdei_asm_handler)
1457 #endif /* CONFIG_ARM_SDE_INTERFACE */