jump_label.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * jump label x86 support
  4. *
  5. * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
  6. *
  7. */
  8. #include <linux/jump_label.h>
  9. #include <linux/memory.h>
  10. #include <linux/uaccess.h>
  11. #include <linux/module.h>
  12. #include <linux/list.h>
  13. #include <linux/jhash.h>
  14. #include <linux/cpu.h>
  15. #include <asm/kprobes.h>
  16. #include <asm/alternative.h>
  17. #include <asm/text-patching.h>
  18. union jump_code_union {
  19. char code[JUMP_LABEL_NOP_SIZE];
  20. struct {
  21. char jump;
  22. int offset;
  23. } __attribute__((packed));
  24. };
  25. static void bug_at(unsigned char *ip, int line)
  26. {
  27. /*
  28. * The location is not an op that we were expecting.
  29. * Something went wrong. Crash the box, as something could be
  30. * corrupting the kernel.
  31. */
  32. pr_crit("jump_label: Fatal kernel bug, unexpected op at %pS [%p] (%5ph) %d\n", ip, ip, ip, line);
  33. BUG();
  34. }
  35. static void __ref __jump_label_transform(struct jump_entry *entry,
  36. enum jump_label_type type,
  37. void *(*poker)(void *, const void *, size_t),
  38. int init)
  39. {
  40. union jump_code_union code;
  41. const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
  42. const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
  43. if (early_boot_irqs_disabled)
  44. poker = text_poke_early;
  45. if (type == JUMP_LABEL_JMP) {
  46. if (init) {
  47. /*
  48. * Jump label is enabled for the first time.
  49. * So we expect a default_nop...
  50. */
  51. if (unlikely(memcmp((void *)entry->code, default_nop, 5)
  52. != 0))
  53. bug_at((void *)entry->code, __LINE__);
  54. } else {
  55. /*
  56. * ...otherwise expect an ideal_nop. Otherwise
  57. * something went horribly wrong.
  58. */
  59. if (unlikely(memcmp((void *)entry->code, ideal_nop, 5)
  60. != 0))
  61. bug_at((void *)entry->code, __LINE__);
  62. }
  63. code.jump = 0xe9;
  64. code.offset = entry->target -
  65. (entry->code + JUMP_LABEL_NOP_SIZE);
  66. } else {
  67. /*
  68. * We are disabling this jump label. If it is not what
  69. * we think it is, then something must have gone wrong.
  70. * If this is the first initialization call, then we
  71. * are converting the default nop to the ideal nop.
  72. */
  73. if (init) {
  74. if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0))
  75. bug_at((void *)entry->code, __LINE__);
  76. } else {
  77. code.jump = 0xe9;
  78. code.offset = entry->target -
  79. (entry->code + JUMP_LABEL_NOP_SIZE);
  80. if (unlikely(memcmp((void *)entry->code, &code, 5) != 0))
  81. bug_at((void *)entry->code, __LINE__);
  82. }
  83. memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
  84. }
  85. /*
  86. * Make text_poke_bp() a default fallback poker.
  87. *
  88. * At the time the change is being done, just ignore whether we
  89. * are doing nop -> jump or jump -> nop transition, and assume
  90. * always nop being the 'currently valid' instruction
  91. *
  92. */
  93. if (poker)
  94. (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
  95. else
  96. text_poke_bp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE,
  97. (void *)entry->code + JUMP_LABEL_NOP_SIZE);
  98. }
  99. void arch_jump_label_transform(struct jump_entry *entry,
  100. enum jump_label_type type)
  101. {
  102. mutex_lock(&text_mutex);
  103. __jump_label_transform(entry, type, NULL, 0);
  104. mutex_unlock(&text_mutex);
  105. }
  106. static enum {
  107. JL_STATE_START,
  108. JL_STATE_NO_UPDATE,
  109. JL_STATE_UPDATE,
  110. } jlstate __initdata_or_module = JL_STATE_START;
  111. __init_or_module void arch_jump_label_transform_static(struct jump_entry *entry,
  112. enum jump_label_type type)
  113. {
  114. /*
  115. * This function is called at boot up and when modules are
  116. * first loaded. Check if the default nop, the one that is
  117. * inserted at compile time, is the ideal nop. If it is, then
  118. * we do not need to update the nop, and we can leave it as is.
  119. * If it is not, then we need to update the nop to the ideal nop.
  120. */
  121. if (jlstate == JL_STATE_START) {
  122. const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
  123. const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
  124. if (memcmp(ideal_nop, default_nop, 5) != 0)
  125. jlstate = JL_STATE_UPDATE;
  126. else
  127. jlstate = JL_STATE_NO_UPDATE;
  128. }
  129. if (jlstate == JL_STATE_UPDATE)
  130. __jump_label_transform(entry, type, text_poke_early, 1);
  131. }