aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-18 09:20:24 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:16:26 -0400
commit7972995b0c346de76fe260ce0fd6bcc8ffab724a (patch)
treea2522988d8cd465b836c0a32399d8eeb7a3ed545 /arch/x86/kvm/emulate.c
parentcf8f70bfe38b326bb80b10f76d6544f571040229 (diff)
KVM: x86 emulator: Move string pio emulation into emulator.c
Currently emulation is done outside of emulator so things like doing ins/outs to/from mmio are broken it also makes it hard (if not impossible) to implement single stepping in the future. The implementation in this patch is not efficient since it exits to userspace for each IO while previous implementation did 'ins' in batches. Further patch that implements pio in string read ahead address this problem. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c48
1 files changed, 15 insertions, 33 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 2d095ce9dc87..2c66e097d916 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -153,8 +153,8 @@ static u32 opcode_table[256] = {
153 0, 0, 0, 0, 153 0, 0, 0, 0,
154 /* 0x68 - 0x6F */ 154 /* 0x68 - 0x6F */
155 SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, 155 SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
156 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ 156 DstDI | ByteOp | Mov | String, DstDI | Mov | String, /* insb, insw/insd */
157 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ 157 SrcSI | ByteOp | ImplicitOps | String, SrcSI | ImplicitOps | String, /* outsb, outsw/outsd */
158 /* 0x70 - 0x77 */ 158 /* 0x70 - 0x77 */
159 SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, 159 SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
160 SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, 160 SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
@@ -2615,47 +2615,29 @@ special_insn:
2615 break; 2615 break;
2616 case 0x6c: /* insb */ 2616 case 0x6c: /* insb */
2617 case 0x6d: /* insw/insd */ 2617 case 0x6d: /* insw/insd */
2618 c->dst.bytes = min(c->dst.bytes, 4u);
2618 if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], 2619 if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
2619 (c->d & ByteOp) ? 1 : c->op_bytes)) { 2620 c->dst.bytes)) {
2620 kvm_inject_gp(ctxt->vcpu, 0); 2621 kvm_inject_gp(ctxt->vcpu, 0);
2621 goto done; 2622 goto done;
2622 } 2623 }
2623 if (kvm_emulate_pio_string(ctxt->vcpu, 2624 if (!ops->pio_in_emulated(c->dst.bytes, c->regs[VCPU_REGS_RDX],
2624 1, 2625 &c->dst.val, 1, ctxt->vcpu))
2625 (c->d & ByteOp) ? 1 : c->op_bytes, 2626 goto done; /* IO is needed, skip writeback */
2626 c->rep_prefix ? 2627 break;
2627 address_mask(c, c->regs[VCPU_REGS_RCX]) : 1,
2628 (ctxt->eflags & EFLG_DF),
2629 register_address(c, es_base(ctxt),
2630 c->regs[VCPU_REGS_RDI]),
2631 c->rep_prefix,
2632 c->regs[VCPU_REGS_RDX]) == 0) {
2633 c->eip = saved_eip;
2634 return -1;
2635 }
2636 return 0;
2637 case 0x6e: /* outsb */ 2628 case 0x6e: /* outsb */
2638 case 0x6f: /* outsw/outsd */ 2629 case 0x6f: /* outsw/outsd */
2630 c->src.bytes = min(c->src.bytes, 4u);
2639 if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], 2631 if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
2640 (c->d & ByteOp) ? 1 : c->op_bytes)) { 2632 c->src.bytes)) {
2641 kvm_inject_gp(ctxt->vcpu, 0); 2633 kvm_inject_gp(ctxt->vcpu, 0);
2642 goto done; 2634 goto done;
2643 } 2635 }
2644 if (kvm_emulate_pio_string(ctxt->vcpu, 2636 ops->pio_out_emulated(c->src.bytes, c->regs[VCPU_REGS_RDX],
2645 0, 2637 &c->src.val, 1, ctxt->vcpu);
2646 (c->d & ByteOp) ? 1 : c->op_bytes, 2638
2647 c->rep_prefix ? 2639 c->dst.type = OP_NONE; /* nothing to writeback */
2648 address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, 2640 break;
2649 (ctxt->eflags & EFLG_DF),
2650 register_address(c,
2651 seg_override_base(ctxt, c),
2652 c->regs[VCPU_REGS_RSI]),
2653 c->rep_prefix,
2654 c->regs[VCPU_REGS_RDX]) == 0) {
2655 c->eip = saved_eip;
2656 return -1;
2657 }
2658 return 0;
2659 case 0x70 ... 0x7f: /* jcc (short) */ 2641 case 0x70 ... 0x7f: /* jcc (short) */
2660 if (test_cc(c->b, ctxt->eflags)) 2642 if (test_cc(c->b, ctxt->eflags))
2661 jmp_rel(c, c->src.val); 2643 jmp_rel(c, c->src.val);