xref: /OK3568_Linux_fs/kernel/arch/arm64/include/asm/traps.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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