OSDN Git Service

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