aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/svm.c5
-rw-r--r--arch/x86/kvm/x86.c43
3 files changed, 47 insertions, 2 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index da07e175dac8..77cb3f93de2b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1133,6 +1133,7 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr);
1133struct x86_emulate_ctxt; 1133struct x86_emulate_ctxt;
1134 1134
1135int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); 1135int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port);
1136int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size, unsigned short port);
1136void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); 1137void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
1137int kvm_emulate_halt(struct kvm_vcpu *vcpu); 1138int kvm_emulate_halt(struct kvm_vcpu *vcpu);
1138int kvm_vcpu_halt(struct kvm_vcpu *vcpu); 1139int kvm_vcpu_halt(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 4e462bb85723..5e64e656103c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2270,7 +2270,7 @@ static int io_interception(struct vcpu_svm *svm)
2270 ++svm->vcpu.stat.io_exits; 2270 ++svm->vcpu.stat.io_exits;
2271 string = (io_info & SVM_IOIO_STR_MASK) != 0; 2271 string = (io_info & SVM_IOIO_STR_MASK) != 0;
2272 in = (io_info & SVM_IOIO_TYPE_MASK) != 0; 2272 in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
2273 if (string || in) 2273 if (string)
2274 return emulate_instruction(vcpu, 0) == EMULATE_DONE; 2274 return emulate_instruction(vcpu, 0) == EMULATE_DONE;
2275 2275
2276 port = io_info >> 16; 2276 port = io_info >> 16;
@@ -2278,7 +2278,8 @@ static int io_interception(struct vcpu_svm *svm)
2278 svm->next_rip = svm->vmcb->control.exit_info_2; 2278 svm->next_rip = svm->vmcb->control.exit_info_2;
2279 skip_emulated_instruction(&svm->vcpu); 2279 skip_emulated_instruction(&svm->vcpu);
2280 2280
2281 return kvm_fast_pio_out(vcpu, size, port); 2281 return in ? kvm_fast_pio_in(vcpu, size, port)
2282 : kvm_fast_pio_out(vcpu, size, port);
2282} 2283}
2283 2284
2284static int nmi_interception(struct vcpu_svm *svm) 2285static int nmi_interception(struct vcpu_svm *svm)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6f9c9ad13f88..ec59301f5192 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5615,6 +5615,49 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
5615} 5615}
5616EXPORT_SYMBOL_GPL(kvm_fast_pio_out); 5616EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
5617 5617
5618static int complete_fast_pio_in(struct kvm_vcpu *vcpu)
5619{
5620 unsigned long val;
5621
5622 /* We should only ever be called with arch.pio.count equal to 1 */
5623 BUG_ON(vcpu->arch.pio.count != 1);
5624
5625 /* For size less than 4 we merge, else we zero extend */
5626 val = (vcpu->arch.pio.size < 4) ? kvm_register_read(vcpu, VCPU_REGS_RAX)
5627 : 0;
5628
5629 /*
5630 * Since vcpu->arch.pio.count == 1 let emulator_pio_in_emulated perform
5631 * the copy and tracing
5632 */
5633 emulator_pio_in_emulated(&vcpu->arch.emulate_ctxt, vcpu->arch.pio.size,
5634 vcpu->arch.pio.port, &val, 1);
5635 kvm_register_write(vcpu, VCPU_REGS_RAX, val);
5636
5637 return 1;
5638}
5639
5640int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size, unsigned short port)
5641{
5642 unsigned long val;
5643 int ret;
5644
5645 /* For size less than 4 we merge, else we zero extend */
5646 val = (size < 4) ? kvm_register_read(vcpu, VCPU_REGS_RAX) : 0;
5647
5648 ret = emulator_pio_in_emulated(&vcpu->arch.emulate_ctxt, size, port,
5649 &val, 1);
5650 if (ret) {
5651 kvm_register_write(vcpu, VCPU_REGS_RAX, val);
5652 return ret;
5653 }
5654
5655 vcpu->arch.complete_userspace_io = complete_fast_pio_in;
5656
5657 return 0;
5658}
5659EXPORT_SYMBOL_GPL(kvm_fast_pio_in);
5660
5618static int kvmclock_cpu_down_prep(unsigned int cpu) 5661static int kvmclock_cpu_down_prep(unsigned int cpu)
5619{ 5662{
5620 __this_cpu_write(cpu_tsc_khz, 0); 5663 __this_cpu_write(cpu_tsc_khz, 0);