bug.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_X86_BUG_H
  3. #define _ASM_X86_BUG_H
  4. #include <linux/stringify.h>
  5. /*
  6. * Since some emulators terminate on UD2, we cannot use it for WARN.
  7. * Since various instruction decoders disagree on the length of UD1,
  8. * we cannot use it either. So use UD0 for WARN.
  9. *
  10. * (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas
  11. * our kernel decoder thinks it takes a ModRM byte, which seems consistent
  12. * with various things like the Intel SDM instruction encoding rules)
  13. */
  14. #define ASM_UD0 ".byte 0x0f, 0xff"
  15. #define ASM_UD1 ".byte 0x0f, 0xb9" /* + ModRM */
  16. #define ASM_UD2 ".byte 0x0f, 0x0b"
  17. #define INSN_UD0 0xff0f
  18. #define INSN_UD2 0x0b0f
  19. #define LEN_UD0 2
  20. #ifdef CONFIG_GENERIC_BUG
  21. #ifdef CONFIG_X86_32
  22. # define __BUG_REL(val) ".long " __stringify(val)
  23. #else
  24. # define __BUG_REL(val) ".long " __stringify(val) " - 2b"
  25. #endif
  26. #ifdef CONFIG_DEBUG_BUGVERBOSE
  27. #define _BUG_FLAGS(ins, flags) \
  28. do { \
  29. asm volatile("1:\t" ins "\n" \
  30. ".pushsection __bug_table,\"aw\"\n" \
  31. "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
  32. "\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \
  33. "\t.word %c1" "\t# bug_entry::line\n" \
  34. "\t.word %c2" "\t# bug_entry::flags\n" \
  35. "\t.org 2b+%c3\n" \
  36. ".popsection" \
  37. : : "i" (__FILE__), "i" (__LINE__), \
  38. "i" (flags), \
  39. "i" (sizeof(struct bug_entry))); \
  40. } while (0)
  41. #else /* !CONFIG_DEBUG_BUGVERBOSE */
  42. #define _BUG_FLAGS(ins, flags) \
  43. do { \
  44. asm volatile("1:\t" ins "\n" \
  45. ".pushsection __bug_table,\"aw\"\n" \
  46. "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
  47. "\t.word %c0" "\t# bug_entry::flags\n" \
  48. "\t.org 2b+%c1\n" \
  49. ".popsection" \
  50. : : "i" (flags), \
  51. "i" (sizeof(struct bug_entry))); \
  52. } while (0)
  53. #endif /* CONFIG_DEBUG_BUGVERBOSE */
  54. #else
  55. #define _BUG_FLAGS(ins, flags) asm volatile(ins)
  56. #endif /* CONFIG_GENERIC_BUG */
  57. #define HAVE_ARCH_BUG
  58. #define BUG() \
  59. do { \
  60. _BUG_FLAGS(ASM_UD2, 0); \
  61. unreachable(); \
  62. } while (0)
  63. #define __WARN_FLAGS(flags) _BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags))
  64. #include <asm-generic/bug.h>
  65. #endif /* _ASM_X86_BUG_H */