1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Based on arch/arm/include/asm/traps.h
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2012 ARM Ltd.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun #ifndef __ASM_TRAP_H
8*4882a593Smuzhiyun #define __ASM_TRAP_H
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/list.h>
11*4882a593Smuzhiyun #include <asm/esr.h>
12*4882a593Smuzhiyun #include <asm/sections.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun struct pt_regs;
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun struct undef_hook {
17*4882a593Smuzhiyun struct list_head node;
18*4882a593Smuzhiyun u32 instr_mask;
19*4882a593Smuzhiyun u32 instr_val;
20*4882a593Smuzhiyun u64 pstate_mask;
21*4882a593Smuzhiyun u64 pstate_val;
22*4882a593Smuzhiyun int (*fn)(struct pt_regs *regs, u32 instr);
23*4882a593Smuzhiyun };
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun void register_undef_hook(struct undef_hook *hook);
26*4882a593Smuzhiyun void unregister_undef_hook(struct undef_hook *hook);
27*4882a593Smuzhiyun void force_signal_inject(int signal, int code, unsigned long address, unsigned int err);
28*4882a593Smuzhiyun void arm64_notify_segfault(unsigned long addr);
29*4882a593Smuzhiyun void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str);
30*4882a593Smuzhiyun void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str);
31*4882a593Smuzhiyun void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str);
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun /*
34*4882a593Smuzhiyun * Move regs->pc to next instruction and do necessary setup before it
35*4882a593Smuzhiyun * is executed.
36*4882a593Smuzhiyun */
37*4882a593Smuzhiyun void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size);
38*4882a593Smuzhiyun
__in_irqentry_text(unsigned long ptr)39*4882a593Smuzhiyun static inline int __in_irqentry_text(unsigned long ptr)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun return ptr >= (unsigned long)&__irqentry_text_start &&
42*4882a593Smuzhiyun ptr < (unsigned long)&__irqentry_text_end;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun
in_entry_text(unsigned long ptr)45*4882a593Smuzhiyun static inline int in_entry_text(unsigned long ptr)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun return ptr >= (unsigned long)&__entry_text_start &&
48*4882a593Smuzhiyun ptr < (unsigned long)&__entry_text_end;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /*
52*4882a593Smuzhiyun * CPUs with the RAS extensions have an Implementation-Defined-Syndrome bit
53*4882a593Smuzhiyun * to indicate whether this ESR has a RAS encoding. CPUs without this feature
54*4882a593Smuzhiyun * have a ISS-Valid bit in the same position.
55*4882a593Smuzhiyun * If this bit is set, we know its not a RAS SError.
56*4882a593Smuzhiyun * If its clear, we need to know if the CPU supports RAS. Uncategorized RAS
57*4882a593Smuzhiyun * errors share the same encoding as an all-zeros encoding from a CPU that
58*4882a593Smuzhiyun * doesn't support RAS.
59*4882a593Smuzhiyun */
arm64_is_ras_serror(u32 esr)60*4882a593Smuzhiyun static inline bool arm64_is_ras_serror(u32 esr)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun WARN_ON(preemptible());
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun if (esr & ESR_ELx_IDS)
65*4882a593Smuzhiyun return false;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN))
68*4882a593Smuzhiyun return true;
69*4882a593Smuzhiyun else
70*4882a593Smuzhiyun return false;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun * Return the AET bits from a RAS SError's ESR.
75*4882a593Smuzhiyun *
76*4882a593Smuzhiyun * It is implementation defined whether Uncategorized errors are containable.
77*4882a593Smuzhiyun * We treat them as Uncontainable.
78*4882a593Smuzhiyun * Non-RAS SError's are reported as Uncontained/Uncategorized.
79*4882a593Smuzhiyun */
arm64_ras_serror_get_severity(u32 esr)80*4882a593Smuzhiyun static inline u32 arm64_ras_serror_get_severity(u32 esr)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun u32 aet = esr & ESR_ELx_AET;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun if (!arm64_is_ras_serror(esr)) {
85*4882a593Smuzhiyun /* Not a RAS error, we can't interpret the ESR. */
86*4882a593Smuzhiyun return ESR_ELx_AET_UC;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /*
90*4882a593Smuzhiyun * AET is RES0 if 'the value returned in the DFSC field is not
91*4882a593Smuzhiyun * [ESR_ELx_FSC_SERROR]'
92*4882a593Smuzhiyun */
93*4882a593Smuzhiyun if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
94*4882a593Smuzhiyun /* No severity information : Uncategorized */
95*4882a593Smuzhiyun return ESR_ELx_AET_UC;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun return aet;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr);
102*4882a593Smuzhiyun void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
103*4882a593Smuzhiyun #endif
104