jump_label.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * jump label x86 support
  3. *
  4. * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
  5. *
  6. */
  7. #include <linux/jump_label.h>
  8. #include <linux/memory.h>
  9. #include <linux/uaccess.h>
  10. #include <linux/module.h>
  11. #include <linux/list.h>
  12. #include <linux/jhash.h>
  13. #include <linux/cpu.h>
  14. #include <asm/kprobes.h>
  15. #include <asm/alternative.h>
  16. #ifdef HAVE_JUMP_LABEL
  17. union jump_code_union {
  18. char code[JUMP_LABEL_NOP_SIZE];
  19. struct {
  20. char jump;
  21. int offset;
  22. } __attribute__((packed));
  23. };
  24. static void bug_at(unsigned char *ip, int line)
  25. {
  26. /*
  27. * The location is not an op that we were expecting.
  28. * Something went wrong. Crash the box, as something could be
  29. * corrupting the kernel.
  30. */
  31. pr_warning("Unexpected op at %pS [%p] (%02x %02x %02x %02x %02x) %s:%d\n",
  32. ip, ip, ip[0], ip[1], ip[2], ip[3], ip[4], __FILE__, line);
  33. BUG();
  34. }
  35. static void __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 (type == JUMP_LABEL_ENABLE) {
  44. if (init) {
  45. /*
  46. * Jump label is enabled for the first time.
  47. * So we expect a default_nop...
  48. */
  49. if (unlikely(memcmp((void *)entry->code, default_nop, 5)
  50. != 0))
  51. bug_at((void *)entry->code, __LINE__);
  52. } else {
  53. /*
  54. * ...otherwise expect an ideal_nop. Otherwise
  55. * something went horribly wrong.
  56. */
  57. if (unlikely(memcmp((void *)entry->code, ideal_nop, 5)
  58. != 0))
  59. bug_at((void *)entry->code, __LINE__);
  60. }
  61. code.jump = 0xe9;
  62. code.offset = entry->target -
  63. (entry->code + JUMP_LABEL_NOP_SIZE);
  64. } else {
  65. /*
  66. * We are disabling this jump label. If it is not what
  67. * we think it is, then something must have gone wrong.
  68. * If this is the first initialization call, then we
  69. * are converting the default nop to the ideal nop.
  70. */
  71. if (init) {
  72. if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0))
  73. bug_at((void *)entry->code, __LINE__);
  74. } else {
  75. code.jump = 0xe9;
  76. code.offset = entry->target -
  77. (entry->code + JUMP_LABEL_NOP_SIZE);
  78. if (unlikely(memcmp((void *)entry->code, &code, 5) != 0))
  79. bug_at((void *)entry->code, __LINE__);
  80. }
  81. memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
  82. }
  83. /*
  84. * Make text_poke_bp() a default fallback poker.
  85. *
  86. * At the time the change is being done, just ignore whether we
  87. * are doing nop -> jump or jump -> nop transition, and assume
  88. * always nop being the 'currently valid' instruction
  89. *
  90. */
  91. if (poker)
  92. (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
  93. else
  94. text_poke_bp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE,
  95. (void *)entry->code + JUMP_LABEL_NOP_SIZE);
  96. }
  97. void arch_jump_label_transform(struct jump_entry *entry,
  98. enum jump_label_type type)
  99. {
  100. get_online_cpus();
  101. mutex_lock(&text_mutex);
  102. __jump_label_transform(entry, type, NULL, 0);
  103. mutex_unlock(&text_mutex);
  104. put_online_cpus();
  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. }
  132. #endif