aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-18 09:20:23 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:16:25 -0400
commitcf8f70bfe38b326bb80b10f76d6544f571040229 (patch)
treed646456d773a887ca592d174b3d45a57d2779d85 /arch/x86/kvm/x86.c
parentd9271123a46011af26da680baeb7fdf67b498abf (diff)
KVM: x86 emulator: fix in/out emulation.
in/out emulation is broken now. The breakage is different depending on where IO device resides. If it is in userspace emulator reports emulation failure since it incorrectly interprets kvm_emulate_pio() return value. If IO device is in the kernel emulation of 'in' will do nothing since kvm_emulate_pio() stores result directly into vcpu registers, so emulator will overwrite result of emulation during commit of shadowed register. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c213
1 files changed, 131 insertions, 82 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f69854c8f339..6624ad13ee99 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3404,6 +3404,86 @@ emul_write:
3404 return emulator_write_emulated(addr, new, bytes, vcpu); 3404 return emulator_write_emulated(addr, new, bytes, vcpu);
3405} 3405}
3406 3406
3407static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
3408{
3409 /* TODO: String I/O for in kernel device */
3410 int r;
3411
3412 if (vcpu->arch.pio.in)
3413 r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
3414 vcpu->arch.pio.size, pd);
3415 else
3416 r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
3417 vcpu->arch.pio.port, vcpu->arch.pio.size,
3418 pd);
3419 return r;
3420}
3421
3422
3423static int emulator_pio_in_emulated(int size, unsigned short port, void *val,
3424 unsigned int count, struct kvm_vcpu *vcpu)
3425{
3426 if (vcpu->arch.pio.cur_count)
3427 goto data_avail;
3428
3429 trace_kvm_pio(1, port, size, 1);
3430
3431 vcpu->arch.pio.port = port;
3432 vcpu->arch.pio.in = 1;
3433 vcpu->arch.pio.string = 0;
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;
3438
3439 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
3440 data_avail:
3441 memcpy(val, vcpu->arch.pio_data, size * count);
3442 vcpu->arch.pio.cur_count = 0;
3443 return 1;
3444 }
3445
3446 vcpu->run->exit_reason = KVM_EXIT_IO;
3447 vcpu->run->io.direction = KVM_EXIT_IO_IN;
3448 vcpu->run->io.size = size;
3449 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
3450 vcpu->run->io.count = count;
3451 vcpu->run->io.port = port;
3452
3453 return 0;
3454}
3455
3456static int emulator_pio_out_emulated(int size, unsigned short port,
3457 const void *val, unsigned int count,
3458 struct kvm_vcpu *vcpu)
3459{
3460 trace_kvm_pio(0, port, size, 1);
3461
3462 vcpu->arch.pio.port = port;
3463 vcpu->arch.pio.in = 0;
3464 vcpu->arch.pio.string = 0;
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;
3469
3470 memcpy(vcpu->arch.pio_data, val, size * count);
3471
3472 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
3473 vcpu->arch.pio.cur_count = 0;
3474 return 1;
3475 }
3476
3477 vcpu->run->exit_reason = KVM_EXIT_IO;
3478 vcpu->run->io.direction = KVM_EXIT_IO_OUT;
3479 vcpu->run->io.size = size;
3480 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
3481 vcpu->run->io.count = count;
3482 vcpu->run->io.port = port;
3483
3484 return 0;
3485}
3486
3407static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) 3487static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
3408{ 3488{
3409 return kvm_x86_ops->get_segment_base(vcpu, seg); 3489 return kvm_x86_ops->get_segment_base(vcpu, seg);
@@ -3597,6 +3677,8 @@ static struct x86_emulate_ops emulate_ops = {
3597 .read_emulated = emulator_read_emulated, 3677 .read_emulated = emulator_read_emulated,
3598 .write_emulated = emulator_write_emulated, 3678 .write_emulated = emulator_write_emulated,
3599 .cmpxchg_emulated = emulator_cmpxchg_emulated, 3679 .cmpxchg_emulated = emulator_cmpxchg_emulated,
3680 .pio_in_emulated = emulator_pio_in_emulated,
3681 .pio_out_emulated = emulator_pio_out_emulated,
3600 .get_cached_descriptor = emulator_get_cached_descriptor, 3682 .get_cached_descriptor = emulator_get_cached_descriptor,
3601 .set_cached_descriptor = emulator_set_cached_descriptor, 3683 .set_cached_descriptor = emulator_set_cached_descriptor,
3602 .get_segment_selector = emulator_get_segment_selector, 3684 .get_segment_selector = emulator_get_segment_selector,
@@ -3704,6 +3786,12 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
3704 if (vcpu->arch.pio.string) 3786 if (vcpu->arch.pio.string)
3705 return EMULATE_DO_MMIO; 3787 return EMULATE_DO_MMIO;
3706 3788
3789 if (vcpu->arch.pio.cur_count && !vcpu->arch.pio.string) {
3790 if (!vcpu->arch.pio.in)
3791 vcpu->arch.pio.cur_count = 0;
3792 return EMULATE_DO_MMIO;
3793 }
3794
3707 if (r || vcpu->mmio_is_write) { 3795 if (r || vcpu->mmio_is_write) {
3708 run->exit_reason = KVM_EXIT_MMIO; 3796 run->exit_reason = KVM_EXIT_MMIO;
3709 run->mmio.phys_addr = vcpu->mmio_phys_addr; 3797 run->mmio.phys_addr = vcpu->mmio_phys_addr;
@@ -3760,43 +3848,36 @@ int complete_pio(struct kvm_vcpu *vcpu)
3760 int r; 3848 int r;
3761 unsigned long val; 3849 unsigned long val;
3762 3850
3763 if (!io->string) { 3851 if (io->in) {
3764 if (io->in) { 3852 r = pio_copy_data(vcpu);
3765 val = kvm_register_read(vcpu, VCPU_REGS_RAX); 3853 if (r)
3766 memcpy(&val, vcpu->arch.pio_data, io->size); 3854 goto out;
3767 kvm_register_write(vcpu, VCPU_REGS_RAX, val); 3855 }
3768 }
3769 } else {
3770 if (io->in) {
3771 r = pio_copy_data(vcpu);
3772 if (r)
3773 goto out;
3774 }
3775 3856
3776 delta = 1; 3857 delta = 1;
3777 if (io->rep) { 3858 if (io->rep) {
3778 delta *= io->cur_count; 3859 delta *= io->cur_count;
3779 /* 3860 /*
3780 * The size of the register should really depend on 3861 * The size of the register should really depend on
3781 * current address size. 3862 * current address size.
3782 */ 3863 */
3783 val = kvm_register_read(vcpu, VCPU_REGS_RCX); 3864 val = kvm_register_read(vcpu, VCPU_REGS_RCX);
3784 val -= delta; 3865 val -= delta;
3785 kvm_register_write(vcpu, VCPU_REGS_RCX, val); 3866 kvm_register_write(vcpu, VCPU_REGS_RCX, val);
3786 } 3867 }
3787 if (io->down) 3868 if (io->down)
3788 delta = -delta; 3869 delta = -delta;
3789 delta *= io->size; 3870 delta *= io->size;
3790 if (io->in) { 3871 if (io->in) {
3791 val = kvm_register_read(vcpu, VCPU_REGS_RDI); 3872 val = kvm_register_read(vcpu, VCPU_REGS_RDI);
3792 val += delta; 3873 val += delta;
3793 kvm_register_write(vcpu, VCPU_REGS_RDI, val); 3874 kvm_register_write(vcpu, VCPU_REGS_RDI, val);
3794 } else { 3875 } else {
3795 val = kvm_register_read(vcpu, VCPU_REGS_RSI); 3876 val = kvm_register_read(vcpu, VCPU_REGS_RSI);
3796 val += delta; 3877 val += delta;
3797 kvm_register_write(vcpu, VCPU_REGS_RSI, val); 3878 kvm_register_write(vcpu, VCPU_REGS_RSI, val);
3798 }
3799 } 3879 }
3880
3800out: 3881out:
3801 io->count -= io->cur_count; 3882 io->count -= io->cur_count;
3802 io->cur_count = 0; 3883 io->cur_count = 0;
@@ -3804,21 +3885,6 @@ out:
3804 return 0; 3885 return 0;
3805} 3886}
3806 3887
3807static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
3808{
3809 /* TODO: String I/O for in kernel device */
3810 int r;
3811
3812 if (vcpu->arch.pio.in)
3813 r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
3814 vcpu->arch.pio.size, pd);
3815 else
3816 r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
3817 vcpu->arch.pio.port, vcpu->arch.pio.size,
3818 pd);
3819 return r;
3820}
3821
3822static int pio_string_write(struct kvm_vcpu *vcpu) 3888static int pio_string_write(struct kvm_vcpu *vcpu)
3823{ 3889{
3824 struct kvm_pio_request *io = &vcpu->arch.pio; 3890 struct kvm_pio_request *io = &vcpu->arch.pio;
@@ -3836,36 +3902,6 @@ static int pio_string_write(struct kvm_vcpu *vcpu)
3836 return r; 3902 return r;
3837} 3903}
3838 3904
3839int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port)
3840{
3841 unsigned long val;
3842
3843 trace_kvm_pio(!in, port, size, 1);
3844
3845 vcpu->run->exit_reason = KVM_EXIT_IO;
3846 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
3847 vcpu->run->io.size = vcpu->arch.pio.size = size;
3848 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
3849 vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = 1;
3850 vcpu->run->io.port = vcpu->arch.pio.port = port;
3851 vcpu->arch.pio.in = in;
3852 vcpu->arch.pio.string = 0;
3853 vcpu->arch.pio.down = 0;
3854 vcpu->arch.pio.rep = 0;
3855
3856 if (!vcpu->arch.pio.in) {
3857 val = kvm_register_read(vcpu, VCPU_REGS_RAX);
3858 memcpy(vcpu->arch.pio_data, &val, 4);
3859 }
3860
3861 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
3862 complete_pio(vcpu);
3863 return 1;
3864 }
3865 return 0;
3866}
3867EXPORT_SYMBOL_GPL(kvm_emulate_pio);
3868
3869int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, 3905int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
3870 int size, unsigned long count, int down, 3906 int size, unsigned long count, int down,
3871 gva_t address, int rep, unsigned port) 3907 gva_t address, int rep, unsigned port)
@@ -3931,6 +3967,16 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
3931} 3967}
3932EXPORT_SYMBOL_GPL(kvm_emulate_pio_string); 3968EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
3933 3969
3970int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
3971{
3972 unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
3973 int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu);
3974 /* do not return to emulator after return from userspace */
3975 vcpu->arch.pio.cur_count = 0;
3976 return ret;
3977}
3978EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
3979
3934static void bounce_off(void *info) 3980static void bounce_off(void *info)
3935{ 3981{
3936 /* nothing */ 3982 /* nothing */
@@ -4661,9 +4707,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
4661 4707
4662 if (vcpu->arch.pio.cur_count) { 4708 if (vcpu->arch.pio.cur_count) {
4663 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 4709 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
4664 r = complete_pio(vcpu); 4710 if (!vcpu->arch.pio.string)
4711 r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE);
4712 else
4713 r = complete_pio(vcpu);
4665 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); 4714 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
4666 if (r) 4715 if (r == EMULATE_DO_MMIO)
4667 goto out; 4716 goto out;
4668 } 4717 }
4669 if (vcpu->mmio_needed) { 4718 if (vcpu->mmio_needed) {