diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 13:39:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 13:39:16 -0500 |
commit | b5aeca54d0212515d820e5555115e2fc7847a68b (patch) | |
tree | c214b1304c0631ab79d2d702799988c285da35a7 /arch/x86 | |
parent | 3f4d9925e9174b8786bfbb6e9aa132aa6745078f (diff) | |
parent | b7e37567d080301d38a302bb93ba79d1ca446dca (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 uprobe/kprobe fixes from Ingo Molnar:
"This contains two uprobes fixes, an uprobes comment update and a
kprobes fix"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
kprobes/x86: Mark 2 bytes NOP as boostable
uprobes/x86: Fix 2-byte opcode table
uprobes/x86: Fix 1-byte opcode tables
uprobes/x86: Add comment with insn opcodes, mnemonics and why we dont support them
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/kprobes/core.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/uprobes.c | 153 |
2 files changed, 111 insertions, 44 deletions
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 98f654d466e5..6a1146ea4d4d 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -84,7 +84,7 @@ static volatile u32 twobyte_is_boostable[256 / 32] = { | |||
84 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 84 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
85 | /* ---------------------------------------------- */ | 85 | /* ---------------------------------------------- */ |
86 | W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */ | 86 | W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */ |
87 | W(0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 10 */ | 87 | W(0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1) , /* 10 */ |
88 | W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 20 */ | 88 | W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 20 */ |
89 | W(0x30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */ | 89 | W(0x30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */ |
90 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ | 90 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ |
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 8b96a947021f..81f8adb0679e 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -66,27 +66,54 @@ | |||
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 | * Opcodes we'll probably never support: | ||
71 | * 6c-6f - ins,outs. SEGVs if used in userspace | ||
72 | * e4-e7 - in,out imm. SEGVs if used in userspace | ||
73 | * ec-ef - in,out acc. SEGVs if used in userspace | ||
74 | * cc - int3. SIGTRAP if used in userspace | ||
75 | * ce - into. Not used in userspace - no kernel support to make it useful. SEGVs | ||
76 | * (why we support bound (62) then? it's similar, and similarly unused...) | ||
77 | * f1 - int1. SIGTRAP if used in userspace | ||
78 | * f4 - hlt. SEGVs if used in userspace | ||
79 | * fa - cli. SEGVs if used in userspace | ||
80 | * fb - sti. SEGVs if used in userspace | ||
81 | * | ||
82 | * Opcodes which need some work to be supported: | ||
83 | * 07,17,1f - pop es/ss/ds | ||
84 | * Normally not used in userspace, but would execute if used. | ||
85 | * Can cause GP or stack exception if tries to load wrong segment descriptor. | ||
86 | * We hesitate to run them under single step since kernel's handling | ||
87 | * of userspace single-stepping (TF flag) is fragile. | ||
88 | * We can easily refuse to support push es/cs/ss/ds (06/0e/16/1e) | ||
89 | * on the same grounds that they are never used. | ||
90 | * cd - int N. | ||
91 | * Used by userspace for "int 80" syscall entry. (Other "int N" | ||
92 | * cause GP -> SEGV since their IDT gates don't allow calls from CPL 3). | ||
93 | * Not supported since kernel's handling of userspace single-stepping | ||
94 | * (TF flag) is fragile. | ||
95 | * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad | ||
69 | */ | 96 | */ |
70 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) | 97 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) |
71 | static volatile u32 good_insns_32[256 / 32] = { | 98 | static volatile u32 good_insns_32[256 / 32] = { |
72 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 99 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
73 | /* ---------------------------------------------- */ | 100 | /* ---------------------------------------------- */ |
74 | W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 00 */ | 101 | W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 00 */ |
75 | W(0x10, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 10 */ | 102 | W(0x10, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 10 */ |
76 | W(0x20, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) | /* 20 */ | 103 | W(0x20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 20 */ |
77 | W(0x30, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) , /* 30 */ | 104 | W(0x30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 30 */ |
78 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ | 105 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ |
79 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ | 106 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ |
80 | W(0x60, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */ | 107 | W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */ |
81 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */ | 108 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */ |
82 | W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ | 109 | W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ |
83 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ | 110 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ |
84 | W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */ | 111 | W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */ |
85 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ | 112 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ |
86 | W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */ | 113 | W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */ |
87 | W(0xd0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ | 114 | W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ |
88 | W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */ | 115 | W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */ |
89 | W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */ | 116 | W(0xf0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */ |
90 | /* ---------------------------------------------- */ | 117 | /* ---------------------------------------------- */ |
91 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 118 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
92 | }; | 119 | }; |
@@ -94,27 +121,61 @@ static volatile u32 good_insns_32[256 / 32] = { | |||
94 | #define good_insns_32 NULL | 121 | #define good_insns_32 NULL |
95 | #endif | 122 | #endif |
96 | 123 | ||
97 | /* Good-instruction tables for 64-bit apps */ | 124 | /* Good-instruction tables for 64-bit apps. |
125 | * | ||
126 | * Genuinely invalid opcodes: | ||
127 | * 06,07 - formerly push/pop es | ||
128 | * 0e - formerly push cs | ||
129 | * 16,17 - formerly push/pop ss | ||
130 | * 1e,1f - formerly push/pop ds | ||
131 | * 27,2f,37,3f - formerly daa/das/aaa/aas | ||
132 | * 60,61 - formerly pusha/popa | ||
133 | * 62 - formerly bound. EVEX prefix for AVX512 (not yet supported) | ||
134 | * 82 - formerly redundant encoding of Group1 | ||
135 | * 9a - formerly call seg:ofs | ||
136 | * ce - formerly into | ||
137 | * d4,d5 - formerly aam/aad | ||
138 | * d6 - formerly undocumented salc | ||
139 | * ea - formerly jmp seg:ofs | ||
140 | * | ||
141 | * Opcodes we'll probably never support: | ||
142 | * 6c-6f - ins,outs. SEGVs if used in userspace | ||
143 | * e4-e7 - in,out imm. SEGVs if used in userspace | ||
144 | * ec-ef - in,out acc. SEGVs if used in userspace | ||
145 | * cc - int3. SIGTRAP if used in userspace | ||
146 | * f1 - int1. SIGTRAP if used in userspace | ||
147 | * f4 - hlt. SEGVs if used in userspace | ||
148 | * fa - cli. SEGVs if used in userspace | ||
149 | * fb - sti. SEGVs if used in userspace | ||
150 | * | ||
151 | * Opcodes which need some work to be supported: | ||
152 | * cd - int N. | ||
153 | * Used by userspace for "int 80" syscall entry. (Other "int N" | ||
154 | * cause GP -> SEGV since their IDT gates don't allow calls from CPL 3). | ||
155 | * Not supported since kernel's handling of userspace single-stepping | ||
156 | * (TF flag) is fragile. | ||
157 | * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad | ||
158 | */ | ||
98 | #if defined(CONFIG_X86_64) | 159 | #if defined(CONFIG_X86_64) |
99 | static volatile u32 good_insns_64[256 / 32] = { | 160 | static volatile u32 good_insns_64[256 / 32] = { |
100 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 161 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
101 | /* ---------------------------------------------- */ | 162 | /* ---------------------------------------------- */ |
102 | W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */ | 163 | W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1) | /* 00 */ |
103 | W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */ | 164 | W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */ |
104 | W(0x20, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 20 */ | 165 | W(0x20, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 20 */ |
105 | W(0x30, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 30 */ | 166 | W(0x30, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 30 */ |
106 | W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */ | 167 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ |
107 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ | 168 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ |
108 | W(0x60, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */ | 169 | W(0x60, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */ |
109 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */ | 170 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */ |
110 | W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ | 171 | W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ |
111 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ | 172 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1) , /* 90 */ |
112 | W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */ | 173 | W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */ |
113 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ | 174 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ |
114 | W(0xc0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */ | 175 | W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */ |
115 | W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ | 176 | W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ |
116 | W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */ | 177 | W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0) | /* e0 */ |
117 | W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */ | 178 | W(0xf0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */ |
118 | /* ---------------------------------------------- */ | 179 | /* ---------------------------------------------- */ |
119 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 180 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
120 | }; | 181 | }; |
@@ -122,49 +183,55 @@ static volatile u32 good_insns_64[256 / 32] = { | |||
122 | #define good_insns_64 NULL | 183 | #define good_insns_64 NULL |
123 | #endif | 184 | #endif |
124 | 185 | ||
125 | /* Using this for both 64-bit and 32-bit apps */ | 186 | /* Using this for both 64-bit and 32-bit apps. |
187 | * Opcodes we don't support: | ||
188 | * 0f 00 - SLDT/STR/LLDT/LTR/VERR/VERW/-/- group. System insns | ||
189 | * 0f 01 - SGDT/SIDT/LGDT/LIDT/SMSW/-/LMSW/INVLPG group. | ||
190 | * Also encodes tons of other system insns if mod=11. | ||
191 | * Some are in fact non-system: xend, xtest, rdtscp, maybe more | ||
192 | * 0f 05 - syscall | ||
193 | * 0f 06 - clts (CPL0 insn) | ||
194 | * 0f 07 - sysret | ||
195 | * 0f 08 - invd (CPL0 insn) | ||
196 | * 0f 09 - wbinvd (CPL0 insn) | ||
197 | * 0f 0b - ud2 | ||
198 | * 0f 30 - wrmsr (CPL0 insn) (then why rdmsr is allowed, it's also CPL0 insn?) | ||
199 | * 0f 34 - sysenter | ||
200 | * 0f 35 - sysexit | ||
201 | * 0f 37 - getsec | ||
202 | * 0f 78 - vmread (Intel VMX. CPL0 insn) | ||
203 | * 0f 79 - vmwrite (Intel VMX. CPL0 insn) | ||
204 | * Note: with prefixes, these two opcodes are | ||
205 | * extrq/insertq/AVX512 convert vector ops. | ||
206 | * 0f ae - group15: [f]xsave,[f]xrstor,[v]{ld,st}mxcsr,clflush[opt], | ||
207 | * {rd,wr}{fs,gs}base,{s,l,m}fence. | ||
208 | * Why? They are all user-executable. | ||
209 | */ | ||
126 | static volatile u32 good_2byte_insns[256 / 32] = { | 210 | static volatile u32 good_2byte_insns[256 / 32] = { |
127 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 211 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
128 | /* ---------------------------------------------- */ | 212 | /* ---------------------------------------------- */ |
129 | W(0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) | /* 00 */ | 213 | W(0x00, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1) | /* 00 */ |
130 | W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1) , /* 10 */ | 214 | W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 10 */ |
131 | W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 20 */ | 215 | W(0x20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 20 */ |
132 | W(0x30, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */ | 216 | W(0x30, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) , /* 30 */ |
133 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ | 217 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ |
134 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ | 218 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ |
135 | W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 60 */ | 219 | W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 60 */ |
136 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) , /* 70 */ | 220 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) , /* 70 */ |
137 | W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ | 221 | W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ |
138 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ | 222 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ |
139 | W(0xa0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1) | /* a0 */ | 223 | W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1) | /* a0 */ |
140 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ | 224 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ |
141 | W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */ | 225 | W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */ |
142 | W(0xd0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ | 226 | W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ |
143 | W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* e0 */ | 227 | W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* e0 */ |
144 | W(0xf0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) /* f0 */ | 228 | W(0xf0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) /* f0 */ |
145 | /* ---------------------------------------------- */ | 229 | /* ---------------------------------------------- */ |
146 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 230 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
147 | }; | 231 | }; |
148 | #undef W | 232 | #undef W |
149 | 233 | ||
150 | /* | 234 | /* |
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: | 235 | * opcodes we may need to refine support for: |
169 | * | 236 | * |
170 | * 0f - 2-byte instructions: For many of these instructions, the validity | 237 | * 0f - 2-byte instructions: For many of these instructions, the validity |