If SynIC is disabled, there is nothing that userspace can do to
handle these exits; on the other hand, userspace probably will
not know about KVM_EXIT_HYPERV_HCALL and complain about it or
even exit.  Just prevent anything bad from happening by handling
the hypercall in KVM and returning an "invalid hypercall" code.

Fixes: 83326e43f27e9a8a501427a0060f8af519a39bb2
Cc: Andrey Smetanin <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
---
 arch/x86/kvm/hyperv.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index b960d9ea171f..9e2becd20a59 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1237,14 +1237,17 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                break;
        case HVCALL_POST_MESSAGE:
        case HVCALL_SIGNAL_EVENT:
-               vcpu->run->exit_reason = KVM_EXIT_HYPERV;
-               vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL;
-               vcpu->run->hyperv.u.hcall.input = param;
-               vcpu->run->hyperv.u.hcall.params[0] = ingpa;
-               vcpu->run->hyperv.u.hcall.params[1] = outgpa;
-               vcpu->arch.complete_userspace_io =
+               if (vcpu_to_synic(vcpu)->active) {
+                       vcpu->run->exit_reason = KVM_EXIT_HYPERV;
+                       vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL;
+                       vcpu->run->hyperv.u.hcall.input = param;
+                       vcpu->run->hyperv.u.hcall.params[0] = ingpa;
+                       vcpu->run->hyperv.u.hcall.params[1] = outgpa;
+                       vcpu->arch.complete_userspace_io =
                                kvm_hv_hypercall_complete_userspace;
-               return 0;
+                       return 0;
+               }
+               /* fall through */
        default:
                res = HV_STATUS_INVALID_HYPERCALL_CODE;
                break;
-- 
1.8.3.1

Reply via email to