diff options
| -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 |
