x86: Delay skip of emulated hypercall instruction
authorMarian Rotariu <mrotariu@bitdefender.com>
Mon, 30 Apr 2018 09:23:01 +0000 (12:23 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 11 May 2018 09:21:10 +0000 (11:21 +0200)
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>
arch/x86/kvm/hyperv.c
arch/x86/kvm/x86.c

index 98618e397342297cdff01a94975147ee543419c0..14dd5e5010a2db38f5415356e66c6261cd6164e4 100644 (file)
@@ -1265,7 +1265,7 @@ static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
        struct kvm_run *run = vcpu->run;
 
        kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result);
-       return 1;
+       return kvm_skip_emulated_instruction(vcpu);
 }
 
 static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
index 51ecd381793b4f281563779b97a04e5063572fdf..44bd4a23b59ccc5287e0e082bdceea078f7f4b8c 100644 (file)
@@ -6671,12 +6671,13 @@ void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 {
        unsigned long nr, a0, a1, a2, a3, ret;
-       int op_64_bit, r;
+       int op_64_bit;
 
-       r = kvm_skip_emulated_instruction(vcpu);
-
-       if (kvm_hv_hypercall_enabled(vcpu->kvm))
-               return kvm_hv_hypercall(vcpu);
+       if (kvm_hv_hypercall_enabled(vcpu->kvm)) {
+               if (!kvm_hv_hypercall(vcpu))
+                       return 0;
+               goto out;
+       }
 
        nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
        a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
@@ -6697,7 +6698,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 
        if (kvm_x86_ops->get_cpl(vcpu) != 0) {
                ret = -KVM_EPERM;
-               goto out;
+               goto out_error;
        }
 
        switch (nr) {
@@ -6717,12 +6718,14 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
                ret = -KVM_ENOSYS;
                break;
        }
-out:
+out_error:
        if (!op_64_bit)
                ret = (u32)ret;
        kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
+
+out:
        ++vcpu->stat.hypercalls;
-       return r;
+       return kvm_skip_emulated_instruction(vcpu);
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);