xref: /openbmc/linux/arch/arm64/include/asm/traps.h (revision 6bf0dcfd)
160ffc30dSCatalin Marinas /*
260ffc30dSCatalin Marinas  * Based on arch/arm/include/asm/traps.h
360ffc30dSCatalin Marinas  *
460ffc30dSCatalin Marinas  * Copyright (C) 2012 ARM Ltd.
560ffc30dSCatalin Marinas  *
660ffc30dSCatalin Marinas  * This program is free software; you can redistribute it and/or modify
760ffc30dSCatalin Marinas  * it under the terms of the GNU General Public License version 2 as
860ffc30dSCatalin Marinas  * published by the Free Software Foundation.
960ffc30dSCatalin Marinas  *
1060ffc30dSCatalin Marinas  * This program is distributed in the hope that it will be useful,
1160ffc30dSCatalin Marinas  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1260ffc30dSCatalin Marinas  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1360ffc30dSCatalin Marinas  * GNU General Public License for more details.
1460ffc30dSCatalin Marinas  *
1560ffc30dSCatalin Marinas  * You should have received a copy of the GNU General Public License
1660ffc30dSCatalin Marinas  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1760ffc30dSCatalin Marinas  */
1860ffc30dSCatalin Marinas #ifndef __ASM_TRAP_H
1960ffc30dSCatalin Marinas #define __ASM_TRAP_H
2060ffc30dSCatalin Marinas 
219b79f52dSPunit Agrawal #include <linux/list.h>
226bf0dcfdSJames Morse #include <asm/esr.h>
23ee78fdc7SJames Morse #include <asm/sections.h>
249b79f52dSPunit Agrawal 
259b79f52dSPunit Agrawal struct pt_regs;
269b79f52dSPunit Agrawal 
279b79f52dSPunit Agrawal struct undef_hook {
289b79f52dSPunit Agrawal 	struct list_head node;
299b79f52dSPunit Agrawal 	u32 instr_mask;
309b79f52dSPunit Agrawal 	u32 instr_val;
319b79f52dSPunit Agrawal 	u64 pstate_mask;
329b79f52dSPunit Agrawal 	u64 pstate_val;
339b79f52dSPunit Agrawal 	int (*fn)(struct pt_regs *regs, u32 instr);
349b79f52dSPunit Agrawal };
359b79f52dSPunit Agrawal 
369b79f52dSPunit Agrawal void register_undef_hook(struct undef_hook *hook);
379b79f52dSPunit Agrawal void unregister_undef_hook(struct undef_hook *hook);
38bc0ee476SDave Martin void force_signal_inject(int signal, int code, struct pt_regs *regs,
39bc0ee476SDave Martin 			 unsigned long address);
409b79f52dSPunit Agrawal 
41390bf177SAndre Przywara void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr);
42390bf177SAndre Przywara 
436436beeeSJulien Thierry /*
446436beeeSJulien Thierry  * Move regs->pc to next instruction and do necessary setup before it
456436beeeSJulien Thierry  * is executed.
466436beeeSJulien Thierry  */
476436beeeSJulien Thierry void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size);
486436beeeSJulien Thierry 
499a5ad7d0SJungseok Lee static inline int __in_irqentry_text(unsigned long ptr)
509a5ad7d0SJungseok Lee {
519a5ad7d0SJungseok Lee 	return ptr >= (unsigned long)&__irqentry_text_start &&
529a5ad7d0SJungseok Lee 	       ptr < (unsigned long)&__irqentry_text_end;
539a5ad7d0SJungseok Lee }
549a5ad7d0SJungseok Lee 
5560ffc30dSCatalin Marinas static inline int in_exception_text(unsigned long ptr)
5660ffc30dSCatalin Marinas {
579a5ad7d0SJungseok Lee 	int in;
5860ffc30dSCatalin Marinas 
599a5ad7d0SJungseok Lee 	in = ptr >= (unsigned long)&__exception_text_start &&
6060ffc30dSCatalin Marinas 	     ptr < (unsigned long)&__exception_text_end;
619a5ad7d0SJungseok Lee 
629a5ad7d0SJungseok Lee 	return in ? : __in_irqentry_text(ptr);
6360ffc30dSCatalin Marinas }
6460ffc30dSCatalin Marinas 
6573267498SArd Biesheuvel static inline int in_entry_text(unsigned long ptr)
6673267498SArd Biesheuvel {
6773267498SArd Biesheuvel 	return ptr >= (unsigned long)&__entry_text_start &&
6873267498SArd Biesheuvel 	       ptr < (unsigned long)&__entry_text_end;
6973267498SArd Biesheuvel }
706bf0dcfdSJames Morse 
716bf0dcfdSJames Morse /*
726bf0dcfdSJames Morse  * CPUs with the RAS extensions have an Implementation-Defined-Syndrome bit
736bf0dcfdSJames Morse  * to indicate whether this ESR has a RAS encoding. CPUs without this feature
746bf0dcfdSJames Morse  * have a ISS-Valid bit in the same position.
756bf0dcfdSJames Morse  * If this bit is set, we know its not a RAS SError.
766bf0dcfdSJames Morse  * If its clear, we need to know if the CPU supports RAS. Uncategorized RAS
776bf0dcfdSJames Morse  * errors share the same encoding as an all-zeros encoding from a CPU that
786bf0dcfdSJames Morse  * doesn't support RAS.
796bf0dcfdSJames Morse  */
806bf0dcfdSJames Morse static inline bool arm64_is_ras_serror(u32 esr)
816bf0dcfdSJames Morse {
826bf0dcfdSJames Morse 	WARN_ON(preemptible());
836bf0dcfdSJames Morse 
846bf0dcfdSJames Morse 	if (esr & ESR_ELx_IDS)
856bf0dcfdSJames Morse 		return false;
866bf0dcfdSJames Morse 
876bf0dcfdSJames Morse 	if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN))
886bf0dcfdSJames Morse 		return true;
896bf0dcfdSJames Morse 	else
906bf0dcfdSJames Morse 		return false;
916bf0dcfdSJames Morse }
926bf0dcfdSJames Morse 
936bf0dcfdSJames Morse /*
946bf0dcfdSJames Morse  * Return the AET bits from a RAS SError's ESR.
956bf0dcfdSJames Morse  *
966bf0dcfdSJames Morse  * It is implementation defined whether Uncategorized errors are containable.
976bf0dcfdSJames Morse  * We treat them as Uncontainable.
986bf0dcfdSJames Morse  * Non-RAS SError's are reported as Uncontained/Uncategorized.
996bf0dcfdSJames Morse  */
1006bf0dcfdSJames Morse static inline u32 arm64_ras_serror_get_severity(u32 esr)
1016bf0dcfdSJames Morse {
1026bf0dcfdSJames Morse 	u32 aet = esr & ESR_ELx_AET;
1036bf0dcfdSJames Morse 
1046bf0dcfdSJames Morse 	if (!arm64_is_ras_serror(esr)) {
1056bf0dcfdSJames Morse 		/* Not a RAS error, we can't interpret the ESR. */
1066bf0dcfdSJames Morse 		return ESR_ELx_AET_UC;
1076bf0dcfdSJames Morse 	}
1086bf0dcfdSJames Morse 
1096bf0dcfdSJames Morse 	/*
1106bf0dcfdSJames Morse 	 * AET is RES0 if 'the value returned in the DFSC field is not
1116bf0dcfdSJames Morse 	 * [ESR_ELx_FSC_SERROR]'
1126bf0dcfdSJames Morse 	 */
1136bf0dcfdSJames Morse 	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
1146bf0dcfdSJames Morse 		/* No severity information : Uncategorized */
1156bf0dcfdSJames Morse 		return ESR_ELx_AET_UC;
1166bf0dcfdSJames Morse 	}
1176bf0dcfdSJames Morse 
1186bf0dcfdSJames Morse 	return aet;
1196bf0dcfdSJames Morse }
1206bf0dcfdSJames Morse 
1216bf0dcfdSJames Morse bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr);
1226bf0dcfdSJames Morse void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
12360ffc30dSCatalin Marinas #endif
124