probes.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Common helper functions for kprobes and uprobes
  3. *
  4. * Copyright IBM Corp. 2014
  5. */
  6. #include <asm/kprobes.h>
  7. #include <asm/dis.h>
  8. int probe_is_prohibited_opcode(u16 *insn)
  9. {
  10. if (!is_known_insn((unsigned char *)insn))
  11. return -EINVAL;
  12. switch (insn[0] >> 8) {
  13. case 0x0c: /* bassm */
  14. case 0x0b: /* bsm */
  15. case 0x83: /* diag */
  16. case 0x44: /* ex */
  17. case 0xac: /* stnsm */
  18. case 0xad: /* stosm */
  19. return -EINVAL;
  20. case 0xc6:
  21. switch (insn[0] & 0x0f) {
  22. case 0x00: /* exrl */
  23. return -EINVAL;
  24. }
  25. }
  26. switch (insn[0]) {
  27. case 0x0101: /* pr */
  28. case 0xb25a: /* bsa */
  29. case 0xb240: /* bakr */
  30. case 0xb258: /* bsg */
  31. case 0xb218: /* pc */
  32. case 0xb228: /* pt */
  33. case 0xb98d: /* epsw */
  34. case 0xe560: /* tbegin */
  35. case 0xe561: /* tbeginc */
  36. case 0xb2f8: /* tend */
  37. return -EINVAL;
  38. }
  39. return 0;
  40. }
  41. int probe_get_fixup_type(u16 *insn)
  42. {
  43. /* default fixup method */
  44. int fixup = FIXUP_PSW_NORMAL;
  45. switch (insn[0] >> 8) {
  46. case 0x05: /* balr */
  47. case 0x0d: /* basr */
  48. fixup = FIXUP_RETURN_REGISTER;
  49. /* if r2 = 0, no branch will be taken */
  50. if ((insn[0] & 0x0f) == 0)
  51. fixup |= FIXUP_BRANCH_NOT_TAKEN;
  52. break;
  53. case 0x06: /* bctr */
  54. case 0x07: /* bcr */
  55. fixup = FIXUP_BRANCH_NOT_TAKEN;
  56. break;
  57. case 0x45: /* bal */
  58. case 0x4d: /* bas */
  59. fixup = FIXUP_RETURN_REGISTER;
  60. break;
  61. case 0x47: /* bc */
  62. case 0x46: /* bct */
  63. case 0x86: /* bxh */
  64. case 0x87: /* bxle */
  65. fixup = FIXUP_BRANCH_NOT_TAKEN;
  66. break;
  67. case 0x82: /* lpsw */
  68. fixup = FIXUP_NOT_REQUIRED;
  69. break;
  70. case 0xb2: /* lpswe */
  71. if ((insn[0] & 0xff) == 0xb2)
  72. fixup = FIXUP_NOT_REQUIRED;
  73. break;
  74. case 0xa7: /* bras */
  75. if ((insn[0] & 0x0f) == 0x05)
  76. fixup |= FIXUP_RETURN_REGISTER;
  77. break;
  78. case 0xc0:
  79. if ((insn[0] & 0x0f) == 0x05) /* brasl */
  80. fixup |= FIXUP_RETURN_REGISTER;
  81. break;
  82. case 0xeb:
  83. switch (insn[2] & 0xff) {
  84. case 0x44: /* bxhg */
  85. case 0x45: /* bxleg */
  86. fixup = FIXUP_BRANCH_NOT_TAKEN;
  87. break;
  88. }
  89. break;
  90. case 0xe3: /* bctg */
  91. if ((insn[2] & 0xff) == 0x46)
  92. fixup = FIXUP_BRANCH_NOT_TAKEN;
  93. break;
  94. case 0xec:
  95. switch (insn[2] & 0xff) {
  96. case 0xe5: /* clgrb */
  97. case 0xe6: /* cgrb */
  98. case 0xf6: /* crb */
  99. case 0xf7: /* clrb */
  100. case 0xfc: /* cgib */
  101. case 0xfd: /* cglib */
  102. case 0xfe: /* cib */
  103. case 0xff: /* clib */
  104. fixup = FIXUP_BRANCH_NOT_TAKEN;
  105. break;
  106. }
  107. break;
  108. }
  109. return fixup;
  110. }
  111. int probe_is_insn_relative_long(u16 *insn)
  112. {
  113. /* Check if we have a RIL-b or RIL-c format instruction which
  114. * we need to modify in order to avoid instruction emulation. */
  115. switch (insn[0] >> 8) {
  116. case 0xc0:
  117. if ((insn[0] & 0x0f) == 0x00) /* larl */
  118. return true;
  119. break;
  120. case 0xc4:
  121. switch (insn[0] & 0x0f) {
  122. case 0x02: /* llhrl */
  123. case 0x04: /* lghrl */
  124. case 0x05: /* lhrl */
  125. case 0x06: /* llghrl */
  126. case 0x07: /* sthrl */
  127. case 0x08: /* lgrl */
  128. case 0x0b: /* stgrl */
  129. case 0x0c: /* lgfrl */
  130. case 0x0d: /* lrl */
  131. case 0x0e: /* llgfrl */
  132. case 0x0f: /* strl */
  133. return true;
  134. }
  135. break;
  136. case 0xc6:
  137. switch (insn[0] & 0x0f) {
  138. case 0x02: /* pfdrl */
  139. case 0x04: /* cghrl */
  140. case 0x05: /* chrl */
  141. case 0x06: /* clghrl */
  142. case 0x07: /* clhrl */
  143. case 0x08: /* cgrl */
  144. case 0x0a: /* clgrl */
  145. case 0x0c: /* cgfrl */
  146. case 0x0d: /* crl */
  147. case 0x0e: /* clgfrl */
  148. case 0x0f: /* clrl */
  149. return true;
  150. }
  151. break;
  152. }
  153. return false;
  154. }