x86/mm: Use WRITE_ONCE() when setting PTEs
[linux/fpc-iii.git] / arch / arm64 / kernel / entry.S
blobca978d7d98eb49e5d1ecdbf769b36311ed38586e
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  */
21 #include <linux/arm-smccc.h>
22 #include <linux/init.h>
23 #include <linux/linkage.h>
25 #include <asm/alternative.h>
26 #include <asm/assembler.h>
27 #include <asm/asm-offsets.h>
28 #include <asm/cpufeature.h>
29 #include <asm/errno.h>
30 #include <asm/esr.h>
31 #include <asm/irq.h>
32 #include <asm/memory.h>
33 #include <asm/mmu.h>
34 #include <asm/processor.h>
35 #include <asm/thread_info.h>
36 #include <asm/asm-uaccess.h>
37 #include <asm/unistd.h>
38 #include <asm/kernel-pgtable.h>
41  * Context tracking subsystem.  Used to instrument transitions
42  * between user and kernel mode.
43  */
44         .macro ct_user_exit, syscall = 0
45 #ifdef CONFIG_CONTEXT_TRACKING
46         bl      context_tracking_user_exit
47         .if \syscall == 1
48         /*
49          * Save/restore needed during syscalls.  Restore syscall arguments from
50          * the values already saved on stack during kernel_entry.
51          */
52         ldp     x0, x1, [sp]
53         ldp     x2, x3, [sp, #S_X2]
54         ldp     x4, x5, [sp, #S_X4]
55         ldp     x6, x7, [sp, #S_X6]
56         .endif
57 #endif
58         .endm
60         .macro ct_user_enter
61 #ifdef CONFIG_CONTEXT_TRACKING
62         bl      context_tracking_user_enter
63 #endif
64         .endm
67  * Bad Abort numbers
68  *-----------------
69  */
70 #define BAD_SYNC        0
71 #define BAD_IRQ         1
72 #define BAD_FIQ         2
73 #define BAD_ERROR       3
75         .macro kernel_ventry, el, label, regsize = 64
76         .align 7
77 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
78 alternative_if ARM64_UNMAP_KERNEL_AT_EL0
79         .if     \el == 0
80         .if     \regsize == 64
81         mrs     x30, tpidrro_el0
82         msr     tpidrro_el0, xzr
83         .else
84         mov     x30, xzr
85         .endif
86         .endif
87 alternative_else_nop_endif
88 #endif
90         sub     sp, sp, #S_FRAME_SIZE
91         b       el\()\el\()_\label
92         .endm
94         .macro tramp_alias, dst, sym
95         mov_q   \dst, TRAMP_VALIAS
96         add     \dst, \dst, #(\sym - .entry.tramp.text)
97         .endm
99         // This macro corrupts x0-x3. It is the caller's duty
100         // to save/restore them if required.
101         .macro  apply_ssbd, state, targ, tmp1, tmp2
102 #ifdef CONFIG_ARM64_SSBD
103 alternative_cb  arm64_enable_wa2_handling
104         b       \targ
105 alternative_cb_end
106         ldr_this_cpu    \tmp2, arm64_ssbd_callback_required, \tmp1
107         cbz     \tmp2, \targ
108         ldr     \tmp2, [tsk, #TI_FLAGS]
109         tbnz    \tmp2, #TIF_SSBD, \targ
110         mov     w0, #ARM_SMCCC_ARCH_WORKAROUND_2
111         mov     w1, #\state
112 alternative_cb  arm64_update_smccc_conduit
113         nop                                     // Patched to SMC/HVC #0
114 alternative_cb_end
115 #endif
116         .endm
118         .macro  kernel_entry, el, regsize = 64
119         .if     \regsize == 32
120         mov     w0, w0                          // zero upper 32 bits of x0
121         .endif
122         stp     x0, x1, [sp, #16 * 0]
123         stp     x2, x3, [sp, #16 * 1]
124         stp     x4, x5, [sp, #16 * 2]
125         stp     x6, x7, [sp, #16 * 3]
126         stp     x8, x9, [sp, #16 * 4]
127         stp     x10, x11, [sp, #16 * 5]
128         stp     x12, x13, [sp, #16 * 6]
129         stp     x14, x15, [sp, #16 * 7]
130         stp     x16, x17, [sp, #16 * 8]
131         stp     x18, x19, [sp, #16 * 9]
132         stp     x20, x21, [sp, #16 * 10]
133         stp     x22, x23, [sp, #16 * 11]
134         stp     x24, x25, [sp, #16 * 12]
135         stp     x26, x27, [sp, #16 * 13]
136         stp     x28, x29, [sp, #16 * 14]
138         .if     \el == 0
139         mrs     x21, sp_el0
140         mov     tsk, sp
141         and     tsk, tsk, #~(THREAD_SIZE - 1)   // Ensure MDSCR_EL1.SS is clear,
142         ldr     x19, [tsk, #TI_FLAGS]           // since we can unmask debug
143         disable_step_tsk x19, x20               // exceptions when scheduling.
145         apply_ssbd 1, 1f, x22, x23
147 #ifdef CONFIG_ARM64_SSBD
148         ldp     x0, x1, [sp, #16 * 0]
149         ldp     x2, x3, [sp, #16 * 1]
150 #endif
153         mov     x29, xzr                        // fp pointed to user-space
154         .else
155         add     x21, sp, #S_FRAME_SIZE
156         get_thread_info tsk
157         /* Save the task's original addr_limit and set USER_DS */
158         ldr     x20, [tsk, #TI_ADDR_LIMIT]
159         str     x20, [sp, #S_ORIG_ADDR_LIMIT]
160         mov     x20, #USER_DS
161         str     x20, [tsk, #TI_ADDR_LIMIT]
162         /* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
163         .endif /* \el == 0 */
164         mrs     x22, elr_el1
165         mrs     x23, spsr_el1
166         stp     lr, x21, [sp, #S_LR]
167         stp     x22, x23, [sp, #S_PC]
169         /*
170          * Set syscallno to -1 by default (overridden later if real syscall).
171          */
172         .if     \el == 0
173         mvn     x21, xzr
174         str     x21, [sp, #S_SYSCALLNO]
175         .endif
177         /*
178          * Set sp_el0 to current thread_info.
179          */
180         .if     \el == 0
181         msr     sp_el0, tsk
182         .endif
184         /*
185          * Registers that may be useful after this macro is invoked:
186          *
187          * x21 - aborted SP
188          * x22 - aborted PC
189          * x23 - aborted PSTATE
190         */
191         .endm
193         .macro  kernel_exit, el
194         .if     \el != 0
195         /* Restore the task's original addr_limit. */
196         ldr     x20, [sp, #S_ORIG_ADDR_LIMIT]
197         str     x20, [tsk, #TI_ADDR_LIMIT]
199         /* No need to restore UAO, it will be restored from SPSR_EL1 */
200         .endif
202         ldp     x21, x22, [sp, #S_PC]           // load ELR, SPSR
203         .if     \el == 0
204         ct_user_enter
205         ldr     x23, [sp, #S_SP]                // load return stack pointer
206         msr     sp_el0, x23
207         tst     x22, #PSR_MODE32_BIT            // native task?
208         b.eq    3f
210 #ifdef CONFIG_ARM64_ERRATUM_845719
211 alternative_if ARM64_WORKAROUND_845719
212 #ifdef CONFIG_PID_IN_CONTEXTIDR
213         mrs     x29, contextidr_el1
214         msr     contextidr_el1, x29
215 #else
216         msr contextidr_el1, xzr
217 #endif
218 alternative_else_nop_endif
219 #endif
221         apply_ssbd 0, 5f, x0, x1
223         .endif
224         msr     elr_el1, x21                    // set up the return data
225         msr     spsr_el1, x22
226         ldp     x0, x1, [sp, #16 * 0]
227         ldp     x2, x3, [sp, #16 * 1]
228         ldp     x4, x5, [sp, #16 * 2]
229         ldp     x6, x7, [sp, #16 * 3]
230         ldp     x8, x9, [sp, #16 * 4]
231         ldp     x10, x11, [sp, #16 * 5]
232         ldp     x12, x13, [sp, #16 * 6]
233         ldp     x14, x15, [sp, #16 * 7]
234         ldp     x16, x17, [sp, #16 * 8]
235         ldp     x18, x19, [sp, #16 * 9]
236         ldp     x20, x21, [sp, #16 * 10]
237         ldp     x22, x23, [sp, #16 * 11]
238         ldp     x24, x25, [sp, #16 * 12]
239         ldp     x26, x27, [sp, #16 * 13]
240         ldp     x28, x29, [sp, #16 * 14]
241         ldr     lr, [sp, #S_LR]
242         add     sp, sp, #S_FRAME_SIZE           // restore sp
244         .if     \el == 0
245 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
246 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
247         bne     4f
248         msr     far_el1, x30
249         tramp_alias     x30, tramp_exit_native
250         br      x30
252         tramp_alias     x30, tramp_exit_compat
253         br      x30
254 #endif
255         .else
256         eret
257         .endif
258         .endm
260         .macro  get_thread_info, rd
261         mrs     \rd, sp_el0
262         .endm
264         .macro  irq_stack_entry
265         mov     x19, sp                 // preserve the original sp
267         /*
268          * Compare sp with the current thread_info, if the top
269          * ~(THREAD_SIZE - 1) bits match, we are on a task stack, and
270          * should switch to the irq stack.
271          */
272         and     x25, x19, #~(THREAD_SIZE - 1)
273         cmp     x25, tsk
274         b.ne    9998f
276         adr_this_cpu x25, irq_stack, x26
277         mov     x26, #IRQ_STACK_START_SP
278         add     x26, x25, x26
280         /* switch to the irq stack */
281         mov     sp, x26
283         /*
284          * Add a dummy stack frame, this non-standard format is fixed up
285          * by unwind_frame()
286          */
287         stp     x29, x19, [sp, #-16]!
288         mov     x29, sp
290 9998:
291         .endm
293         /*
294          * x19 should be preserved between irq_stack_entry and
295          * irq_stack_exit.
296          */
297         .macro  irq_stack_exit
298         mov     sp, x19
299         .endm
302  * These are the registers used in the syscall handler, and allow us to
303  * have in theory up to 7 arguments to a function - x0 to x6.
305  * x7 is reserved for the system call number in 32-bit mode.
306  */
307 sc_nr   .req    x25             // number of system calls
308 scno    .req    x26             // syscall number
309 stbl    .req    x27             // syscall table pointer
310 tsk     .req    x28             // current thread_info
313  * Interrupt handling.
314  */
315         .macro  irq_handler
316         ldr_l   x1, handle_arch_irq
317         mov     x0, sp
318         irq_stack_entry
319         blr     x1
320         irq_stack_exit
321         .endm
323         .text
326  * Exception vectors.
327  */
328         .pushsection ".entry.text", "ax"
330         .align  11
331 ENTRY(vectors)
332         kernel_ventry   1, sync_invalid                 // Synchronous EL1t
333         kernel_ventry   1, irq_invalid                  // IRQ EL1t
334         kernel_ventry   1, fiq_invalid                  // FIQ EL1t
335         kernel_ventry   1, error_invalid                // Error EL1t
337         kernel_ventry   1, sync                         // Synchronous EL1h
338         kernel_ventry   1, irq                          // IRQ EL1h
339         kernel_ventry   1, fiq_invalid                  // FIQ EL1h
340         kernel_ventry   1, error_invalid                // Error EL1h
342         kernel_ventry   0, sync                         // Synchronous 64-bit EL0
343         kernel_ventry   0, irq                          // IRQ 64-bit EL0
344         kernel_ventry   0, fiq_invalid                  // FIQ 64-bit EL0
345         kernel_ventry   0, error_invalid                // Error 64-bit EL0
347 #ifdef CONFIG_COMPAT
348         kernel_ventry   0, sync_compat, 32              // Synchronous 32-bit EL0
349         kernel_ventry   0, irq_compat, 32               // IRQ 32-bit EL0
350         kernel_ventry   0, fiq_invalid_compat, 32       // FIQ 32-bit EL0
351         kernel_ventry   0, error_invalid_compat, 32     // Error 32-bit EL0
352 #else
353         kernel_ventry   0, sync_invalid, 32             // Synchronous 32-bit EL0
354         kernel_ventry   0, irq_invalid, 32              // IRQ 32-bit EL0
355         kernel_ventry   0, fiq_invalid, 32              // FIQ 32-bit EL0
356         kernel_ventry   0, error_invalid, 32            // Error 32-bit EL0
357 #endif
358 END(vectors)
361  * Invalid mode handlers
362  */
363         .macro  inv_entry, el, reason, regsize = 64
364         kernel_entry \el, \regsize
365         mov     x0, sp
366         mov     x1, #\reason
367         mrs     x2, esr_el1
368         b       bad_mode
369         .endm
371 el0_sync_invalid:
372         inv_entry 0, BAD_SYNC
373 ENDPROC(el0_sync_invalid)
375 el0_irq_invalid:
376         inv_entry 0, BAD_IRQ
377 ENDPROC(el0_irq_invalid)
379 el0_fiq_invalid:
380         inv_entry 0, BAD_FIQ
381 ENDPROC(el0_fiq_invalid)
383 el0_error_invalid:
384         inv_entry 0, BAD_ERROR
385 ENDPROC(el0_error_invalid)
387 #ifdef CONFIG_COMPAT
388 el0_fiq_invalid_compat:
389         inv_entry 0, BAD_FIQ, 32
390 ENDPROC(el0_fiq_invalid_compat)
392 el0_error_invalid_compat:
393         inv_entry 0, BAD_ERROR, 32
394 ENDPROC(el0_error_invalid_compat)
395 #endif
397 el1_sync_invalid:
398         inv_entry 1, BAD_SYNC
399 ENDPROC(el1_sync_invalid)
401 el1_irq_invalid:
402         inv_entry 1, BAD_IRQ
403 ENDPROC(el1_irq_invalid)
405 el1_fiq_invalid:
406         inv_entry 1, BAD_FIQ
407 ENDPROC(el1_fiq_invalid)
409 el1_error_invalid:
410         inv_entry 1, BAD_ERROR
411 ENDPROC(el1_error_invalid)
414  * EL1 mode handlers.
415  */
416         .align  6
417 el1_sync:
418         kernel_entry 1
419         mrs     x1, esr_el1                     // read the syndrome register
420         lsr     x24, x1, #ESR_ELx_EC_SHIFT      // exception class
421         cmp     x24, #ESR_ELx_EC_DABT_CUR       // data abort in EL1
422         b.eq    el1_da
423         cmp     x24, #ESR_ELx_EC_IABT_CUR       // instruction abort in EL1
424         b.eq    el1_ia
425         cmp     x24, #ESR_ELx_EC_SYS64          // configurable trap
426         b.eq    el1_undef
427         cmp     x24, #ESR_ELx_EC_SP_ALIGN       // stack alignment exception
428         b.eq    el1_sp_pc
429         cmp     x24, #ESR_ELx_EC_PC_ALIGN       // pc alignment exception
430         b.eq    el1_sp_pc
431         cmp     x24, #ESR_ELx_EC_UNKNOWN        // unknown exception in EL1
432         b.eq    el1_undef
433         cmp     x24, #ESR_ELx_EC_BREAKPT_CUR    // debug exception in EL1
434         b.ge    el1_dbg
435         b       el1_inv
437 el1_ia:
438         /*
439          * Fall through to the Data abort case
440          */
441 el1_da:
442         /*
443          * Data abort handling
444          */
445         mrs     x3, far_el1
446         enable_dbg
447         // re-enable interrupts if they were enabled in the aborted context
448         tbnz    x23, #7, 1f                     // PSR_I_BIT
449         enable_irq
451         clear_address_tag x0, x3
452         mov     x2, sp                          // struct pt_regs
453         bl      do_mem_abort
455         // disable interrupts before pulling preserved data off the stack
456         disable_irq
457         kernel_exit 1
458 el1_sp_pc:
459         /*
460          * Stack or PC alignment exception handling
461          */
462         mrs     x0, far_el1
463         enable_dbg
464         mov     x2, sp
465         b       do_sp_pc_abort
466 el1_undef:
467         /*
468          * Undefined instruction
469          */
470         enable_dbg
471         mov     x0, sp
472         b       do_undefinstr
473 el1_dbg:
474         /*
475          * Debug exception handling
476          */
477         cmp     x24, #ESR_ELx_EC_BRK64          // if BRK64
478         cinc    x24, x24, eq                    // set bit '0'
479         tbz     x24, #0, el1_inv                // EL1 only
480         mrs     x0, far_el1
481         mov     x2, sp                          // struct pt_regs
482         bl      do_debug_exception
483         kernel_exit 1
484 el1_inv:
485         // TODO: add support for undefined instructions in kernel mode
486         enable_dbg
487         mov     x0, sp
488         mov     x2, x1
489         mov     x1, #BAD_SYNC
490         b       bad_mode
491 ENDPROC(el1_sync)
493         .align  6
494 el1_irq:
495         kernel_entry 1
496         enable_dbg
497 #ifdef CONFIG_TRACE_IRQFLAGS
498         bl      trace_hardirqs_off
499 #endif
501         irq_handler
503 #ifdef CONFIG_PREEMPT
504         ldr     w24, [tsk, #TI_PREEMPT]         // get preempt count
505         cbnz    w24, 1f                         // preempt count != 0
506         ldr     x0, [tsk, #TI_FLAGS]            // get flags
507         tbz     x0, #TIF_NEED_RESCHED, 1f       // needs rescheduling?
508         bl      el1_preempt
510 #endif
511 #ifdef CONFIG_TRACE_IRQFLAGS
512         bl      trace_hardirqs_on
513 #endif
514         kernel_exit 1
515 ENDPROC(el1_irq)
517 #ifdef CONFIG_PREEMPT
518 el1_preempt:
519         mov     x24, lr
520 1:      bl      preempt_schedule_irq            // irq en/disable is done inside
521         ldr     x0, [tsk, #TI_FLAGS]            // get new tasks TI_FLAGS
522         tbnz    x0, #TIF_NEED_RESCHED, 1b       // needs rescheduling?
523         ret     x24
524 #endif
527  * EL0 mode handlers.
528  */
529         .align  6
530 el0_sync:
531         kernel_entry 0
532         mrs     x25, esr_el1                    // read the syndrome register
533         lsr     x24, x25, #ESR_ELx_EC_SHIFT     // exception class
534         cmp     x24, #ESR_ELx_EC_SVC64          // SVC in 64-bit state
535         b.eq    el0_svc
536         cmp     x24, #ESR_ELx_EC_DABT_LOW       // data abort in EL0
537         b.eq    el0_da
538         cmp     x24, #ESR_ELx_EC_IABT_LOW       // instruction abort in EL0
539         b.eq    el0_ia
540         cmp     x24, #ESR_ELx_EC_FP_ASIMD       // FP/ASIMD access
541         b.eq    el0_fpsimd_acc
542         cmp     x24, #ESR_ELx_EC_FP_EXC64       // FP/ASIMD exception
543         b.eq    el0_fpsimd_exc
544         cmp     x24, #ESR_ELx_EC_SYS64          // configurable trap
545         b.eq    el0_sys
546         cmp     x24, #ESR_ELx_EC_SP_ALIGN       // stack alignment exception
547         b.eq    el0_sp_pc
548         cmp     x24, #ESR_ELx_EC_PC_ALIGN       // pc alignment exception
549         b.eq    el0_sp_pc
550         cmp     x24, #ESR_ELx_EC_UNKNOWN        // unknown exception in EL0
551         b.eq    el0_undef
552         cmp     x24, #ESR_ELx_EC_BREAKPT_LOW    // debug exception in EL0
553         b.ge    el0_dbg
554         b       el0_inv
556 #ifdef CONFIG_COMPAT
557         .align  6
558 el0_sync_compat:
559         kernel_entry 0, 32
560         mrs     x25, esr_el1                    // read the syndrome register
561         lsr     x24, x25, #ESR_ELx_EC_SHIFT     // exception class
562         cmp     x24, #ESR_ELx_EC_SVC32          // SVC in 32-bit state
563         b.eq    el0_svc_compat
564         cmp     x24, #ESR_ELx_EC_DABT_LOW       // data abort in EL0
565         b.eq    el0_da
566         cmp     x24, #ESR_ELx_EC_IABT_LOW       // instruction abort in EL0
567         b.eq    el0_ia
568         cmp     x24, #ESR_ELx_EC_FP_ASIMD       // FP/ASIMD access
569         b.eq    el0_fpsimd_acc
570         cmp     x24, #ESR_ELx_EC_FP_EXC32       // FP/ASIMD exception
571         b.eq    el0_fpsimd_exc
572         cmp     x24, #ESR_ELx_EC_PC_ALIGN       // pc alignment exception
573         b.eq    el0_sp_pc
574         cmp     x24, #ESR_ELx_EC_UNKNOWN        // unknown exception in EL0
575         b.eq    el0_undef
576         cmp     x24, #ESR_ELx_EC_CP15_32        // CP15 MRC/MCR trap
577         b.eq    el0_undef
578         cmp     x24, #ESR_ELx_EC_CP15_64        // CP15 MRRC/MCRR trap
579         b.eq    el0_undef
580         cmp     x24, #ESR_ELx_EC_CP14_MR        // CP14 MRC/MCR trap
581         b.eq    el0_undef
582         cmp     x24, #ESR_ELx_EC_CP14_LS        // CP14 LDC/STC trap
583         b.eq    el0_undef
584         cmp     x24, #ESR_ELx_EC_CP14_64        // CP14 MRRC/MCRR trap
585         b.eq    el0_undef
586         cmp     x24, #ESR_ELx_EC_BREAKPT_LOW    // debug exception in EL0
587         b.ge    el0_dbg
588         b       el0_inv
589 el0_svc_compat:
590         /*
591          * AArch32 syscall handling
592          */
593         adrp    stbl, compat_sys_call_table     // load compat syscall table pointer
594         uxtw    scno, w7                        // syscall number in w7 (r7)
595         mov     sc_nr, #__NR_compat_syscalls
596         b       el0_svc_naked
598         .align  6
599 el0_irq_compat:
600         kernel_entry 0, 32
601         b       el0_irq_naked
602 #endif
604 el0_da:
605         /*
606          * Data abort handling
607          */
608         mrs     x26, far_el1
609         // enable interrupts before calling the main handler
610         enable_dbg_and_irq
611         ct_user_exit
612         clear_address_tag x0, x26
613         mov     x1, x25
614         mov     x2, sp
615         bl      do_mem_abort
616         b       ret_to_user
617 el0_ia:
618         /*
619          * Instruction abort handling
620          */
621         mrs     x26, far_el1
622         msr     daifclr, #(8 | 4 | 1)
623 #ifdef CONFIG_TRACE_IRQFLAGS
624         bl      trace_hardirqs_off
625 #endif
626         ct_user_exit
627         mov     x0, x26
628         mov     x1, x25
629         mov     x2, sp
630         bl      do_el0_ia_bp_hardening
631         b       ret_to_user
632 el0_fpsimd_acc:
633         /*
634          * Floating Point or Advanced SIMD access
635          */
636         enable_dbg
637         ct_user_exit
638         mov     x0, x25
639         mov     x1, sp
640         bl      do_fpsimd_acc
641         b       ret_to_user
642 el0_fpsimd_exc:
643         /*
644          * Floating Point or Advanced SIMD exception
645          */
646         enable_dbg
647         ct_user_exit
648         mov     x0, x25
649         mov     x1, sp
650         bl      do_fpsimd_exc
651         b       ret_to_user
652 el0_sp_pc:
653         /*
654          * Stack or PC alignment exception handling
655          */
656         mrs     x26, far_el1
657         enable_dbg
658 #ifdef CONFIG_TRACE_IRQFLAGS
659         bl      trace_hardirqs_off
660 #endif
661         ct_user_exit
662         mov     x0, x26
663         mov     x1, x25
664         mov     x2, sp
665         bl      do_sp_pc_abort
666         b       ret_to_user
667 el0_undef:
668         /*
669          * Undefined instruction
670          */
671         // enable interrupts before calling the main handler
672         enable_dbg_and_irq
673         ct_user_exit
674         mov     x0, sp
675         bl      do_undefinstr
676         b       ret_to_user
677 el0_sys:
678         /*
679          * System instructions, for trapped cache maintenance instructions
680          */
681         enable_dbg_and_irq
682         ct_user_exit
683         mov     x0, x25
684         mov     x1, sp
685         bl      do_sysinstr
686         b       ret_to_user
687 el0_dbg:
688         /*
689          * Debug exception handling
690          */
691         tbnz    x24, #0, el0_inv                // EL0 only
692         mrs     x0, far_el1
693         mov     x1, x25
694         mov     x2, sp
695         bl      do_debug_exception
696         enable_dbg
697         ct_user_exit
698         b       ret_to_user
699 el0_inv:
700         enable_dbg
701         ct_user_exit
702         mov     x0, sp
703         mov     x1, #BAD_SYNC
704         mov     x2, x25
705         bl      bad_el0_sync
706         b       ret_to_user
707 ENDPROC(el0_sync)
709         .align  6
710 el0_irq:
711         kernel_entry 0
712 el0_irq_naked:
713         enable_dbg
714 #ifdef CONFIG_TRACE_IRQFLAGS
715         bl      trace_hardirqs_off
716 #endif
718         ct_user_exit
719 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
720         tbz     x22, #55, 1f
721         bl      do_el0_irq_bp_hardening
723 #endif
724         irq_handler
726 #ifdef CONFIG_TRACE_IRQFLAGS
727         bl      trace_hardirqs_on
728 #endif
729         b       ret_to_user
730 ENDPROC(el0_irq)
733  * Register switch for AArch64. The callee-saved registers need to be saved
734  * and restored. On entry:
735  *   x0 = previous task_struct (must be preserved across the switch)
736  *   x1 = next task_struct
737  * Previous and next are guaranteed not to be the same.
739  */
740 ENTRY(cpu_switch_to)
741         mov     x10, #THREAD_CPU_CONTEXT
742         add     x8, x0, x10
743         mov     x9, sp
744         stp     x19, x20, [x8], #16             // store callee-saved registers
745         stp     x21, x22, [x8], #16
746         stp     x23, x24, [x8], #16
747         stp     x25, x26, [x8], #16
748         stp     x27, x28, [x8], #16
749         stp     x29, x9, [x8], #16
750         str     lr, [x8]
751         add     x8, x1, x10
752         ldp     x19, x20, [x8], #16             // restore callee-saved registers
753         ldp     x21, x22, [x8], #16
754         ldp     x23, x24, [x8], #16
755         ldp     x25, x26, [x8], #16
756         ldp     x27, x28, [x8], #16
757         ldp     x29, x9, [x8], #16
758         ldr     lr, [x8]
759         mov     sp, x9
760         and     x9, x9, #~(THREAD_SIZE - 1)
761         msr     sp_el0, x9
762         ret
763 ENDPROC(cpu_switch_to)
766  * This is the fast syscall return path.  We do as little as possible here,
767  * and this includes saving x0 back into the kernel stack.
768  */
769 ret_fast_syscall:
770         disable_irq                             // disable interrupts
771         str     x0, [sp, #S_X0]                 // returned x0
772         ldr     x1, [tsk, #TI_FLAGS]            // re-check for syscall tracing
773         and     x2, x1, #_TIF_SYSCALL_WORK
774         cbnz    x2, ret_fast_syscall_trace
775         and     x2, x1, #_TIF_WORK_MASK
776         cbnz    x2, work_pending
777         enable_step_tsk x1, x2
778         kernel_exit 0
779 ret_fast_syscall_trace:
780         enable_irq                              // enable interrupts
781         b       __sys_trace_return_skipped      // we already saved x0
784  * Ok, we need to do extra processing, enter the slow path.
785  */
786 work_pending:
787         mov     x0, sp                          // 'regs'
788         bl      do_notify_resume
789 #ifdef CONFIG_TRACE_IRQFLAGS
790         bl      trace_hardirqs_on               // enabled while in userspace
791 #endif
792         ldr     x1, [tsk, #TI_FLAGS]            // re-check for single-step
793         b       finish_ret_to_user
795  * "slow" syscall return path.
796  */
797 ret_to_user:
798         disable_irq                             // disable interrupts
799         ldr     x1, [tsk, #TI_FLAGS]
800         and     x2, x1, #_TIF_WORK_MASK
801         cbnz    x2, work_pending
802 finish_ret_to_user:
803         enable_step_tsk x1, x2
804         kernel_exit 0
805 ENDPROC(ret_to_user)
808  * This is how we return from a fork.
809  */
810 ENTRY(ret_from_fork)
811         bl      schedule_tail
812         cbz     x19, 1f                         // not a kernel thread
813         mov     x0, x20
814         blr     x19
815 1:      get_thread_info tsk
816         b       ret_to_user
817 ENDPROC(ret_from_fork)
820  * SVC handler.
821  */
822         .align  6
823 el0_svc:
824         adrp    stbl, sys_call_table            // load syscall table pointer
825         uxtw    scno, w8                        // syscall number in w8
826         mov     sc_nr, #__NR_syscalls
827 el0_svc_naked:                                  // compat entry point
828         stp     x0, scno, [sp, #S_ORIG_X0]      // save the original x0 and syscall number
829         enable_dbg_and_irq
830         ct_user_exit 1
832         ldr     x16, [tsk, #TI_FLAGS]           // check for syscall hooks
833         tst     x16, #_TIF_SYSCALL_WORK
834         b.ne    __sys_trace
835         cmp     scno, sc_nr                     // check upper syscall limit
836         b.hs    ni_sys
837         mask_nospec64 scno, sc_nr, x19  // enforce bounds for syscall number
838         ldr     x16, [stbl, scno, lsl #3]       // address in the syscall table
839         blr     x16                             // call sys_* routine
840         b       ret_fast_syscall
841 ni_sys:
842         mov     x0, sp
843         bl      do_ni_syscall
844         b       ret_fast_syscall
845 ENDPROC(el0_svc)
847         /*
848          * This is the really slow path.  We're going to be doing context
849          * switches, and waiting for our parent to respond.
850          */
851 __sys_trace:
852         mov     w0, #-1                         // set default errno for
853         cmp     scno, x0                        // user-issued syscall(-1)
854         b.ne    1f
855         mov     x0, #-ENOSYS
856         str     x0, [sp, #S_X0]
857 1:      mov     x0, sp
858         bl      syscall_trace_enter
859         cmp     w0, #-1                         // skip the syscall?
860         b.eq    __sys_trace_return_skipped
861         uxtw    scno, w0                        // syscall number (possibly new)
862         mov     x1, sp                          // pointer to regs
863         cmp     scno, sc_nr                     // check upper syscall limit
864         b.hs    __ni_sys_trace
865         ldp     x0, x1, [sp]                    // restore the syscall args
866         ldp     x2, x3, [sp, #S_X2]
867         ldp     x4, x5, [sp, #S_X4]
868         ldp     x6, x7, [sp, #S_X6]
869         ldr     x16, [stbl, scno, lsl #3]       // address in the syscall table
870         blr     x16                             // call sys_* routine
872 __sys_trace_return:
873         str     x0, [sp, #S_X0]                 // save returned x0
874 __sys_trace_return_skipped:
875         mov     x0, sp
876         bl      syscall_trace_exit
877         b       ret_to_user
879 __ni_sys_trace:
880         mov     x0, sp
881         bl      do_ni_syscall
882         b       __sys_trace_return
884         .popsection                             // .entry.text
886 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
888  * Exception vectors trampoline.
889  */
890         .pushsection ".entry.tramp.text", "ax"
892         .macro tramp_map_kernel, tmp
893         mrs     \tmp, ttbr1_el1
894         sub     \tmp, \tmp, #SWAPPER_DIR_SIZE
895         bic     \tmp, \tmp, #USER_ASID_FLAG
896         msr     ttbr1_el1, \tmp
897         .endm
899         .macro tramp_unmap_kernel, tmp
900         mrs     \tmp, ttbr1_el1
901         add     \tmp, \tmp, #SWAPPER_DIR_SIZE
902         orr     \tmp, \tmp, #USER_ASID_FLAG
903         msr     ttbr1_el1, \tmp
904         /*
905          * We avoid running the post_ttbr_update_workaround here because
906          * it's only needed by Cavium ThunderX, which requires KPTI to be
907          * disabled.
908          */
909         .endm
911         .macro tramp_ventry, regsize = 64
912         .align  7
914         .if     \regsize == 64
915         msr     tpidrro_el0, x30        // Restored in kernel_ventry
916         .endif
917         /*
918          * Defend against branch aliasing attacks by pushing a dummy
919          * entry onto the return stack and using a RET instruction to
920          * enter the full-fat kernel vectors.
921          */
922         bl      2f
923         b       .
925         tramp_map_kernel        x30
926 #ifdef CONFIG_RANDOMIZE_BASE
927         adr     x30, tramp_vectors + PAGE_SIZE
928         isb
929         ldr     x30, [x30]
930 #else
931         ldr     x30, =vectors
932 #endif
933         prfm    plil1strm, [x30, #(1b - tramp_vectors)]
934         msr     vbar_el1, x30
935         add     x30, x30, #(1b - tramp_vectors)
936         isb
937         ret
938         .endm
940         .macro tramp_exit, regsize = 64
941         adr     x30, tramp_vectors
942         msr     vbar_el1, x30
943         tramp_unmap_kernel      x30
944         .if     \regsize == 64
945         mrs     x30, far_el1
946         .endif
947         eret
948         .endm
950         .align  11
951 ENTRY(tramp_vectors)
952         .space  0x400
954         tramp_ventry
955         tramp_ventry
956         tramp_ventry
957         tramp_ventry
959         tramp_ventry    32
960         tramp_ventry    32
961         tramp_ventry    32
962         tramp_ventry    32
963 END(tramp_vectors)
965 ENTRY(tramp_exit_native)
966         tramp_exit
967 END(tramp_exit_native)
969 ENTRY(tramp_exit_compat)
970         tramp_exit      32
971 END(tramp_exit_compat)
973         .ltorg
974         .popsection                             // .entry.tramp.text
975 #ifdef CONFIG_RANDOMIZE_BASE
976         .pushsection ".rodata", "a"
977         .align PAGE_SHIFT
978         .globl  __entry_tramp_data_start
979 __entry_tramp_data_start:
980         .quad   vectors
981         .popsection                             // .rodata
982 #endif /* CONFIG_RANDOMIZE_BASE */
983 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
986  * Special system call wrappers.
987  */
988 ENTRY(sys_rt_sigreturn_wrapper)
989         mov     x0, sp
990         b       sys_rt_sigreturn
991 ENDPROC(sys_rt_sigreturn_wrapper)