diff options
author | Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net> | 2008-05-27 04:19:08 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-20 05:42:27 -0400 |
commit | 954cd36f7613ac6d084abe33114dd45a8e0dbe92 (patch) | |
tree | 85f69477e28d69fb8e2584fd8c8c26275da8194b /arch/x86 | |
parent | 89c696383d6eb493351a89d450d8ad7a55cbe1da (diff) |
KVM: x86 emulator: add support for jmp far 0xea
Add support for jmp far (opcode 0xea) instruction.
Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Laurent Vivier <laurent.vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index a928aa6cdad2..48b62cc3bd0c 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -168,7 +168,8 @@ static u16 opcode_table[256] = { | |||
168 | /* 0xE0 - 0xE7 */ | 168 | /* 0xE0 - 0xE7 */ |
169 | 0, 0, 0, 0, 0, 0, 0, 0, | 169 | 0, 0, 0, 0, 0, 0, 0, 0, |
170 | /* 0xE8 - 0xEF */ | 170 | /* 0xE8 - 0xEF */ |
171 | ImplicitOps | Stack, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps, | 171 | ImplicitOps | Stack, SrcImm | ImplicitOps, |
172 | ImplicitOps, SrcImmByte | ImplicitOps, | ||
172 | 0, 0, 0, 0, | 173 | 0, 0, 0, 0, |
173 | /* 0xF0 - 0xF7 */ | 174 | /* 0xF0 - 0xF7 */ |
174 | 0, 0, 0, 0, | 175 | 0, 0, 0, 0, |
@@ -1661,7 +1662,33 @@ special_insn: | |||
1661 | break; | 1662 | break; |
1662 | } | 1663 | } |
1663 | case 0xe9: /* jmp rel */ | 1664 | case 0xe9: /* jmp rel */ |
1664 | case 0xeb: /* jmp rel short */ | 1665 | goto jmp; |
1666 | case 0xea: /* jmp far */ { | ||
1667 | uint32_t eip; | ||
1668 | uint16_t sel; | ||
1669 | |||
1670 | switch (c->op_bytes) { | ||
1671 | case 2: | ||
1672 | eip = insn_fetch(u16, 2, c->eip); | ||
1673 | break; | ||
1674 | case 4: | ||
1675 | eip = insn_fetch(u32, 4, c->eip); | ||
1676 | break; | ||
1677 | default: | ||
1678 | DPRINTF("jmp far: Invalid op_bytes\n"); | ||
1679 | goto cannot_emulate; | ||
1680 | } | ||
1681 | sel = insn_fetch(u16, 2, c->eip); | ||
1682 | if (kvm_load_segment_descriptor(ctxt->vcpu, sel, 9, VCPU_SREG_CS) < 0) { | ||
1683 | DPRINTF("jmp far: Failed to load CS descriptor\n"); | ||
1684 | goto cannot_emulate; | ||
1685 | } | ||
1686 | |||
1687 | c->eip = eip; | ||
1688 | break; | ||
1689 | } | ||
1690 | case 0xeb: | ||
1691 | jmp: /* jmp rel short */ | ||
1665 | jmp_rel(c, c->src.val); | 1692 | jmp_rel(c, c->src.val); |
1666 | c->dst.type = OP_NONE; /* Disable writeback. */ | 1693 | c->dst.type = OP_NONE; /* Disable writeback. */ |
1667 | break; | 1694 | break; |