aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2011-11-22 01:16:54 -0500
committerAvi Kivity <avi@redhat.com>2011-12-27 04:17:23 -0500
commitd7841a4b1b6e8509881e1ec21c024c82ccf565a6 (patch)
tree632e7986e920d09a5b0654a0357022aa81ffe965
parent46199f33c29533e7ad2a7d2128dc30175d1d4157 (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.c54
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
2779static 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
2788static 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
2779static int em_cli(struct x86_emulate_ctxt *ctxt) 2797static 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
3330static unsigned imm_size(struct x86_emulate_ctxt *ctxt) 3351static 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;