diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-04-12 06:36:25 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:40 -0400 |
commit | 782b877c8073a9ef307ad6638ee472b8336b2b85 (patch) | |
tree | 454b855b52f8ab88a2e26b45df43b78fc8337eed | |
parent | 0654169e7309f2f68ec4bea9257b14b05ea94d7d (diff) |
KVM: x86 emulator: Complete ljmp decoding at decode stage
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 25 |
1 files changed, 5 insertions, 20 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 71b4bee2e221..8779cf233a83 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -193,7 +193,7 @@ static u32 opcode_table[256] = { | |||
193 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 193 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
194 | /* 0xE8 - 0xEF */ | 194 | /* 0xE8 - 0xEF */ |
195 | ImplicitOps | Stack, SrcImm | ImplicitOps, | 195 | ImplicitOps | Stack, SrcImm | ImplicitOps, |
196 | ImplicitOps, SrcImmByte | ImplicitOps, | 196 | SrcImm | Src2Imm16, SrcImmByte | ImplicitOps, |
197 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 197 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
198 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 198 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
199 | /* 0xF0 - 0xF7 */ | 199 | /* 0xF0 - 0xF7 */ |
@@ -1805,30 +1805,15 @@ special_insn: | |||
1805 | } | 1805 | } |
1806 | case 0xe9: /* jmp rel */ | 1806 | case 0xe9: /* jmp rel */ |
1807 | goto jmp; | 1807 | goto jmp; |
1808 | case 0xea: /* jmp far */ { | 1808 | case 0xea: /* jmp far */ |
1809 | uint32_t eip; | 1809 | if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9, |
1810 | uint16_t sel; | 1810 | VCPU_SREG_CS) < 0) { |
1811 | |||
1812 | switch (c->op_bytes) { | ||
1813 | case 2: | ||
1814 | eip = insn_fetch(u16, 2, c->eip); | ||
1815 | break; | ||
1816 | case 4: | ||
1817 | eip = insn_fetch(u32, 4, c->eip); | ||
1818 | break; | ||
1819 | default: | ||
1820 | DPRINTF("jmp far: Invalid op_bytes\n"); | ||
1821 | goto cannot_emulate; | ||
1822 | } | ||
1823 | sel = insn_fetch(u16, 2, c->eip); | ||
1824 | if (kvm_load_segment_descriptor(ctxt->vcpu, sel, 9, VCPU_SREG_CS) < 0) { | ||
1825 | DPRINTF("jmp far: Failed to load CS descriptor\n"); | 1811 | DPRINTF("jmp far: Failed to load CS descriptor\n"); |
1826 | goto cannot_emulate; | 1812 | goto cannot_emulate; |
1827 | } | 1813 | } |
1828 | 1814 | ||
1829 | c->eip = eip; | 1815 | c->eip = c->src.val; |
1830 | break; | 1816 | break; |
1831 | } | ||
1832 | case 0xeb: | 1817 | case 0xeb: |
1833 | jmp: /* jmp rel short */ | 1818 | jmp: /* jmp rel short */ |
1834 | jmp_rel(c, c->src.val); | 1819 | jmp_rel(c, c->src.val); |