aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarian Rotariu <mrotariu@bitdefender.com>2018-04-30 05:23:01 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2018-05-11 05:21:10 -0400
commit6356ee0c9602004e0a3b4b2dad68ee2ee9385b17 (patch)
tree0b5978c4e855c52181e1a2004e95d87558794e79
parentddc9cfb79c1096a0855839631c091aa7e9602052 (diff)
x86: Delay skip of emulated hypercall instruction
The IP increment should be done after the hypercall emulation, after calling the various handlers. In this way, these handlers can accurately identify the the IP of the VMCALL if they need it. This patch keeps the same functionality for the Hyper-V handler which does not use the return code of the standard kvm_skip_emulated_instruction() call. Signed-off-by: Marian Rotariu <mrotariu@bitdefender.com> [Hyper-V hypercalls also need kvm_skip_emulated_instruction() - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/hyperv.c2
-rw-r--r--arch/x86/kvm/x86.c19
2 files changed, 12 insertions, 9 deletions
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 98618e397342..14dd5e5010a2 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1265,7 +1265,7 @@ static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
1265 struct kvm_run *run = vcpu->run; 1265 struct kvm_run *run = vcpu->run;
1266 1266
1267 kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result); 1267 kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result);
1268 return 1; 1268 return kvm_skip_emulated_instruction(vcpu);
1269} 1269}
1270 1270
1271static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param) 1271static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 51ecd381793b..44bd4a23b59c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6671,12 +6671,13 @@ void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
6671int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) 6671int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
6672{ 6672{
6673 unsigned long nr, a0, a1, a2, a3, ret; 6673 unsigned long nr, a0, a1, a2, a3, ret;
6674 int op_64_bit, r; 6674 int op_64_bit;
6675 6675
6676 r = kvm_skip_emulated_instruction(vcpu); 6676 if (kvm_hv_hypercall_enabled(vcpu->kvm)) {
6677 6677 if (!kvm_hv_hypercall(vcpu))
6678 if (kvm_hv_hypercall_enabled(vcpu->kvm)) 6678 return 0;
6679 return kvm_hv_hypercall(vcpu); 6679 goto out;
6680 }
6680 6681
6681 nr = kvm_register_read(vcpu, VCPU_REGS_RAX); 6682 nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
6682 a0 = kvm_register_read(vcpu, VCPU_REGS_RBX); 6683 a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
@@ -6697,7 +6698,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
6697 6698
6698 if (kvm_x86_ops->get_cpl(vcpu) != 0) { 6699 if (kvm_x86_ops->get_cpl(vcpu) != 0) {
6699 ret = -KVM_EPERM; 6700 ret = -KVM_EPERM;
6700 goto out; 6701 goto out_error;
6701 } 6702 }
6702 6703
6703 switch (nr) { 6704 switch (nr) {
@@ -6717,12 +6718,14 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
6717 ret = -KVM_ENOSYS; 6718 ret = -KVM_ENOSYS;
6718 break; 6719 break;
6719 } 6720 }
6720out: 6721out_error:
6721 if (!op_64_bit) 6722 if (!op_64_bit)
6722 ret = (u32)ret; 6723 ret = (u32)ret;
6723 kvm_register_write(vcpu, VCPU_REGS_RAX, ret); 6724 kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
6725
6726out:
6724 ++vcpu->stat.hypercalls; 6727 ++vcpu->stat.hypercalls;
6725 return r; 6728 return kvm_skip_emulated_instruction(vcpu);
6726} 6729}
6727EXPORT_SYMBOL_GPL(kvm_emulate_hypercall); 6730EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
6728 6731