aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2011-05-29 09:04:08 -0400
committerAvi Kivity <avi@redhat.com>2011-07-12 06:16:06 -0400
commitd06e03adcb30f9e9fff4df1d80a3087f54a62d9a (patch)
treec944856cbdf9fac510f99a84914c845dc3d23d02 /arch/x86/kvm/emulate.c
parent5c5df76b8b32055956ee4cca338d29046016b13e (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.c35
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
2827static 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
2839static 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
2827static bool valid_cr(int nr) 2849static 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;