diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-05-02 02:30:48 +0900 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-22 08:48:06 -0400 |
commit | d2f62766d5778bbaf80d4feb90a23c7edc371a54 (patch) | |
tree | 8c3a3aa062dd6de622532b5a7cf5321804bccc7f /arch/x86 | |
parent | 51187683cb11b959535d32eb91b673c6a9a03e88 (diff) |
KVM: x86 emulator: Make jmp far emulation into a separate function
We introduce em_jmp_far().
We also call this from em_grp45() to stop treating modrm_reg == 5 case
separately in the group 5 emulation.
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/emulate.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d9ebf6939e49..d6e2477feb18 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1687,6 +1687,23 @@ static inline int emulate_iret(struct x86_emulate_ctxt *ctxt, } } +static int em_jmp_far(struct x86_emulate_ctxt *ctxt) +{ + struct decode_cache *c = &ctxt->decode; + int rc; + unsigned short sel; + + memcpy(&sel, c->src.valptr + c->op_bytes, 2); + + rc = load_segment_descriptor(ctxt, ctxt->ops, sel, VCPU_SREG_CS); + if (rc != X86EMUL_CONTINUE) + return rc; + + c->eip = 0; + memcpy(&c->eip, c->src.valptr, c->op_bytes); + return X86EMUL_CONTINUE; +} + static int em_grp1a(struct x86_emulate_ctxt *ctxt) { struct decode_cache *c = &ctxt->decode; @@ -1786,6 +1803,9 @@ static int em_grp45(struct x86_emulate_ctxt *ctxt) case 4: /* jmp abs */ c->eip = c->src.val; break; + case 5: /* jmp far */ + rc = em_jmp_far(ctxt); + break; case 6: /* push */ rc = em_push(ctxt); break; @@ -3997,19 +4017,9 @@ special_insn: } case 0xe9: /* jmp rel */ goto jmp; - case 0xea: { /* jmp far */ - unsigned short sel; - jump_far: - memcpy(&sel, c->src.valptr + c->op_bytes, 2); - - rc = load_segment_descriptor(ctxt, ops, sel, VCPU_SREG_CS); - if (rc != X86EMUL_CONTINUE) - goto done; - - c->eip = 0; - memcpy(&c->eip, c->src.valptr, c->op_bytes); + case 0xea: /* jmp far */ + rc = em_jmp_far(ctxt); break; - } case 0xeb: jmp: /* jmp rel short */ jmp_rel(c, c->src.val); @@ -4073,8 +4083,6 @@ special_insn: rc = em_grp45(ctxt); break; case 0xff: /* Grp5 */ - if (c->modrm_reg == 5) - goto jump_far; rc = em_grp45(ctxt); break; default: |