arm64: entry: fix NMI {user, kernel}->kernel transitions
[linux-2.6-microblaze.git] / arch / arm64 / kernel / entry-common.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Exception handling code
4  *
5  * Copyright (C) 2019 ARM Ltd.
6  */
7
8 #include <linux/context_tracking.h>
9 #include <linux/ptrace.h>
10 #include <linux/thread_info.h>
11
12 #include <asm/cpufeature.h>
13 #include <asm/daifflags.h>
14 #include <asm/esr.h>
15 #include <asm/exception.h>
16 #include <asm/kprobes.h>
17 #include <asm/mmu.h>
18 #include <asm/sysreg.h>
19
20 /*
21  * This is intended to match the logic in irqentry_enter(), handling the kernel
22  * mode transitions only.
23  */
24 static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
25 {
26         regs->exit_rcu = false;
27
28         if (!IS_ENABLED(CONFIG_TINY_RCU) && is_idle_task(current)) {
29                 lockdep_hardirqs_off(CALLER_ADDR0);
30                 rcu_irq_enter();
31                 trace_hardirqs_off_finish();
32
33                 regs->exit_rcu = true;
34                 return;
35         }
36
37         lockdep_hardirqs_off(CALLER_ADDR0);
38         rcu_irq_enter_check_tick();
39         trace_hardirqs_off_finish();
40 }
41
42 /*
43  * This is intended to match the logic in irqentry_exit(), handling the kernel
44  * mode transitions only, and with preemption handled elsewhere.
45  */
46 static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
47 {
48         lockdep_assert_irqs_disabled();
49
50         if (interrupts_enabled(regs)) {
51                 if (regs->exit_rcu) {
52                         trace_hardirqs_on_prepare();
53                         lockdep_hardirqs_on_prepare(CALLER_ADDR0);
54                         rcu_irq_exit();
55                         lockdep_hardirqs_on(CALLER_ADDR0);
56                         return;
57                 }
58
59                 trace_hardirqs_on();
60         } else {
61                 if (regs->exit_rcu)
62                         rcu_irq_exit();
63         }
64 }
65
66 void noinstr arm64_enter_nmi(struct pt_regs *regs)
67 {
68         regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
69
70         __nmi_enter();
71         lockdep_hardirqs_off(CALLER_ADDR0);
72         lockdep_hardirq_enter();
73         rcu_nmi_enter();
74
75         trace_hardirqs_off_finish();
76         ftrace_nmi_enter();
77 }
78
79 void noinstr arm64_exit_nmi(struct pt_regs *regs)
80 {
81         bool restore = regs->lockdep_hardirqs;
82
83         ftrace_nmi_exit();
84         if (restore) {
85                 trace_hardirqs_on_prepare();
86                 lockdep_hardirqs_on_prepare(CALLER_ADDR0);
87         }
88
89         rcu_nmi_exit();
90         lockdep_hardirq_exit();
91         if (restore)
92                 lockdep_hardirqs_on(CALLER_ADDR0);
93         __nmi_exit();
94 }
95
96 asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs)
97 {
98         if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
99                 arm64_enter_nmi(regs);
100         else
101                 enter_from_kernel_mode(regs);
102 }
103
104 asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs)
105 {
106         if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
107                 arm64_exit_nmi(regs);
108         else
109                 exit_to_kernel_mode(regs);
110 }
111
112 static void noinstr el1_abort(struct pt_regs *regs, unsigned long esr)
113 {
114         unsigned long far = read_sysreg(far_el1);
115
116         enter_from_kernel_mode(regs);
117         local_daif_inherit(regs);
118         far = untagged_addr(far);
119         do_mem_abort(far, esr, regs);
120         local_daif_mask();
121         exit_to_kernel_mode(regs);
122 }
123
124 static void noinstr el1_pc(struct pt_regs *regs, unsigned long esr)
125 {
126         unsigned long far = read_sysreg(far_el1);
127
128         enter_from_kernel_mode(regs);
129         local_daif_inherit(regs);
130         do_sp_pc_abort(far, esr, regs);
131         local_daif_mask();
132         exit_to_kernel_mode(regs);
133 }
134
135 static void noinstr el1_undef(struct pt_regs *regs)
136 {
137         enter_from_kernel_mode(regs);
138         local_daif_inherit(regs);
139         do_undefinstr(regs);
140         local_daif_mask();
141         exit_to_kernel_mode(regs);
142 }
143
144 static void noinstr el1_inv(struct pt_regs *regs, unsigned long esr)
145 {
146         enter_from_kernel_mode(regs);
147         local_daif_inherit(regs);
148         bad_mode(regs, 0, esr);
149         local_daif_mask();
150         exit_to_kernel_mode(regs);
151 }
152
153 static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr)
154 {
155         unsigned long far = read_sysreg(far_el1);
156
157         /*
158          * The CPU masked interrupts, and we are leaving them masked during
159          * do_debug_exception(). Update PMR as if we had called
160          * local_daif_mask().
161          */
162         if (system_uses_irq_prio_masking())
163                 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
164
165         do_debug_exception(far, esr, regs);
166 }
167
168 static void noinstr el1_fpac(struct pt_regs *regs, unsigned long esr)
169 {
170         enter_from_kernel_mode(regs);
171         local_daif_inherit(regs);
172         do_ptrauth_fault(regs, esr);
173         local_daif_mask();
174         exit_to_kernel_mode(regs);
175 }
176
177 asmlinkage void noinstr el1_sync_handler(struct pt_regs *regs)
178 {
179         unsigned long esr = read_sysreg(esr_el1);
180
181         switch (ESR_ELx_EC(esr)) {
182         case ESR_ELx_EC_DABT_CUR:
183         case ESR_ELx_EC_IABT_CUR:
184                 el1_abort(regs, esr);
185                 break;
186         /*
187          * We don't handle ESR_ELx_EC_SP_ALIGN, since we will have hit a
188          * recursive exception when trying to push the initial pt_regs.
189          */
190         case ESR_ELx_EC_PC_ALIGN:
191                 el1_pc(regs, esr);
192                 break;
193         case ESR_ELx_EC_SYS64:
194         case ESR_ELx_EC_UNKNOWN:
195                 el1_undef(regs);
196                 break;
197         case ESR_ELx_EC_BREAKPT_CUR:
198         case ESR_ELx_EC_SOFTSTP_CUR:
199         case ESR_ELx_EC_WATCHPT_CUR:
200         case ESR_ELx_EC_BRK64:
201                 el1_dbg(regs, esr);
202                 break;
203         case ESR_ELx_EC_FPAC:
204                 el1_fpac(regs, esr);
205                 break;
206         default:
207                 el1_inv(regs, esr);
208         }
209 }
210
211 asmlinkage void noinstr enter_from_user_mode(void)
212 {
213         lockdep_hardirqs_off(CALLER_ADDR0);
214         CT_WARN_ON(ct_state() != CONTEXT_USER);
215         user_exit_irqoff();
216         trace_hardirqs_off_finish();
217 }
218
219 asmlinkage void noinstr exit_to_user_mode(void)
220 {
221         trace_hardirqs_on_prepare();
222         lockdep_hardirqs_on_prepare(CALLER_ADDR0);
223         user_enter_irqoff();
224         lockdep_hardirqs_on(CALLER_ADDR0);
225 }
226
227 static void noinstr el0_da(struct pt_regs *regs, unsigned long esr)
228 {
229         unsigned long far = read_sysreg(far_el1);
230
231         enter_from_user_mode();
232         local_daif_restore(DAIF_PROCCTX);
233         far = untagged_addr(far);
234         do_mem_abort(far, esr, regs);
235 }
236
237 static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr)
238 {
239         unsigned long far = read_sysreg(far_el1);
240
241         /*
242          * We've taken an instruction abort from userspace and not yet
243          * re-enabled IRQs. If the address is a kernel address, apply
244          * BP hardening prior to enabling IRQs and pre-emption.
245          */
246         if (!is_ttbr0_addr(far))
247                 arm64_apply_bp_hardening();
248
249         enter_from_user_mode();
250         local_daif_restore(DAIF_PROCCTX);
251         do_mem_abort(far, esr, regs);
252 }
253
254 static void noinstr el0_fpsimd_acc(struct pt_regs *regs, unsigned long esr)
255 {
256         enter_from_user_mode();
257         local_daif_restore(DAIF_PROCCTX);
258         do_fpsimd_acc(esr, regs);
259 }
260
261 static void noinstr el0_sve_acc(struct pt_regs *regs, unsigned long esr)
262 {
263         enter_from_user_mode();
264         local_daif_restore(DAIF_PROCCTX);
265         do_sve_acc(esr, regs);
266 }
267
268 static void noinstr el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
269 {
270         enter_from_user_mode();
271         local_daif_restore(DAIF_PROCCTX);
272         do_fpsimd_exc(esr, regs);
273 }
274
275 static void noinstr el0_sys(struct pt_regs *regs, unsigned long esr)
276 {
277         enter_from_user_mode();
278         local_daif_restore(DAIF_PROCCTX);
279         do_sysinstr(esr, regs);
280 }
281
282 static void noinstr el0_pc(struct pt_regs *regs, unsigned long esr)
283 {
284         unsigned long far = read_sysreg(far_el1);
285
286         if (!is_ttbr0_addr(instruction_pointer(regs)))
287                 arm64_apply_bp_hardening();
288
289         enter_from_user_mode();
290         local_daif_restore(DAIF_PROCCTX);
291         do_sp_pc_abort(far, esr, regs);
292 }
293
294 static void noinstr el0_sp(struct pt_regs *regs, unsigned long esr)
295 {
296         enter_from_user_mode();
297         local_daif_restore(DAIF_PROCCTX);
298         do_sp_pc_abort(regs->sp, esr, regs);
299 }
300
301 static void noinstr el0_undef(struct pt_regs *regs)
302 {
303         enter_from_user_mode();
304         local_daif_restore(DAIF_PROCCTX);
305         do_undefinstr(regs);
306 }
307
308 static void noinstr el0_bti(struct pt_regs *regs)
309 {
310         enter_from_user_mode();
311         local_daif_restore(DAIF_PROCCTX);
312         do_bti(regs);
313 }
314
315 static void noinstr el0_inv(struct pt_regs *regs, unsigned long esr)
316 {
317         enter_from_user_mode();
318         local_daif_restore(DAIF_PROCCTX);
319         bad_el0_sync(regs, 0, esr);
320 }
321
322 static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
323 {
324         /* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */
325         unsigned long far = read_sysreg(far_el1);
326
327         if (system_uses_irq_prio_masking())
328                 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
329
330         enter_from_user_mode();
331         do_debug_exception(far, esr, regs);
332         local_daif_restore(DAIF_PROCCTX_NOIRQ);
333 }
334
335 static void noinstr el0_svc(struct pt_regs *regs)
336 {
337         if (system_uses_irq_prio_masking())
338                 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
339
340         enter_from_user_mode();
341         do_el0_svc(regs);
342 }
343
344 static void noinstr el0_fpac(struct pt_regs *regs, unsigned long esr)
345 {
346         enter_from_user_mode();
347         local_daif_restore(DAIF_PROCCTX);
348         do_ptrauth_fault(regs, esr);
349 }
350
351 asmlinkage void noinstr el0_sync_handler(struct pt_regs *regs)
352 {
353         unsigned long esr = read_sysreg(esr_el1);
354
355         switch (ESR_ELx_EC(esr)) {
356         case ESR_ELx_EC_SVC64:
357                 el0_svc(regs);
358                 break;
359         case ESR_ELx_EC_DABT_LOW:
360                 el0_da(regs, esr);
361                 break;
362         case ESR_ELx_EC_IABT_LOW:
363                 el0_ia(regs, esr);
364                 break;
365         case ESR_ELx_EC_FP_ASIMD:
366                 el0_fpsimd_acc(regs, esr);
367                 break;
368         case ESR_ELx_EC_SVE:
369                 el0_sve_acc(regs, esr);
370                 break;
371         case ESR_ELx_EC_FP_EXC64:
372                 el0_fpsimd_exc(regs, esr);
373                 break;
374         case ESR_ELx_EC_SYS64:
375         case ESR_ELx_EC_WFx:
376                 el0_sys(regs, esr);
377                 break;
378         case ESR_ELx_EC_SP_ALIGN:
379                 el0_sp(regs, esr);
380                 break;
381         case ESR_ELx_EC_PC_ALIGN:
382                 el0_pc(regs, esr);
383                 break;
384         case ESR_ELx_EC_UNKNOWN:
385                 el0_undef(regs);
386                 break;
387         case ESR_ELx_EC_BTI:
388                 el0_bti(regs);
389                 break;
390         case ESR_ELx_EC_BREAKPT_LOW:
391         case ESR_ELx_EC_SOFTSTP_LOW:
392         case ESR_ELx_EC_WATCHPT_LOW:
393         case ESR_ELx_EC_BRK64:
394                 el0_dbg(regs, esr);
395                 break;
396         case ESR_ELx_EC_FPAC:
397                 el0_fpac(regs, esr);
398                 break;
399         default:
400                 el0_inv(regs, esr);
401         }
402 }
403
404 #ifdef CONFIG_COMPAT
405 static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
406 {
407         enter_from_user_mode();
408         local_daif_restore(DAIF_PROCCTX);
409         do_cp15instr(esr, regs);
410 }
411
412 static void noinstr el0_svc_compat(struct pt_regs *regs)
413 {
414         if (system_uses_irq_prio_masking())
415                 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
416
417         enter_from_user_mode();
418         do_el0_svc_compat(regs);
419 }
420
421 asmlinkage void noinstr el0_sync_compat_handler(struct pt_regs *regs)
422 {
423         unsigned long esr = read_sysreg(esr_el1);
424
425         switch (ESR_ELx_EC(esr)) {
426         case ESR_ELx_EC_SVC32:
427                 el0_svc_compat(regs);
428                 break;
429         case ESR_ELx_EC_DABT_LOW:
430                 el0_da(regs, esr);
431                 break;
432         case ESR_ELx_EC_IABT_LOW:
433                 el0_ia(regs, esr);
434                 break;
435         case ESR_ELx_EC_FP_ASIMD:
436                 el0_fpsimd_acc(regs, esr);
437                 break;
438         case ESR_ELx_EC_FP_EXC32:
439                 el0_fpsimd_exc(regs, esr);
440                 break;
441         case ESR_ELx_EC_PC_ALIGN:
442                 el0_pc(regs, esr);
443                 break;
444         case ESR_ELx_EC_UNKNOWN:
445         case ESR_ELx_EC_CP14_MR:
446         case ESR_ELx_EC_CP14_LS:
447         case ESR_ELx_EC_CP14_64:
448                 el0_undef(regs);
449                 break;
450         case ESR_ELx_EC_CP15_32:
451         case ESR_ELx_EC_CP15_64:
452                 el0_cp15(regs, esr);
453                 break;
454         case ESR_ELx_EC_BREAKPT_LOW:
455         case ESR_ELx_EC_SOFTSTP_LOW:
456         case ESR_ELx_EC_WATCHPT_LOW:
457         case ESR_ELx_EC_BKPT32:
458                 el0_dbg(regs, esr);
459                 break;
460         default:
461                 el0_inv(regs, esr);
462         }
463 }
464 #endif /* CONFIG_COMPAT */