aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-01-18 05:58:04 -0500
committerAvi Kivity <avi@qumranet.com>2008-04-27 04:53:14 -0400
commit7d858a19efe5844a98e060931570359b70dea6d1 (patch)
tree62ee800fb0f1a8a976ab47b015717b34636f3275 /arch/x86/kvm
parent43bb19cd3398d3f544d8e2d6ed6c5c5d7b4e5819 (diff)
KVM: x86 emulator: Group decoding for group 3
This adds group decoding support for opcodes 0xf6, 0xf7 (group 3). Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/x86_emulate.c34
1 files changed, 10 insertions, 24 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index cf1ce7c316a9..52e65ae37f06 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -70,7 +70,7 @@
70#define GroupMask 0xff /* Group number stored in bits 0:7 */ 70#define GroupMask 0xff /* Group number stored in bits 0:7 */
71 71
72enum { 72enum {
73 Group1A, 73 Group1A, Group3_Byte, Group3,
74}; 74};
75 75
76static u16 opcode_table[256] = { 76static u16 opcode_table[256] = {
@@ -171,8 +171,7 @@ static u16 opcode_table[256] = {
171 0, 0, 0, 0, 171 0, 0, 0, 0,
172 /* 0xF0 - 0xF7 */ 172 /* 0xF0 - 0xF7 */
173 0, 0, 0, 0, 173 0, 0, 0, 0,
174 ImplicitOps, ImplicitOps, 174 ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
175 ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
176 /* 0xF8 - 0xFF */ 175 /* 0xF8 - 0xFF */
177 ImplicitOps, 0, ImplicitOps, ImplicitOps, 176 ImplicitOps, 0, ImplicitOps, ImplicitOps,
178 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM 177 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM
@@ -239,6 +238,14 @@ static u16 twobyte_table[256] = {
239static u16 group_table[] = { 238static u16 group_table[] = {
240 [Group1A*8] = 239 [Group1A*8] =
241 DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, 240 DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
241 [Group3_Byte*8] =
242 ByteOp | SrcImm | DstMem | ModRM, 0,
243 ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
244 0, 0, 0, 0,
245 [Group3*8] =
246 DstMem | SrcImm | ModRM | SrcImm, 0,
247 DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
248 0, 0, 0, 0,
242}; 249};
243 250
244static u16 group2_table[] = { 251static u16 group2_table[] = {
@@ -1070,26 +1077,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
1070 1077
1071 switch (c->modrm_reg) { 1078 switch (c->modrm_reg) {
1072 case 0 ... 1: /* test */ 1079 case 0 ... 1: /* test */
1073 /*
1074 * Special case in Grp3: test has an immediate
1075 * source operand.
1076 */
1077 c->src.type = OP_IMM;
1078 c->src.ptr = (unsigned long *)c->eip;
1079 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1080 if (c->src.bytes == 8)
1081 c->src.bytes = 4;
1082 switch (c->src.bytes) {
1083 case 1:
1084 c->src.val = insn_fetch(s8, 1, c->eip);
1085 break;
1086 case 2:
1087 c->src.val = insn_fetch(s16, 2, c->eip);
1088 break;
1089 case 4:
1090 c->src.val = insn_fetch(s32, 4, c->eip);
1091 break;
1092 }
1093 emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); 1080 emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
1094 break; 1081 break;
1095 case 2: /* not */ 1082 case 2: /* not */
@@ -1103,7 +1090,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
1103 rc = X86EMUL_UNHANDLEABLE; 1090 rc = X86EMUL_UNHANDLEABLE;
1104 break; 1091 break;
1105 } 1092 }
1106done:
1107 return rc; 1093 return rc;
1108} 1094}
1109 1095