probes.c 3.3 KB

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