traps.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Based on arch/arm/include/asm/traps.h
  4. *
  5. * Copyright (C) 2012 ARM Ltd.
  6. */
  7. #ifndef __ASM_TRAP_H
  8. #define __ASM_TRAP_H
  9. #include <linux/list.h>
  10. #include <asm/esr.h>
  11. #include <asm/ptrace.h>
  12. #include <asm/sections.h>
  13. #ifdef CONFIG_ARMV8_DEPRECATED
  14. bool try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn);
  15. #else
  16. static inline bool
  17. try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn)
  18. {
  19. return false;
  20. }
  21. #endif /* CONFIG_ARMV8_DEPRECATED */
  22. void force_signal_inject(int signal, int code, unsigned long address, unsigned long err);
  23. void arm64_notify_segfault(unsigned long addr);
  24. void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str);
  25. void arm64_force_sig_fault_pkey(unsigned long far, const char *str, int pkey);
  26. void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str);
  27. void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str);
  28. int early_brk64(unsigned long addr, unsigned long esr, struct pt_regs *regs);
  29. /*
  30. * Move regs->pc to next instruction and do necessary setup before it
  31. * is executed.
  32. */
  33. void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size);
  34. static inline int __in_irqentry_text(unsigned long ptr)
  35. {
  36. return ptr >= (unsigned long)&__irqentry_text_start &&
  37. ptr < (unsigned long)&__irqentry_text_end;
  38. }
  39. static inline int in_entry_text(unsigned long ptr)
  40. {
  41. return ptr >= (unsigned long)&__entry_text_start &&
  42. ptr < (unsigned long)&__entry_text_end;
  43. }
  44. /*
  45. * CPUs with the RAS extensions have an Implementation-Defined-Syndrome bit
  46. * to indicate whether this ESR has a RAS encoding. CPUs without this feature
  47. * have a ISS-Valid bit in the same position.
  48. * If this bit is set, we know its not a RAS SError.
  49. * If its clear, we need to know if the CPU supports RAS. Uncategorized RAS
  50. * errors share the same encoding as an all-zeros encoding from a CPU that
  51. * doesn't support RAS.
  52. */
  53. static inline bool arm64_is_ras_serror(unsigned long esr)
  54. {
  55. WARN_ON(preemptible());
  56. if (esr & ESR_ELx_IDS)
  57. return false;
  58. if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN))
  59. return true;
  60. else
  61. return false;
  62. }
  63. /*
  64. * Return the AET bits from a RAS SError's ESR.
  65. *
  66. * It is implementation defined whether Uncategorized errors are containable.
  67. * We treat them as Uncontainable.
  68. * Non-RAS SError's are reported as Uncontained/Uncategorized.
  69. */
  70. static inline unsigned long arm64_ras_serror_get_severity(unsigned long esr)
  71. {
  72. unsigned long aet = esr & ESR_ELx_AET;
  73. if (!arm64_is_ras_serror(esr)) {
  74. /* Not a RAS error, we can't interpret the ESR. */
  75. return ESR_ELx_AET_UC;
  76. }
  77. /*
  78. * AET is RES0 if 'the value returned in the DFSC field is not
  79. * [ESR_ELx_FSC_SERROR]'
  80. */
  81. if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
  82. /* No severity information : Uncategorized */
  83. return ESR_ELx_AET_UC;
  84. }
  85. return aet;
  86. }
  87. bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr);
  88. void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr);
  89. static inline void arm64_mops_reset_regs(struct user_pt_regs *regs, unsigned long esr)
  90. {
  91. bool wrong_option = esr & ESR_ELx_MOPS_ISS_WRONG_OPTION;
  92. bool option_a = esr & ESR_ELx_MOPS_ISS_OPTION_A;
  93. int dstreg = ESR_ELx_MOPS_ISS_DESTREG(esr);
  94. int srcreg = ESR_ELx_MOPS_ISS_SRCREG(esr);
  95. int sizereg = ESR_ELx_MOPS_ISS_SIZEREG(esr);
  96. unsigned long dst, size;
  97. dst = regs->regs[dstreg];
  98. size = regs->regs[sizereg];
  99. /*
  100. * Put the registers back in the original format suitable for a
  101. * prologue instruction, using the generic return routine from the
  102. * Arm ARM (DDI 0487I.a) rules CNTMJ and MWFQH.
  103. */
  104. if (esr & ESR_ELx_MOPS_ISS_MEM_INST) {
  105. /* SET* instruction */
  106. if (option_a ^ wrong_option) {
  107. /* Format is from Option A; forward set */
  108. regs->regs[dstreg] = dst + size;
  109. regs->regs[sizereg] = -size;
  110. }
  111. } else {
  112. /* CPY* instruction */
  113. unsigned long src = regs->regs[srcreg];
  114. if (!(option_a ^ wrong_option)) {
  115. /* Format is from Option B */
  116. if (regs->pstate & PSR_N_BIT) {
  117. /* Backward copy */
  118. regs->regs[dstreg] = dst - size;
  119. regs->regs[srcreg] = src - size;
  120. }
  121. } else {
  122. /* Format is from Option A */
  123. if (size & BIT(63)) {
  124. /* Forward copy */
  125. regs->regs[dstreg] = dst + size;
  126. regs->regs[srcreg] = src + size;
  127. regs->regs[sizereg] = -size;
  128. }
  129. }
  130. }
  131. if (esr & ESR_ELx_MOPS_ISS_FROM_EPILOGUE)
  132. regs->pc -= 8;
  133. else
  134. regs->pc -= 4;
  135. }
  136. #endif