diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-11-22 01:16:54 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-12-27 04:17:23 -0500 |
commit | d7841a4b1b6e8509881e1ec21c024c82ccf565a6 (patch) | |
tree | 632e7986e920d09a5b0654a0357022aa81ffe965 | |
parent | 46199f33c29533e7ad2a7d2128dc30175d1d4157 (diff) |
KVM: x86 emulator: Use opcode::execute for IN/OUT
IN : E4, E5, EC, ED
OUT: E6, E7, EE, EF
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | arch/x86/kvm/emulate.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8547958e3582..8ba4ea8cac72 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2776,6 +2776,24 @@ static int em_jcxz(struct x86_emulate_ctxt *ctxt) | |||
2776 | return X86EMUL_CONTINUE; | 2776 | return X86EMUL_CONTINUE; |
2777 | } | 2777 | } |
2778 | 2778 | ||
2779 | static int em_in(struct x86_emulate_ctxt *ctxt) | ||
2780 | { | ||
2781 | if (!pio_in_emulated(ctxt, ctxt->dst.bytes, ctxt->src.val, | ||
2782 | &ctxt->dst.val)) | ||
2783 | return X86EMUL_IO_NEEDED; | ||
2784 | |||
2785 | return X86EMUL_CONTINUE; | ||
2786 | } | ||
2787 | |||
2788 | static int em_out(struct x86_emulate_ctxt *ctxt) | ||
2789 | { | ||
2790 | ctxt->ops->pio_out_emulated(ctxt, ctxt->src.bytes, ctxt->dst.val, | ||
2791 | &ctxt->src.val, 1); | ||
2792 | /* Disable writeback. */ | ||
2793 | ctxt->dst.type = OP_NONE; | ||
2794 | return X86EMUL_CONTINUE; | ||
2795 | } | ||
2796 | |||
2779 | static int em_cli(struct x86_emulate_ctxt *ctxt) | 2797 | static int em_cli(struct x86_emulate_ctxt *ctxt) |
2780 | { | 2798 | { |
2781 | if (emulator_bad_iopl(ctxt)) | 2799 | if (emulator_bad_iopl(ctxt)) |
@@ -3004,6 +3022,8 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt) | |||
3004 | #define D2bv(_f) D((_f) | ByteOp), D(_f) | 3022 | #define D2bv(_f) D((_f) | ByteOp), D(_f) |
3005 | #define D2bvIP(_f, _i, _p) DIP((_f) | ByteOp, _i, _p), DIP(_f, _i, _p) | 3023 | #define D2bvIP(_f, _i, _p) DIP((_f) | ByteOp, _i, _p), DIP(_f, _i, _p) |
3006 | #define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e) | 3024 | #define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e) |
3025 | #define I2bvIP(_f, _e, _i, _p) \ | ||
3026 | IIP((_f) | ByteOp, _e, _i, _p), IIP(_f, _e, _i, _p) | ||
3007 | 3027 | ||
3008 | #define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e), \ | 3028 | #define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e), \ |
3009 | I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \ | 3029 | I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \ |
@@ -3217,13 +3237,13 @@ static struct opcode opcode_table[256] = { | |||
3217 | /* 0xE0 - 0xE7 */ | 3237 | /* 0xE0 - 0xE7 */ |
3218 | X3(I(SrcImmByte, em_loop)), | 3238 | X3(I(SrcImmByte, em_loop)), |
3219 | I(SrcImmByte, em_jcxz), | 3239 | I(SrcImmByte, em_jcxz), |
3220 | D2bvIP(SrcImmUByte | DstAcc, in, check_perm_in), | 3240 | I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in), |
3221 | D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out), | 3241 | I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out), |
3222 | /* 0xE8 - 0xEF */ | 3242 | /* 0xE8 - 0xEF */ |
3223 | D(SrcImm | Stack), D(SrcImm | ImplicitOps), | 3243 | D(SrcImm | Stack), D(SrcImm | ImplicitOps), |
3224 | I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), | 3244 | I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), |
3225 | D2bvIP(SrcDX | DstAcc, in, check_perm_in), | 3245 | I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in), |
3226 | D2bvIP(SrcAcc | DstDX, out, check_perm_out), | 3246 | I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out), |
3227 | /* 0xF0 - 0xF7 */ | 3247 | /* 0xF0 - 0xF7 */ |
3228 | N, DI(ImplicitOps, icebp), N, N, | 3248 | N, DI(ImplicitOps, icebp), N, N, |
3229 | DI(ImplicitOps | Priv, hlt), D(ImplicitOps), | 3249 | DI(ImplicitOps | Priv, hlt), D(ImplicitOps), |
@@ -3325,6 +3345,7 @@ static struct opcode twobyte_table[256] = { | |||
3325 | #undef D2bv | 3345 | #undef D2bv |
3326 | #undef D2bvIP | 3346 | #undef D2bvIP |
3327 | #undef I2bv | 3347 | #undef I2bv |
3348 | #undef I2bvIP | ||
3328 | #undef I6ALU | 3349 | #undef I6ALU |
3329 | 3350 | ||
3330 | static unsigned imm_size(struct x86_emulate_ctxt *ctxt) | 3351 | static unsigned imm_size(struct x86_emulate_ctxt *ctxt) |
@@ -3867,11 +3888,12 @@ special_insn: | |||
3867 | case 0x6c: /* insb */ | 3888 | case 0x6c: /* insb */ |
3868 | case 0x6d: /* insw/insd */ | 3889 | case 0x6d: /* insw/insd */ |
3869 | ctxt->src.val = ctxt->regs[VCPU_REGS_RDX]; | 3890 | ctxt->src.val = ctxt->regs[VCPU_REGS_RDX]; |
3870 | goto do_io_in; | 3891 | rc = em_in(ctxt); |
3892 | break; | ||
3871 | case 0x6e: /* outsb */ | 3893 | case 0x6e: /* outsb */ |
3872 | case 0x6f: /* outsw/outsd */ | 3894 | case 0x6f: /* outsw/outsd */ |
3873 | ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX]; | 3895 | ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX]; |
3874 | goto do_io_out; | 3896 | rc = em_out(ctxt); |
3875 | break; | 3897 | break; |
3876 | case 0x70 ... 0x7f: /* jcc (short) */ | 3898 | case 0x70 ... 0x7f: /* jcc (short) */ |
3877 | if (test_cc(ctxt->b, ctxt->eflags)) | 3899 | if (test_cc(ctxt->b, ctxt->eflags)) |
@@ -3915,12 +3937,6 @@ special_insn: | |||
3915 | ctxt->src.val = ctxt->regs[VCPU_REGS_RCX]; | 3937 | ctxt->src.val = ctxt->regs[VCPU_REGS_RCX]; |
3916 | rc = em_grp2(ctxt); | 3938 | rc = em_grp2(ctxt); |
3917 | break; | 3939 | break; |
3918 | case 0xe4: /* inb */ | ||
3919 | case 0xe5: /* in */ | ||
3920 | goto do_io_in; | ||
3921 | case 0xe6: /* outb */ | ||
3922 | case 0xe7: /* out */ | ||
3923 | goto do_io_out; | ||
3924 | case 0xe8: /* call (near) */ { | 3940 | case 0xe8: /* call (near) */ { |
3925 | long int rel = ctxt->src.val; | 3941 | long int rel = ctxt->src.val; |
3926 | ctxt->src.val = (unsigned long) ctxt->_eip; | 3942 | ctxt->src.val = (unsigned long) ctxt->_eip; |
@@ -3933,20 +3949,6 @@ special_insn: | |||
3933 | jmp_rel(ctxt, ctxt->src.val); | 3949 | jmp_rel(ctxt, ctxt->src.val); |
3934 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | 3950 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ |
3935 | break; | 3951 | break; |
3936 | case 0xec: /* in al,dx */ | ||
3937 | case 0xed: /* in (e/r)ax,dx */ | ||
3938 | do_io_in: | ||
3939 | if (!pio_in_emulated(ctxt, ctxt->dst.bytes, ctxt->src.val, | ||
3940 | &ctxt->dst.val)) | ||
3941 | goto done; /* IO is needed */ | ||
3942 | break; | ||
3943 | case 0xee: /* out dx,al */ | ||
3944 | case 0xef: /* out dx,(e/r)ax */ | ||
3945 | do_io_out: | ||
3946 | ops->pio_out_emulated(ctxt, ctxt->src.bytes, ctxt->dst.val, | ||
3947 | &ctxt->src.val, 1); | ||
3948 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | ||
3949 | break; | ||
3950 | case 0xf4: /* hlt */ | 3952 | case 0xf4: /* hlt */ |
3951 | ctxt->ops->halt(ctxt); | 3953 | ctxt->ops->halt(ctxt); |
3952 | break; | 3954 | break; |