diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-05-29 09:04:08 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 06:16:06 -0400 |
commit | d06e03adcb30f9e9fff4df1d80a3087f54a62d9a (patch) | |
tree | c944856cbdf9fac510f99a84914c845dc3d23d02 /arch/x86/kvm/emulate.c | |
parent | 5c5df76b8b32055956ee4cca338d29046016b13e (diff) |
KVM: x86 emulator: Use opcode::execute for LOOP/JCXZ
LOOP/LOOPcc : E0-E2
JCXZ/JECXZ/JRCXZ : E3
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d7df7ba17b89..e9dbbc91ce8e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2824,6 +2824,28 @@ static int em_lmsw(struct x86_emulate_ctxt *ctxt) | |||
2824 | return X86EMUL_CONTINUE; | 2824 | return X86EMUL_CONTINUE; |
2825 | } | 2825 | } |
2826 | 2826 | ||
2827 | static int em_loop(struct x86_emulate_ctxt *ctxt) | ||
2828 | { | ||
2829 | struct decode_cache *c = &ctxt->decode; | ||
2830 | |||
2831 | register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); | ||
2832 | if ((address_mask(c, c->regs[VCPU_REGS_RCX]) != 0) && | ||
2833 | (c->b == 0xe2 || test_cc(c->b ^ 0x5, ctxt->eflags))) | ||
2834 | jmp_rel(c, c->src.val); | ||
2835 | |||
2836 | return X86EMUL_CONTINUE; | ||
2837 | } | ||
2838 | |||
2839 | static int em_jcxz(struct x86_emulate_ctxt *ctxt) | ||
2840 | { | ||
2841 | struct decode_cache *c = &ctxt->decode; | ||
2842 | |||
2843 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) | ||
2844 | jmp_rel(c, c->src.val); | ||
2845 | |||
2846 | return X86EMUL_CONTINUE; | ||
2847 | } | ||
2848 | |||
2827 | static bool valid_cr(int nr) | 2849 | static bool valid_cr(int nr) |
2828 | { | 2850 | { |
2829 | switch (nr) { | 2851 | switch (nr) { |
@@ -3240,7 +3262,8 @@ static struct opcode opcode_table[256] = { | |||
3240 | /* 0xD8 - 0xDF */ | 3262 | /* 0xD8 - 0xDF */ |
3241 | N, N, N, N, N, N, N, N, | 3263 | N, N, N, N, N, N, N, N, |
3242 | /* 0xE0 - 0xE7 */ | 3264 | /* 0xE0 - 0xE7 */ |
3243 | X4(D(SrcImmByte)), | 3265 | X3(I(SrcImmByte, em_loop)), |
3266 | I(SrcImmByte, em_jcxz), | ||
3244 | D2bvIP(SrcImmUByte | DstAcc, in, check_perm_in), | 3267 | D2bvIP(SrcImmUByte | DstAcc, in, check_perm_in), |
3245 | D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out), | 3268 | D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out), |
3246 | /* 0xE8 - 0xEF */ | 3269 | /* 0xE8 - 0xEF */ |
@@ -3978,16 +4001,6 @@ special_insn: | |||
3978 | c->src.val = c->regs[VCPU_REGS_RCX]; | 4001 | c->src.val = c->regs[VCPU_REGS_RCX]; |
3979 | rc = em_grp2(ctxt); | 4002 | rc = em_grp2(ctxt); |
3980 | break; | 4003 | break; |
3981 | case 0xe0 ... 0xe2: /* loop/loopz/loopnz */ | ||
3982 | register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); | ||
3983 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) != 0 && | ||
3984 | (c->b == 0xe2 || test_cc(c->b ^ 0x5, ctxt->eflags))) | ||
3985 | jmp_rel(c, c->src.val); | ||
3986 | break; | ||
3987 | case 0xe3: /* jcxz/jecxz/jrcxz */ | ||
3988 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) | ||
3989 | jmp_rel(c, c->src.val); | ||
3990 | break; | ||
3991 | case 0xe4: /* inb */ | 4004 | case 0xe4: /* inb */ |
3992 | case 0xe5: /* in */ | 4005 | case 0xe5: /* in */ |
3993 | goto do_io_in; | 4006 | goto do_io_in; |