diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-05-29 09:01:33 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 06:16:03 -0400 |
commit | 1bd5f469b2d54330ba41d9c4b857dc5051e8dcf7 (patch) | |
tree | f4c23a7cbf965b63d02b67b8f592b09641f766b3 /arch/x86/kvm/emulate.c | |
parent | ebda02c2a5a6001c787f311b4d5a0dc827ce2d92 (diff) |
KVM: x86 emulator: Use opcode::execute for MOV(8C/8E)
Different functions for those which take segment register operands.
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 | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2ebec692d44b..5561680c1e9c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2683,6 +2683,33 @@ static int em_mov(struct x86_emulate_ctxt *ctxt) | |||
2683 | return X86EMUL_CONTINUE; | 2683 | return X86EMUL_CONTINUE; |
2684 | } | 2684 | } |
2685 | 2685 | ||
2686 | static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) | ||
2687 | { | ||
2688 | struct decode_cache *c = &ctxt->decode; | ||
2689 | |||
2690 | if (c->modrm_reg > VCPU_SREG_GS) | ||
2691 | return emulate_ud(ctxt); | ||
2692 | |||
2693 | c->dst.val = get_segment_selector(ctxt, c->modrm_reg); | ||
2694 | return X86EMUL_CONTINUE; | ||
2695 | } | ||
2696 | |||
2697 | static int em_mov_sreg_rm(struct x86_emulate_ctxt *ctxt) | ||
2698 | { | ||
2699 | struct decode_cache *c = &ctxt->decode; | ||
2700 | u16 sel = c->src.val; | ||
2701 | |||
2702 | if (c->modrm_reg == VCPU_SREG_CS || c->modrm_reg > VCPU_SREG_GS) | ||
2703 | return emulate_ud(ctxt); | ||
2704 | |||
2705 | if (c->modrm_reg == VCPU_SREG_SS) | ||
2706 | ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS; | ||
2707 | |||
2708 | /* Disable writeback. */ | ||
2709 | c->dst.type = OP_NONE; | ||
2710 | return load_segment_descriptor(ctxt, sel, c->modrm_reg); | ||
2711 | } | ||
2712 | |||
2686 | static int em_movdqu(struct x86_emulate_ctxt *ctxt) | 2713 | static int em_movdqu(struct x86_emulate_ctxt *ctxt) |
2687 | { | 2714 | { |
2688 | struct decode_cache *c = &ctxt->decode; | 2715 | struct decode_cache *c = &ctxt->decode; |
@@ -3172,8 +3199,10 @@ static struct opcode opcode_table[256] = { | |||
3172 | /* 0x88 - 0x8F */ | 3199 | /* 0x88 - 0x8F */ |
3173 | I2bv(DstMem | SrcReg | ModRM | Mov, em_mov), | 3200 | I2bv(DstMem | SrcReg | ModRM | Mov, em_mov), |
3174 | I2bv(DstReg | SrcMem | ModRM | Mov, em_mov), | 3201 | I2bv(DstReg | SrcMem | ModRM | Mov, em_mov), |
3175 | D(DstMem | SrcNone | ModRM | Mov), D(ModRM | SrcMem | NoAccess | DstReg), | 3202 | I(DstMem | SrcNone | ModRM | Mov, em_mov_rm_sreg), |
3176 | D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A), | 3203 | D(ModRM | SrcMem | NoAccess | DstReg), |
3204 | I(ImplicitOps | SrcMem16 | ModRM, em_mov_sreg_rm), | ||
3205 | G(0, group1A), | ||
3177 | /* 0x90 - 0x97 */ | 3206 | /* 0x90 - 0x97 */ |
3178 | DI(SrcAcc | DstReg, pause), X7(D(SrcAcc | DstReg)), | 3207 | DI(SrcAcc | DstReg, pause), X7(D(SrcAcc | DstReg)), |
3179 | /* 0x98 - 0x9F */ | 3208 | /* 0x98 - 0x9F */ |
@@ -3906,35 +3935,9 @@ special_insn: | |||
3906 | if (test_cc(c->b, ctxt->eflags)) | 3935 | if (test_cc(c->b, ctxt->eflags)) |
3907 | jmp_rel(c, c->src.val); | 3936 | jmp_rel(c, c->src.val); |
3908 | break; | 3937 | break; |
3909 | case 0x8c: /* mov r/m, sreg */ | ||
3910 | if (c->modrm_reg > VCPU_SREG_GS) { | ||
3911 | rc = emulate_ud(ctxt); | ||
3912 | goto done; | ||
3913 | } | ||
3914 | c->dst.val = get_segment_selector(ctxt, c->modrm_reg); | ||
3915 | break; | ||
3916 | case 0x8d: /* lea r16/r32, m */ | 3938 | case 0x8d: /* lea r16/r32, m */ |
3917 | c->dst.val = c->src.addr.mem.ea; | 3939 | c->dst.val = c->src.addr.mem.ea; |
3918 | break; | 3940 | break; |
3919 | case 0x8e: { /* mov seg, r/m16 */ | ||
3920 | uint16_t sel; | ||
3921 | |||
3922 | sel = c->src.val; | ||
3923 | |||
3924 | if (c->modrm_reg == VCPU_SREG_CS || | ||
3925 | c->modrm_reg > VCPU_SREG_GS) { | ||
3926 | rc = emulate_ud(ctxt); | ||
3927 | goto done; | ||
3928 | } | ||
3929 | |||
3930 | if (c->modrm_reg == VCPU_SREG_SS) | ||
3931 | ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS; | ||
3932 | |||
3933 | rc = load_segment_descriptor(ctxt, sel, c->modrm_reg); | ||
3934 | |||
3935 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3936 | break; | ||
3937 | } | ||
3938 | case 0x8f: /* pop (sole member of Grp1a) */ | 3941 | case 0x8f: /* pop (sole member of Grp1a) */ |
3939 | rc = em_grp1a(ctxt); | 3942 | rc = em_grp1a(ctxt); |
3940 | break; | 3943 | break; |