diff options
author | Avi Kivity <avi@redhat.com> | 2009-01-05 06:27:34 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:03:01 -0400 |
commit | a77ab5ead5c1fef2c6c5a9b3cf3765e52643a2aa (patch) | |
tree | ae490e1a6b05f726796429b3e504dec302b78396 /arch/x86/kvm/x86_emulate.c | |
parent | 8b3079a5c0c031de07c8390aa160a4229088274f (diff) |
KVM: x86 emulator: implement 'ret far' instruction (opcode 0xcb)
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86_emulate.c')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 94459f313f12..ca91749d2083 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -178,7 +178,7 @@ static u32 opcode_table[256] = { | |||
178 | 0, ImplicitOps | Stack, 0, 0, | 178 | 0, ImplicitOps | Stack, 0, 0, |
179 | ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov, | 179 | ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov, |
180 | /* 0xC8 - 0xCF */ | 180 | /* 0xC8 - 0xCF */ |
181 | 0, 0, 0, 0, 0, 0, 0, 0, | 181 | 0, 0, 0, ImplicitOps | Stack, 0, 0, 0, 0, |
182 | /* 0xD0 - 0xD7 */ | 182 | /* 0xD0 - 0xD7 */ |
183 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, | 183 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, |
184 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, | 184 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, |
@@ -1278,6 +1278,25 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1278 | return 0; | 1278 | return 0; |
1279 | } | 1279 | } |
1280 | 1280 | ||
1281 | static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, | ||
1282 | struct x86_emulate_ops *ops) | ||
1283 | { | ||
1284 | struct decode_cache *c = &ctxt->decode; | ||
1285 | int rc; | ||
1286 | unsigned long cs; | ||
1287 | |||
1288 | rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes); | ||
1289 | if (rc) | ||
1290 | return rc; | ||
1291 | if (c->op_bytes == 4) | ||
1292 | c->eip = (u32)c->eip; | ||
1293 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); | ||
1294 | if (rc) | ||
1295 | return rc; | ||
1296 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS); | ||
1297 | return rc; | ||
1298 | } | ||
1299 | |||
1281 | static inline int writeback(struct x86_emulate_ctxt *ctxt, | 1300 | static inline int writeback(struct x86_emulate_ctxt *ctxt, |
1282 | struct x86_emulate_ops *ops) | 1301 | struct x86_emulate_ops *ops) |
1283 | { | 1302 | { |
@@ -1735,6 +1754,11 @@ special_insn: | |||
1735 | mov: | 1754 | mov: |
1736 | c->dst.val = c->src.val; | 1755 | c->dst.val = c->src.val; |
1737 | break; | 1756 | break; |
1757 | case 0xcb: /* ret far */ | ||
1758 | rc = emulate_ret_far(ctxt, ops); | ||
1759 | if (rc) | ||
1760 | goto done; | ||
1761 | break; | ||
1738 | case 0xd0 ... 0xd1: /* Grp2 */ | 1762 | case 0xd0 ... 0xd1: /* Grp2 */ |
1739 | c->src.val = 1; | 1763 | c->src.val = 1; |
1740 | emulate_grp2(ctxt); | 1764 | emulate_grp2(ctxt); |