diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 5 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 43 |
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); | |||
1133 | struct x86_emulate_ctxt; | 1133 | struct x86_emulate_ctxt; |
1134 | 1134 | ||
1135 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); | 1135 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); |
1136 | int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size, unsigned short port); | ||
1136 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); | 1137 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
1137 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); | 1138 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
1138 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu); | 1139 | int 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 | ||
2284 | static int nmi_interception(struct vcpu_svm *svm) | 2285 | static 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 | } |
5616 | EXPORT_SYMBOL_GPL(kvm_fast_pio_out); | 5616 | EXPORT_SYMBOL_GPL(kvm_fast_pio_out); |
5617 | 5617 | ||
5618 | static 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 | |||
5640 | int 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 | } | ||
5659 | EXPORT_SYMBOL_GPL(kvm_fast_pio_in); | ||
5660 | |||
5618 | static int kvmclock_cpu_down_prep(unsigned int cpu) | 5661 | static 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); |