aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h8
-rw-r--r--arch/x86/kvm/emulate.c48
-rw-r--r--arch/x86/kvm/x86.c206
3 files changed, 32 insertions, 230 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 776d3e202b56..26c629a062db 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -224,14 +224,9 @@ struct kvm_pv_mmu_op_buffer {
224 224
225struct kvm_pio_request { 225struct kvm_pio_request {
226 unsigned long count; 226 unsigned long count;
227 int cur_count;
228 gva_t guest_gva;
229 int in; 227 int in;
230 int port; 228 int port;
231 int size; 229 int size;
232 int string;
233 int down;
234 int rep;
235}; 230};
236 231
237/* 232/*
@@ -591,9 +586,6 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
591struct x86_emulate_ctxt; 586struct x86_emulate_ctxt;
592 587
593int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); 588int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port);
594int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
595 int size, unsigned long count, int down,
596 gva_t address, int rep, unsigned port);
597void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); 589void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
598int kvm_emulate_halt(struct kvm_vcpu *vcpu); 590int kvm_emulate_halt(struct kvm_vcpu *vcpu);
599int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); 591int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address);
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);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6624ad13ee99..658e8e8155cb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3150,18 +3150,17 @@ static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes,
3150 return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); 3150 return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
3151} 3151}
3152 3152
3153static int kvm_write_guest_virt_helper(gva_t addr, void *val, 3153static int kvm_write_guest_virt_system(gva_t addr, void *val,
3154 unsigned int bytes, 3154 unsigned int bytes,
3155 struct kvm_vcpu *vcpu, u32 access, 3155 struct kvm_vcpu *vcpu,
3156 u32 *error) 3156 u32 *error)
3157{ 3157{
3158 void *data = val; 3158 void *data = val;
3159 int r = X86EMUL_CONTINUE; 3159 int r = X86EMUL_CONTINUE;
3160 3160
3161 access |= PFERR_WRITE_MASK;
3162
3163 while (bytes) { 3161 while (bytes) {
3164 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error); 3162 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr,
3163 PFERR_WRITE_MASK, error);
3165 unsigned offset = addr & (PAGE_SIZE-1); 3164 unsigned offset = addr & (PAGE_SIZE-1);
3166 unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); 3165 unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
3167 int ret; 3166 int ret;
@@ -3184,20 +3183,6 @@ out:
3184 return r; 3183 return r;
3185} 3184}
3186 3185
3187static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
3188 struct kvm_vcpu *vcpu, u32 *error)
3189{
3190 u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
3191 return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, access, error);
3192}
3193
3194static int kvm_write_guest_virt_system(gva_t addr, void *val,
3195 unsigned int bytes,
3196 struct kvm_vcpu *vcpu, u32 *error)
3197{
3198 return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
3199}
3200
3201static int emulator_read_emulated(unsigned long addr, 3186static int emulator_read_emulated(unsigned long addr,
3202 void *val, 3187 void *val,
3203 unsigned int bytes, 3188 unsigned int bytes,
@@ -3423,23 +3408,20 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
3423static int emulator_pio_in_emulated(int size, unsigned short port, void *val, 3408static int emulator_pio_in_emulated(int size, unsigned short port, void *val,
3424 unsigned int count, struct kvm_vcpu *vcpu) 3409 unsigned int count, struct kvm_vcpu *vcpu)
3425{ 3410{
3426 if (vcpu->arch.pio.cur_count) 3411 if (vcpu->arch.pio.count)
3427 goto data_avail; 3412 goto data_avail;
3428 3413
3429 trace_kvm_pio(1, port, size, 1); 3414 trace_kvm_pio(1, port, size, 1);
3430 3415
3431 vcpu->arch.pio.port = port; 3416 vcpu->arch.pio.port = port;
3432 vcpu->arch.pio.in = 1; 3417 vcpu->arch.pio.in = 1;
3433 vcpu->arch.pio.string = 0; 3418 vcpu->arch.pio.count = count;
3434 vcpu->arch.pio.down = 0;
3435 vcpu->arch.pio.rep = 0;
3436 vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count;
3437 vcpu->arch.pio.size = size; 3419 vcpu->arch.pio.size = size;
3438 3420
3439 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { 3421 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
3440 data_avail: 3422 data_avail:
3441 memcpy(val, vcpu->arch.pio_data, size * count); 3423 memcpy(val, vcpu->arch.pio_data, size * count);
3442 vcpu->arch.pio.cur_count = 0; 3424 vcpu->arch.pio.count = 0;
3443 return 1; 3425 return 1;
3444 } 3426 }
3445 3427
@@ -3461,16 +3443,13 @@ static int emulator_pio_out_emulated(int size, unsigned short port,
3461 3443
3462 vcpu->arch.pio.port = port; 3444 vcpu->arch.pio.port = port;
3463 vcpu->arch.pio.in = 0; 3445 vcpu->arch.pio.in = 0;
3464 vcpu->arch.pio.string = 0; 3446 vcpu->arch.pio.count = count;
3465 vcpu->arch.pio.down = 0;
3466 vcpu->arch.pio.rep = 0;
3467 vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count;
3468 vcpu->arch.pio.size = size; 3447 vcpu->arch.pio.size = size;
3469 3448
3470 memcpy(vcpu->arch.pio_data, val, size * count); 3449 memcpy(vcpu->arch.pio_data, val, size * count);
3471 3450
3472 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { 3451 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
3473 vcpu->arch.pio.cur_count = 0; 3452 vcpu->arch.pio.count = 0;
3474 return 1; 3453 return 1;
3475 } 3454 }
3476 3455
@@ -3717,7 +3696,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
3717 cache_all_regs(vcpu); 3696 cache_all_regs(vcpu);
3718 3697
3719 vcpu->mmio_is_write = 0; 3698 vcpu->mmio_is_write = 0;
3720 vcpu->arch.pio.string = 0;
3721 3699
3722 if (!(emulation_type & EMULTYPE_NO_DECODE)) { 3700 if (!(emulation_type & EMULTYPE_NO_DECODE)) {
3723 int cs_db, cs_l; 3701 int cs_db, cs_l;
@@ -3783,12 +3761,9 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
3783 if (r == 0) 3761 if (r == 0)
3784 kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask); 3762 kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask);
3785 3763
3786 if (vcpu->arch.pio.string) 3764 if (vcpu->arch.pio.count) {
3787 return EMULATE_DO_MMIO;
3788
3789 if (vcpu->arch.pio.cur_count && !vcpu->arch.pio.string) {
3790 if (!vcpu->arch.pio.in) 3765 if (!vcpu->arch.pio.in)
3791 vcpu->arch.pio.cur_count = 0; 3766 vcpu->arch.pio.count = 0;
3792 return EMULATE_DO_MMIO; 3767 return EMULATE_DO_MMIO;
3793 } 3768 }
3794 3769
@@ -3821,158 +3796,12 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
3821} 3796}
3822EXPORT_SYMBOL_GPL(emulate_instruction); 3797EXPORT_SYMBOL_GPL(emulate_instruction);
3823 3798
3824static int pio_copy_data(struct kvm_vcpu *vcpu)
3825{
3826 void *p = vcpu->arch.pio_data;
3827 gva_t q = vcpu->arch.pio.guest_gva;
3828 unsigned bytes;
3829 int ret;
3830 u32 error_code;
3831
3832 bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
3833 if (vcpu->arch.pio.in)
3834 ret = kvm_write_guest_virt(q, p, bytes, vcpu, &error_code);
3835 else
3836 ret = kvm_read_guest_virt(q, p, bytes, vcpu, &error_code);
3837
3838 if (ret == X86EMUL_PROPAGATE_FAULT)
3839 kvm_inject_page_fault(vcpu, q, error_code);
3840
3841 return ret;
3842}
3843
3844int complete_pio(struct kvm_vcpu *vcpu)
3845{
3846 struct kvm_pio_request *io = &vcpu->arch.pio;
3847 long delta;
3848 int r;
3849 unsigned long val;
3850
3851 if (io->in) {
3852 r = pio_copy_data(vcpu);
3853 if (r)
3854 goto out;
3855 }
3856
3857 delta = 1;
3858 if (io->rep) {
3859 delta *= io->cur_count;
3860 /*
3861 * The size of the register should really depend on
3862 * current address size.
3863 */
3864 val = kvm_register_read(vcpu, VCPU_REGS_RCX);
3865 val -= delta;
3866 kvm_register_write(vcpu, VCPU_REGS_RCX, val);
3867 }
3868 if (io->down)
3869 delta = -delta;
3870 delta *= io->size;
3871 if (io->in) {
3872 val = kvm_register_read(vcpu, VCPU_REGS_RDI);
3873 val += delta;
3874 kvm_register_write(vcpu, VCPU_REGS_RDI, val);
3875 } else {
3876 val = kvm_register_read(vcpu, VCPU_REGS_RSI);
3877 val += delta;
3878 kvm_register_write(vcpu, VCPU_REGS_RSI, val);
3879 }
3880
3881out:
3882 io->count -= io->cur_count;
3883 io->cur_count = 0;
3884
3885 return 0;
3886}
3887
3888static int pio_string_write(struct kvm_vcpu *vcpu)
3889{
3890 struct kvm_pio_request *io = &vcpu->arch.pio;
3891 void *pd = vcpu->arch.pio_data;
3892 int i, r = 0;
3893
3894 for (i = 0; i < io->cur_count; i++) {
3895 if (kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
3896 io->port, io->size, pd)) {
3897 r = -EOPNOTSUPP;
3898 break;
3899 }
3900 pd += io->size;
3901 }
3902 return r;
3903}
3904
3905int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
3906 int size, unsigned long count, int down,
3907 gva_t address, int rep, unsigned port)
3908{
3909 unsigned now, in_page;
3910 int ret = 0;
3911
3912 trace_kvm_pio(!in, port, size, count);
3913
3914 vcpu->run->exit_reason = KVM_EXIT_IO;
3915 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
3916 vcpu->run->io.size = vcpu->arch.pio.size = size;
3917 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
3918 vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count;
3919 vcpu->run->io.port = vcpu->arch.pio.port = port;
3920 vcpu->arch.pio.in = in;
3921 vcpu->arch.pio.string = 1;
3922 vcpu->arch.pio.down = down;
3923 vcpu->arch.pio.rep = rep;
3924
3925 if (!count) {
3926 kvm_x86_ops->skip_emulated_instruction(vcpu);
3927 return 1;
3928 }
3929
3930 if (!down)
3931 in_page = PAGE_SIZE - offset_in_page(address);
3932 else
3933 in_page = offset_in_page(address) + size;
3934 now = min(count, (unsigned long)in_page / size);
3935 if (!now)
3936 now = 1;
3937 if (down) {
3938 /*
3939 * String I/O in reverse. Yuck. Kill the guest, fix later.
3940 */
3941 pr_unimpl(vcpu, "guest string pio down\n");
3942 kvm_inject_gp(vcpu, 0);
3943 return 1;
3944 }
3945 vcpu->run->io.count = now;
3946 vcpu->arch.pio.cur_count = now;
3947
3948 if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count)
3949 kvm_x86_ops->skip_emulated_instruction(vcpu);
3950
3951 vcpu->arch.pio.guest_gva = address;
3952
3953 if (!vcpu->arch.pio.in) {
3954 /* string PIO write */
3955 ret = pio_copy_data(vcpu);
3956 if (ret == X86EMUL_PROPAGATE_FAULT)
3957 return 1;
3958 if (ret == 0 && !pio_string_write(vcpu)) {
3959 complete_pio(vcpu);
3960 if (vcpu->arch.pio.count == 0)
3961 ret = 1;
3962 }
3963 }
3964 /* no string PIO read support yet */
3965
3966 return ret;
3967}
3968EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
3969
3970int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) 3799int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
3971{ 3800{
3972 unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX); 3801 unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
3973 int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu); 3802 int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu);
3974 /* do not return to emulator after return from userspace */ 3803 /* do not return to emulator after return from userspace */
3975 vcpu->arch.pio.cur_count = 0; 3804 vcpu->arch.pio.count = 0;
3976 return ret; 3805 return ret;
3977} 3806}
3978EXPORT_SYMBOL_GPL(kvm_fast_pio_out); 3807EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
@@ -4705,15 +4534,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
4705 if (!irqchip_in_kernel(vcpu->kvm)) 4534 if (!irqchip_in_kernel(vcpu->kvm))
4706 kvm_set_cr8(vcpu, kvm_run->cr8); 4535 kvm_set_cr8(vcpu, kvm_run->cr8);
4707 4536
4708 if (vcpu->arch.pio.cur_count) { 4537 if (vcpu->arch.pio.count) {
4709 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 4538 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
4710 if (!vcpu->arch.pio.string) 4539 r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE);
4711 r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE);
4712 else
4713 r = complete_pio(vcpu);
4714 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); 4540 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
4715 if (r == EMULATE_DO_MMIO) 4541 if (r == EMULATE_DO_MMIO) {
4542 r = 0;
4716 goto out; 4543 goto out;
4544 }
4717 } 4545 }
4718 if (vcpu->mmio_needed) { 4546 if (vcpu->mmio_needed) {
4719 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); 4547 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);