1caab277bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 260ffc30dSCatalin Marinas /* 360ffc30dSCatalin Marinas * Based on arch/arm/include/asm/traps.h 460ffc30dSCatalin Marinas * 560ffc30dSCatalin Marinas * Copyright (C) 2012 ARM Ltd. 660ffc30dSCatalin Marinas */ 760ffc30dSCatalin Marinas #ifndef __ASM_TRAP_H 860ffc30dSCatalin Marinas #define __ASM_TRAP_H 960ffc30dSCatalin Marinas 109b79f52dSPunit Agrawal #include <linux/list.h> 116bf0dcfdSJames Morse #include <asm/esr.h> 12ee78fdc7SJames Morse #include <asm/sections.h> 139b79f52dSPunit Agrawal 149b79f52dSPunit Agrawal struct pt_regs; 159b79f52dSPunit Agrawal 169b79f52dSPunit Agrawal struct undef_hook { 179b79f52dSPunit Agrawal struct list_head node; 189b79f52dSPunit Agrawal u32 instr_mask; 199b79f52dSPunit Agrawal u32 instr_val; 209b79f52dSPunit Agrawal u64 pstate_mask; 219b79f52dSPunit Agrawal u64 pstate_val; 229b79f52dSPunit Agrawal int (*fn)(struct pt_regs *regs, u32 instr); 239b79f52dSPunit Agrawal }; 249b79f52dSPunit Agrawal 259b79f52dSPunit Agrawal void register_undef_hook(struct undef_hook *hook); 269b79f52dSPunit Agrawal void unregister_undef_hook(struct undef_hook *hook); 27*8d56e5c5SAlexandru Elisei void force_signal_inject(int signal, int code, unsigned long address, unsigned long err); 282c9120f3SWill Deacon void arm64_notify_segfault(unsigned long addr); 29dceec3ffSPeter Collingbourne void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str); 30dceec3ffSPeter Collingbourne void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str); 31dceec3ffSPeter Collingbourne void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str); 32390bf177SAndre Przywara 336436beeeSJulien Thierry /* 346436beeeSJulien Thierry * Move regs->pc to next instruction and do necessary setup before it 356436beeeSJulien Thierry * is executed. 366436beeeSJulien Thierry */ 376436beeeSJulien Thierry void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size); 386436beeeSJulien Thierry 399a5ad7d0SJungseok Lee static inline int __in_irqentry_text(unsigned long ptr) 409a5ad7d0SJungseok Lee { 419a5ad7d0SJungseok Lee return ptr >= (unsigned long)&__irqentry_text_start && 429a5ad7d0SJungseok Lee ptr < (unsigned long)&__irqentry_text_end; 439a5ad7d0SJungseok Lee } 449a5ad7d0SJungseok Lee 4573267498SArd Biesheuvel static inline int in_entry_text(unsigned long ptr) 4673267498SArd Biesheuvel { 4773267498SArd Biesheuvel return ptr >= (unsigned long)&__entry_text_start && 4873267498SArd Biesheuvel ptr < (unsigned long)&__entry_text_end; 4973267498SArd Biesheuvel } 506bf0dcfdSJames Morse 516bf0dcfdSJames Morse /* 526bf0dcfdSJames Morse * CPUs with the RAS extensions have an Implementation-Defined-Syndrome bit 536bf0dcfdSJames Morse * to indicate whether this ESR has a RAS encoding. CPUs without this feature 546bf0dcfdSJames Morse * have a ISS-Valid bit in the same position. 556bf0dcfdSJames Morse * If this bit is set, we know its not a RAS SError. 566bf0dcfdSJames Morse * If its clear, we need to know if the CPU supports RAS. Uncategorized RAS 576bf0dcfdSJames Morse * errors share the same encoding as an all-zeros encoding from a CPU that 586bf0dcfdSJames Morse * doesn't support RAS. 596bf0dcfdSJames Morse */ 60*8d56e5c5SAlexandru Elisei static inline bool arm64_is_ras_serror(unsigned long esr) 616bf0dcfdSJames Morse { 626bf0dcfdSJames Morse WARN_ON(preemptible()); 636bf0dcfdSJames Morse 646bf0dcfdSJames Morse if (esr & ESR_ELx_IDS) 656bf0dcfdSJames Morse return false; 666bf0dcfdSJames Morse 676bf0dcfdSJames Morse if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN)) 686bf0dcfdSJames Morse return true; 696bf0dcfdSJames Morse else 706bf0dcfdSJames Morse return false; 716bf0dcfdSJames Morse } 726bf0dcfdSJames Morse 736bf0dcfdSJames Morse /* 746bf0dcfdSJames Morse * Return the AET bits from a RAS SError's ESR. 756bf0dcfdSJames Morse * 766bf0dcfdSJames Morse * It is implementation defined whether Uncategorized errors are containable. 776bf0dcfdSJames Morse * We treat them as Uncontainable. 786bf0dcfdSJames Morse * Non-RAS SError's are reported as Uncontained/Uncategorized. 796bf0dcfdSJames Morse */ 80*8d56e5c5SAlexandru Elisei static inline unsigned long arm64_ras_serror_get_severity(unsigned long esr) 816bf0dcfdSJames Morse { 82*8d56e5c5SAlexandru Elisei unsigned long aet = esr & ESR_ELx_AET; 836bf0dcfdSJames Morse 846bf0dcfdSJames Morse if (!arm64_is_ras_serror(esr)) { 856bf0dcfdSJames Morse /* Not a RAS error, we can't interpret the ESR. */ 866bf0dcfdSJames Morse return ESR_ELx_AET_UC; 876bf0dcfdSJames Morse } 886bf0dcfdSJames Morse 896bf0dcfdSJames Morse /* 906bf0dcfdSJames Morse * AET is RES0 if 'the value returned in the DFSC field is not 916bf0dcfdSJames Morse * [ESR_ELx_FSC_SERROR]' 926bf0dcfdSJames Morse */ 936bf0dcfdSJames Morse if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) { 946bf0dcfdSJames Morse /* No severity information : Uncategorized */ 956bf0dcfdSJames Morse return ESR_ELx_AET_UC; 966bf0dcfdSJames Morse } 976bf0dcfdSJames Morse 986bf0dcfdSJames Morse return aet; 996bf0dcfdSJames Morse } 1006bf0dcfdSJames Morse 101*8d56e5c5SAlexandru Elisei bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr); 102*8d56e5c5SAlexandru Elisei void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr); 10360ffc30dSCatalin Marinas #endif 104