diff options
author | Avi Kivity <avi@qumranet.com> | 2008-01-18 06:12:26 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 04:53:15 -0400 |
commit | fd60754e4ffa992586346dd56451723b4c096626 (patch) | |
tree | 0d03253f9d5b564f0f2da916a753f51870dbda92 /arch | |
parent | 7d858a19efe5844a98e060931570359b70dea6d1 (diff) |
KVM: x86 emulator: Group decoding for groups 4 and 5
Add group decoding support for opcode 0xfe (group 4) and 0xff (group 5).
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 40 |
1 files changed, 10 insertions, 30 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 52e65ae37f06..7310368c4857 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 | ||
72 | enum { | 72 | enum { |
73 | Group1A, Group3_Byte, Group3, | 73 | Group1A, Group3_Byte, Group3, Group4, Group5, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static u16 opcode_table[256] = { | 76 | static u16 opcode_table[256] = { |
@@ -174,7 +174,7 @@ static u16 opcode_table[256] = { | |||
174 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, | 174 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, |
175 | /* 0xF8 - 0xFF */ | 175 | /* 0xF8 - 0xFF */ |
176 | ImplicitOps, 0, ImplicitOps, ImplicitOps, | 176 | ImplicitOps, 0, ImplicitOps, ImplicitOps, |
177 | 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM | 177 | 0, 0, Group | Group4, Group | Group5, |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static u16 twobyte_table[256] = { | 180 | static u16 twobyte_table[256] = { |
@@ -246,6 +246,12 @@ static u16 group_table[] = { | |||
246 | DstMem | SrcImm | ModRM | SrcImm, 0, | 246 | DstMem | SrcImm | ModRM | SrcImm, 0, |
247 | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, | 247 | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, |
248 | 0, 0, 0, 0, | 248 | 0, 0, 0, 0, |
249 | [Group4*8] = | ||
250 | ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, | ||
251 | 0, 0, 0, 0, 0, 0, | ||
252 | [Group5*8] = | ||
253 | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, 0, 0, | ||
254 | SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0, | ||
249 | }; | 255 | }; |
250 | 256 | ||
251 | static u16 group2_table[] = { | 257 | static u16 group2_table[] = { |
@@ -1097,7 +1103,6 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | |||
1097 | struct x86_emulate_ops *ops) | 1103 | struct x86_emulate_ops *ops) |
1098 | { | 1104 | { |
1099 | struct decode_cache *c = &ctxt->decode; | 1105 | struct decode_cache *c = &ctxt->decode; |
1100 | int rc; | ||
1101 | 1106 | ||
1102 | switch (c->modrm_reg) { | 1107 | switch (c->modrm_reg) { |
1103 | case 0: /* inc */ | 1108 | case 0: /* inc */ |
@@ -1107,36 +1112,11 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | |||
1107 | emulate_1op("dec", c->dst, ctxt->eflags); | 1112 | emulate_1op("dec", c->dst, ctxt->eflags); |
1108 | break; | 1113 | break; |
1109 | case 4: /* jmp abs */ | 1114 | case 4: /* jmp abs */ |
1110 | if (c->b == 0xff) | 1115 | c->eip = c->src.val; |
1111 | c->eip = c->dst.val; | ||
1112 | else { | ||
1113 | DPRINTF("Cannot emulate %02x\n", c->b); | ||
1114 | return X86EMUL_UNHANDLEABLE; | ||
1115 | } | ||
1116 | break; | 1116 | break; |
1117 | case 6: /* push */ | 1117 | case 6: /* push */ |
1118 | 1118 | emulate_push(ctxt); | |
1119 | /* 64-bit mode: PUSH always pushes a 64-bit operand. */ | ||
1120 | |||
1121 | if (ctxt->mode == X86EMUL_MODE_PROT64) { | ||
1122 | c->dst.bytes = 8; | ||
1123 | rc = ops->read_std((unsigned long)c->dst.ptr, | ||
1124 | &c->dst.val, 8, ctxt->vcpu); | ||
1125 | if (rc != 0) | ||
1126 | return rc; | ||
1127 | } | ||
1128 | register_address_increment(c->regs[VCPU_REGS_RSP], | ||
1129 | -c->dst.bytes); | ||
1130 | rc = ops->write_emulated(register_address(ctxt->ss_base, | ||
1131 | c->regs[VCPU_REGS_RSP]), &c->dst.val, | ||
1132 | c->dst.bytes, ctxt->vcpu); | ||
1133 | if (rc != 0) | ||
1134 | return rc; | ||
1135 | c->dst.type = OP_NONE; | ||
1136 | break; | 1119 | break; |
1137 | default: | ||
1138 | DPRINTF("Cannot emulate %02x\n", c->b); | ||
1139 | return X86EMUL_UNHANDLEABLE; | ||
1140 | } | 1120 | } |
1141 | return 0; | 1121 | return 0; |
1142 | } | 1122 | } |