1
2
3
4
5
6
7
8#include <linux/errno.h>
9#include <asm/kprobes.h>
10#include <asm/dis.h>
11
12int probe_is_prohibited_opcode(u16 *insn)
13{
14 if (!is_known_insn((unsigned char *)insn))
15 return -EINVAL;
16 switch (insn[0] >> 8) {
17 case 0x0c:
18 case 0x0b:
19 case 0x83:
20 case 0x44:
21 case 0xac:
22 case 0xad:
23 return -EINVAL;
24 case 0xc6:
25 switch (insn[0] & 0x0f) {
26 case 0x00:
27 return -EINVAL;
28 }
29 }
30 switch (insn[0]) {
31 case 0x0101:
32 case 0xb25a:
33 case 0xb240:
34 case 0xb258:
35 case 0xb218:
36 case 0xb228:
37 case 0xb98d:
38 case 0xe560:
39 case 0xe561:
40 case 0xb2f8:
41 return -EINVAL;
42 }
43 return 0;
44}
45
46int probe_get_fixup_type(u16 *insn)
47{
48
49 int fixup = FIXUP_PSW_NORMAL;
50
51 switch (insn[0] >> 8) {
52 case 0x05:
53 case 0x0d:
54 fixup = FIXUP_RETURN_REGISTER;
55
56 if ((insn[0] & 0x0f) == 0)
57 fixup |= FIXUP_BRANCH_NOT_TAKEN;
58 break;
59 case 0x06:
60 case 0x07:
61 fixup = FIXUP_BRANCH_NOT_TAKEN;
62 break;
63 case 0x45:
64 case 0x4d:
65 fixup = FIXUP_RETURN_REGISTER;
66 break;
67 case 0x47:
68 case 0x46:
69 case 0x86:
70 case 0x87:
71 fixup = FIXUP_BRANCH_NOT_TAKEN;
72 break;
73 case 0x82:
74 fixup = FIXUP_NOT_REQUIRED;
75 break;
76 case 0xb2:
77 if ((insn[0] & 0xff) == 0xb2)
78 fixup = FIXUP_NOT_REQUIRED;
79 break;
80 case 0xa7:
81 if ((insn[0] & 0x0f) == 0x05)
82 fixup |= FIXUP_RETURN_REGISTER;
83 break;
84 case 0xc0:
85 if ((insn[0] & 0x0f) == 0x05)
86 fixup |= FIXUP_RETURN_REGISTER;
87 break;
88 case 0xeb:
89 switch (insn[2] & 0xff) {
90 case 0x44:
91 case 0x45:
92 fixup = FIXUP_BRANCH_NOT_TAKEN;
93 break;
94 }
95 break;
96 case 0xe3:
97 if ((insn[2] & 0xff) == 0x46)
98 fixup = FIXUP_BRANCH_NOT_TAKEN;
99 break;
100 case 0xec:
101 switch (insn[2] & 0xff) {
102 case 0xe5:
103 case 0xe6:
104 case 0xf6:
105 case 0xf7:
106 case 0xfc:
107 case 0xfd:
108 case 0xfe:
109 case 0xff:
110 fixup = FIXUP_BRANCH_NOT_TAKEN;
111 break;
112 }
113 break;
114 }
115 return fixup;
116}
117
118int probe_is_insn_relative_long(u16 *insn)
119{
120
121
122 switch (insn[0] >> 8) {
123 case 0xc0:
124 if ((insn[0] & 0x0f) == 0x00)
125 return true;
126 break;
127 case 0xc4:
128 switch (insn[0] & 0x0f) {
129 case 0x02:
130 case 0x04:
131 case 0x05:
132 case 0x06:
133 case 0x07:
134 case 0x08:
135 case 0x0b:
136 case 0x0c:
137 case 0x0d:
138 case 0x0e:
139 case 0x0f:
140 return true;
141 }
142 break;
143 case 0xc6:
144 switch (insn[0] & 0x0f) {
145 case 0x02:
146 case 0x04:
147 case 0x05:
148 case 0x06:
149 case 0x07:
150 case 0x08:
151 case 0x0a:
152 case 0x0c:
153 case 0x0d:
154 case 0x0e:
155 case 0x0f:
156 return true;
157 }
158 break;
159 }
160 return false;
161}
162