aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2015-02-12 14:18:50 -0500
committerIngo Molnar <mingo@kernel.org>2015-02-18 14:55:46 -0500
commit097f4e5e839359021c8f0ea273655031e6ed04ff (patch)
tree8fbdb7e2aa43e918691ab72079bc45bbf23acde5
parente07e0d4cb0c4bfe822ec8491cc06269096a38bea (diff)
uprobes/x86: Add comment with insn opcodes, mnemonics and why we dont support them
After adding these, it's clear we have some awkward choices there. Some valid instructions are prohibited from uprobing while several invalid ones are allowed. Hopefully future edits to the good-opcode tables will fix wrong bits or explain why those bits are not wrong. No actual code changes. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/1423768732-32194-1-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/uprobes.c153
1 files changed, 134 insertions, 19 deletions
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 8b96a947021f..54e36248e9c0 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -66,6 +66,49 @@
66 * Good-instruction tables for 32-bit apps. This is non-const and volatile 66 * Good-instruction tables for 32-bit apps. This is non-const and volatile
67 * to keep gcc from statically optimizing it out, as variable_test_bit makes 67 * to keep gcc from statically optimizing it out, as variable_test_bit makes
68 * some versions of gcc to think only *(unsigned long*) is used. 68 * some versions of gcc to think only *(unsigned long*) is used.
69 *
70 * Prefixes. Most marked as "bad", but it doesn't matter, since insn decoder
71 * won't report *prefixes* as OPCODE1(insn).
72 * 0f - 2-byte opcode prefix
73 * 26,2e,36,3e - es:/cs:/ss:/ds:
74 * 64 - fs: (marked as "good", why?)
75 * 65 - gs: (marked as "good", why?)
76 * 66 - operand-size prefix
77 * 67 - address-size prefix
78 * f0 - lock prefix
79 * f2 - repnz (marked as "good", why?)
80 * f3 - rep/repz (marked as "good", why?)
81 *
82 * Opcodes we'll probably never support:
83 * 6c-6f - ins,outs. SEGVs if used in userspace
84 * e4-e7 - in,out imm. SEGVs if used in userspace
85 * ec-ef - in,out acc. SEGVs if used in userspace
86 * cc - int3. SIGTRAP if used in userspace
87 * ce - into. Not used in userspace - no kernel support to make it useful. SEGVs
88 * (why we support bound (62) then? it's similar, and similarly unused...)
89 * f1 - int1. SIGTRAP if used in userspace
90 * f4 - hlt. SEGVs if used in userspace
91 * fa - cli. SEGVs if used in userspace
92 * fb - sti. SEGVs if used in userspace
93 *
94 * Opcodes which need some work to be supported:
95 * 07,17,1f - pop es/ss/ds
96 * Normally not used in userspace, but would execute if used.
97 * Can cause GP or stack exception if tries to load wrong segment descriptor.
98 * We hesitate to run them under single step since kernel's handling
99 * of userspace single-stepping (TF flag) is fragile.
100 * We can easily refuse to support push es/cs/ss/ds (06/0e/16/1e)
101 * on the same grounds that they are never used.
102 * cd - int N.
103 * Used by userspace for "int 80" syscall entry. (Other "int N"
104 * cause GP -> SEGV since their IDT gates don't allow calls from CPL 3).
105 * Not supported since kernel's handling of userspace single-stepping
106 * (TF flag) is fragile.
107 * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad
108 *
109 * Opcodes which can be enabled right away:
110 * 63 - arpl. This insn has no unusual exceptions (it's basically an arith op).
111 * d6 - salc. Undocumented "sign-extend carry flag to AL" insn
69 */ 112 */
70#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) 113#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
71static volatile u32 good_insns_32[256 / 32] = { 114static volatile u32 good_insns_32[256 / 32] = {
@@ -94,7 +137,55 @@ static volatile u32 good_insns_32[256 / 32] = {
94#define good_insns_32 NULL 137#define good_insns_32 NULL
95#endif 138#endif
96 139
97/* Good-instruction tables for 64-bit apps */ 140/* Good-instruction tables for 64-bit apps.
141 *
142 * Prefixes. Most marked as "bad", but it doesn't matter, since insn decoder
143 * won't report *prefixes* as OPCODE1(insn).
144 * 0f - 2-byte opcode prefix
145 * 26,2e,36,3e - es:/cs:/ss:/ds:
146 * 40-4f - rex prefixes
147 * 64 - fs: (marked as "good", why?)
148 * 65 - gs: (marked as "good", why?)
149 * 66 - operand-size prefix
150 * 67 - address-size prefix
151 * f0 - lock prefix
152 * f2 - repnz (marked as "good", why?)
153 * f3 - rep/repz (marked as "good", why?)
154 *
155 * Genuinely invalid opcodes:
156 * 06,07 - formerly push/pop es
157 * 0e - formerly push cs
158 * 16,17 - formerly push/pop ss
159 * 1e,1f - formerly push/pop ds
160 * 27,2f,37,3f - formerly daa/das/aaa/aas
161 * 60,61 - formerly pusha/popa
162 * 62 - formerly bound. EVEX prefix for AVX512
163 * 82 - formerly redundant encoding of Group1
164 * 9a - formerly call seg:ofs (marked as "supported"???)
165 * c4,c5 - formerly les/lds. VEX prefixes for AVX
166 * ce - formerly into
167 * d4,d5 - formerly aam/aad
168 * d6 - formerly undocumented salc
169 * ea - formerly jmp seg:ofs (marked as "supported"???)
170 *
171 * Opcodes we'll probably never support:
172 * 6c-6f - ins,outs. SEGVs if used in userspace
173 * e4-e7 - in,out imm. SEGVs if used in userspace
174 * ec-ef - in,out acc. SEGVs if used in userspace
175 * cc - int3. SIGTRAP if used in userspace
176 * f1 - int1. SIGTRAP if used in userspace
177 * f4 - hlt. SEGVs if used in userspace
178 * fa - cli. SEGVs if used in userspace
179 * fb - sti. SEGVs if used in userspace
180 *
181 * Opcodes which need some work to be supported:
182 * cd - int N.
183 * Used by userspace for "int 80" syscall entry. (Other "int N"
184 * cause GP -> SEGV since their IDT gates don't allow calls from CPL 3).
185 * Not supported since kernel's handling of userspace single-stepping
186 * (TF flag) is fragile.
187 * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad
188 */
98#if defined(CONFIG_X86_64) 189#if defined(CONFIG_X86_64)
99static volatile u32 good_insns_64[256 / 32] = { 190static volatile u32 good_insns_64[256 / 32] = {
100 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
@@ -122,7 +213,48 @@ static volatile u32 good_insns_64[256 / 32] = {
122#define good_insns_64 NULL 213#define good_insns_64 NULL
123#endif 214#endif
124 215
125/* Using this for both 64-bit and 32-bit apps */ 216/* Using this for both 64-bit and 32-bit apps.
217 * Opcodes we don't support:
218 * 0f 00 - SLDT/STR/LLDT/LTR/VERR/VERW/-/- group. System insns
219 * 0f 01 - SGDT/SIDT/LGDT/LIDT/SMSW/-/LMSW/INVLPG group.
220 * Also encodes tons of other system insns if mod=11.
221 * Some are in fact non-system: xend, xtest, rdtscp, maybe more
222 * 0f 02 - lar (why? should be safe, it throws no exceptipons)
223 * 0f 03 - lsl (why? should be safe, it throws no exceptipons)
224 * 0f 04 - undefined
225 * 0f 05 - syscall
226 * 0f 06 - clts (CPL0 insn)
227 * 0f 07 - sysret
228 * 0f 08 - invd (CPL0 insn)
229 * 0f 09 - wbinvd (CPL0 insn)
230 * 0f 0a - undefined
231 * 0f 0b - ud2
232 * 0f 0c - undefined
233 * 0f 0d - prefetchFOO (amd prefetch insns)
234 * 0f 18 - prefetchBAR (intel prefetch insns)
235 * 0f 24 - mov from test regs (perhaps entire 20-27 area can be disabled (special reg ops))
236 * 0f 25 - undefined
237 * 0f 26 - mov to test regs
238 * 0f 27 - undefined
239 * 0f 30 - wrmsr (CPL0 insn)
240 * 0f 34 - sysenter
241 * 0f 35 - sysexit
242 * 0f 36 - undefined
243 * 0f 37 - getsec
244 * 0f 38-3f - 3-byte opcodes (why?? all look safe)
245 * 0f 78 - vmread
246 * 0f 79 - vmwrite
247 * 0f 7a - undefined
248 * 0f 7b - undefined
249 * 0f 7c - undefined
250 * 0f 7d - undefined
251 * 0f a6 - undefined
252 * 0f a7 - undefined
253 * 0f b8 - popcnt (why?? it's an ordinary ALU op)
254 * 0f d0 - undefined
255 * 0f f0 - lddqu (why?? it's an ordinary vector load op)
256 * 0f ff - undefined
257 */
126static volatile u32 good_2byte_insns[256 / 32] = { 258static volatile u32 good_2byte_insns[256 / 32] = {
127 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 259 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
128 /* ---------------------------------------------- */ 260 /* ---------------------------------------------- */
@@ -148,23 +280,6 @@ static volatile u32 good_2byte_insns[256 / 32] = {
148#undef W 280#undef W
149 281
150/* 282/*
151 * opcodes we'll probably never support:
152 *
153 * 6c-6d, e4-e5, ec-ed - in
154 * 6e-6f, e6-e7, ee-ef - out
155 * cc, cd - int3, int
156 * cf - iret
157 * d6 - illegal instruction
158 * f1 - int1/icebp
159 * f4 - hlt
160 * fa, fb - cli, sti
161 * 0f - lar, lsl, syscall, clts, sysret, sysenter, sysexit, invd, wbinvd, ud2
162 *
163 * invalid opcodes in 64-bit mode:
164 *
165 * 06, 0e, 16, 1e, 27, 2f, 37, 3f, 60-62, 82, c4-c5, d4-d5
166 * 63 - we support this opcode in x86_64 but not in i386.
167 *
168 * opcodes we may need to refine support for: 283 * opcodes we may need to refine support for:
169 * 284 *
170 * 0f - 2-byte instructions: For many of these instructions, the validity 285 * 0f - 2-byte instructions: For many of these instructions, the validity