1 // SPDX-License-Identifier: GPL-2.0
3 * Exception handling code
5 * Copyright (C) 2019 ARM Ltd.
8 #include <linux/context_tracking.h>
9 #include <linux/ptrace.h>
10 #include <linux/thread_info.h>
12 #include <asm/cpufeature.h>
13 #include <asm/daifflags.h>
15 #include <asm/exception.h>
16 #include <asm/kprobes.h>
18 #include <asm/sysreg.h>
20 static void notrace el1_abort(struct pt_regs *regs, unsigned long esr)
22 unsigned long far = read_sysreg(far_el1);
24 local_daif_inherit(regs);
25 far = untagged_addr(far);
26 do_mem_abort(far, esr, regs);
28 NOKPROBE_SYMBOL(el1_abort);
30 static void notrace el1_pc(struct pt_regs *regs, unsigned long esr)
32 unsigned long far = read_sysreg(far_el1);
34 local_daif_inherit(regs);
35 do_sp_pc_abort(far, esr, regs);
37 NOKPROBE_SYMBOL(el1_pc);
39 static void notrace el1_undef(struct pt_regs *regs)
41 local_daif_inherit(regs);
44 NOKPROBE_SYMBOL(el1_undef);
46 static void notrace el1_inv(struct pt_regs *regs, unsigned long esr)
48 local_daif_inherit(regs);
49 bad_mode(regs, 0, esr);
51 NOKPROBE_SYMBOL(el1_inv);
53 static void notrace el1_dbg(struct pt_regs *regs, unsigned long esr)
55 unsigned long far = read_sysreg(far_el1);
58 * The CPU masked interrupts, and we are leaving them masked during
59 * do_debug_exception(). Update PMR as if we had called
62 if (system_uses_irq_prio_masking())
63 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
65 do_debug_exception(far, esr, regs);
67 NOKPROBE_SYMBOL(el1_dbg);
69 static void notrace el1_fpac(struct pt_regs *regs, unsigned long esr)
71 local_daif_inherit(regs);
72 do_ptrauth_fault(regs, esr);
74 NOKPROBE_SYMBOL(el1_fpac);
76 asmlinkage void notrace el1_sync_handler(struct pt_regs *regs)
78 unsigned long esr = read_sysreg(esr_el1);
80 switch (ESR_ELx_EC(esr)) {
81 case ESR_ELx_EC_DABT_CUR:
82 case ESR_ELx_EC_IABT_CUR:
86 * We don't handle ESR_ELx_EC_SP_ALIGN, since we will have hit a
87 * recursive exception when trying to push the initial pt_regs.
89 case ESR_ELx_EC_PC_ALIGN:
92 case ESR_ELx_EC_SYS64:
93 case ESR_ELx_EC_UNKNOWN:
96 case ESR_ELx_EC_BREAKPT_CUR:
97 case ESR_ELx_EC_SOFTSTP_CUR:
98 case ESR_ELx_EC_WATCHPT_CUR:
99 case ESR_ELx_EC_BRK64:
102 case ESR_ELx_EC_FPAC:
109 NOKPROBE_SYMBOL(el1_sync_handler);
111 static void notrace el0_da(struct pt_regs *regs, unsigned long esr)
113 unsigned long far = read_sysreg(far_el1);
116 local_daif_restore(DAIF_PROCCTX);
117 far = untagged_addr(far);
118 do_mem_abort(far, esr, regs);
120 NOKPROBE_SYMBOL(el0_da);
122 static void notrace el0_ia(struct pt_regs *regs, unsigned long esr)
124 unsigned long far = read_sysreg(far_el1);
127 * We've taken an instruction abort from userspace and not yet
128 * re-enabled IRQs. If the address is a kernel address, apply
129 * BP hardening prior to enabling IRQs and pre-emption.
131 if (!is_ttbr0_addr(far))
132 arm64_apply_bp_hardening();
135 local_daif_restore(DAIF_PROCCTX);
136 do_mem_abort(far, esr, regs);
138 NOKPROBE_SYMBOL(el0_ia);
140 static void notrace el0_fpsimd_acc(struct pt_regs *regs, unsigned long esr)
143 local_daif_restore(DAIF_PROCCTX);
144 do_fpsimd_acc(esr, regs);
146 NOKPROBE_SYMBOL(el0_fpsimd_acc);
148 static void notrace el0_sve_acc(struct pt_regs *regs, unsigned long esr)
151 local_daif_restore(DAIF_PROCCTX);
152 do_sve_acc(esr, regs);
154 NOKPROBE_SYMBOL(el0_sve_acc);
156 static void notrace el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
159 local_daif_restore(DAIF_PROCCTX);
160 do_fpsimd_exc(esr, regs);
162 NOKPROBE_SYMBOL(el0_fpsimd_exc);
164 static void notrace el0_sys(struct pt_regs *regs, unsigned long esr)
167 local_daif_restore(DAIF_PROCCTX);
168 do_sysinstr(esr, regs);
170 NOKPROBE_SYMBOL(el0_sys);
172 static void notrace el0_pc(struct pt_regs *regs, unsigned long esr)
174 unsigned long far = read_sysreg(far_el1);
176 if (!is_ttbr0_addr(instruction_pointer(regs)))
177 arm64_apply_bp_hardening();
180 local_daif_restore(DAIF_PROCCTX);
181 do_sp_pc_abort(far, esr, regs);
183 NOKPROBE_SYMBOL(el0_pc);
185 static void notrace el0_sp(struct pt_regs *regs, unsigned long esr)
188 local_daif_restore(DAIF_PROCCTX);
189 do_sp_pc_abort(regs->sp, esr, regs);
191 NOKPROBE_SYMBOL(el0_sp);
193 static void notrace el0_undef(struct pt_regs *regs)
196 local_daif_restore(DAIF_PROCCTX);
199 NOKPROBE_SYMBOL(el0_undef);
201 static void notrace el0_bti(struct pt_regs *regs)
204 local_daif_restore(DAIF_PROCCTX);
207 NOKPROBE_SYMBOL(el0_bti);
209 static void notrace el0_inv(struct pt_regs *regs, unsigned long esr)
212 local_daif_restore(DAIF_PROCCTX);
213 bad_el0_sync(regs, 0, esr);
215 NOKPROBE_SYMBOL(el0_inv);
217 static void notrace el0_dbg(struct pt_regs *regs, unsigned long esr)
219 /* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */
220 unsigned long far = read_sysreg(far_el1);
222 if (system_uses_irq_prio_masking())
223 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
226 do_debug_exception(far, esr, regs);
227 local_daif_restore(DAIF_PROCCTX_NOIRQ);
229 NOKPROBE_SYMBOL(el0_dbg);
231 static void notrace el0_svc(struct pt_regs *regs)
233 if (system_uses_irq_prio_masking())
234 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
238 NOKPROBE_SYMBOL(el0_svc);
240 static void notrace el0_fpac(struct pt_regs *regs, unsigned long esr)
243 local_daif_restore(DAIF_PROCCTX);
244 do_ptrauth_fault(regs, esr);
246 NOKPROBE_SYMBOL(el0_fpac);
248 asmlinkage void notrace el0_sync_handler(struct pt_regs *regs)
250 unsigned long esr = read_sysreg(esr_el1);
252 switch (ESR_ELx_EC(esr)) {
253 case ESR_ELx_EC_SVC64:
256 case ESR_ELx_EC_DABT_LOW:
259 case ESR_ELx_EC_IABT_LOW:
262 case ESR_ELx_EC_FP_ASIMD:
263 el0_fpsimd_acc(regs, esr);
266 el0_sve_acc(regs, esr);
268 case ESR_ELx_EC_FP_EXC64:
269 el0_fpsimd_exc(regs, esr);
271 case ESR_ELx_EC_SYS64:
275 case ESR_ELx_EC_SP_ALIGN:
278 case ESR_ELx_EC_PC_ALIGN:
281 case ESR_ELx_EC_UNKNOWN:
287 case ESR_ELx_EC_BREAKPT_LOW:
288 case ESR_ELx_EC_SOFTSTP_LOW:
289 case ESR_ELx_EC_WATCHPT_LOW:
290 case ESR_ELx_EC_BRK64:
293 case ESR_ELx_EC_FPAC:
300 NOKPROBE_SYMBOL(el0_sync_handler);
303 static void notrace el0_cp15(struct pt_regs *regs, unsigned long esr)
306 local_daif_restore(DAIF_PROCCTX);
307 do_cp15instr(esr, regs);
309 NOKPROBE_SYMBOL(el0_cp15);
311 static void notrace el0_svc_compat(struct pt_regs *regs)
313 if (system_uses_irq_prio_masking())
314 gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
316 do_el0_svc_compat(regs);
318 NOKPROBE_SYMBOL(el0_svc_compat);
320 asmlinkage void notrace el0_sync_compat_handler(struct pt_regs *regs)
322 unsigned long esr = read_sysreg(esr_el1);
324 switch (ESR_ELx_EC(esr)) {
325 case ESR_ELx_EC_SVC32:
326 el0_svc_compat(regs);
328 case ESR_ELx_EC_DABT_LOW:
331 case ESR_ELx_EC_IABT_LOW:
334 case ESR_ELx_EC_FP_ASIMD:
335 el0_fpsimd_acc(regs, esr);
337 case ESR_ELx_EC_FP_EXC32:
338 el0_fpsimd_exc(regs, esr);
340 case ESR_ELx_EC_PC_ALIGN:
343 case ESR_ELx_EC_UNKNOWN:
344 case ESR_ELx_EC_CP14_MR:
345 case ESR_ELx_EC_CP14_LS:
346 case ESR_ELx_EC_CP14_64:
349 case ESR_ELx_EC_CP15_32:
350 case ESR_ELx_EC_CP15_64:
353 case ESR_ELx_EC_BREAKPT_LOW:
354 case ESR_ELx_EC_SOFTSTP_LOW:
355 case ESR_ELx_EC_WATCHPT_LOW:
356 case ESR_ELx_EC_BKPT32:
363 NOKPROBE_SYMBOL(el0_sync_compat_handler);
364 #endif /* CONFIG_COMPAT */