From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58539) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTXw5-0001NO-Fy for qemu-devel@nongnu.org; Wed, 10 Feb 2016 11:48:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aTXw1-0007kM-2D for qemu-devel@nongnu.org; Wed, 10 Feb 2016 11:48:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47943) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTXw0-0007kI-Qr for qemu-devel@nongnu.org; Wed, 10 Feb 2016 11:48:08 -0500 References: <1453384873-14832-1-git-send-email-asmetanin@virtuozzo.com> <1453384873-14832-6-git-send-email-asmetanin@virtuozzo.com> From: Paolo Bonzini Message-ID: <56BB69C2.1080509@redhat.com> Date: Wed, 10 Feb 2016 17:48:02 +0100 MIME-Version: 1.0 In-Reply-To: <1453384873-14832-6-git-send-email-asmetanin@virtuozzo.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2 5/5] kvm/x86: Hyper-V VMBus hypercall userspace exit List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Andrey Smetanin , kvm@vger.kernel.org Cc: Gleb Natapov , Joerg Roedel , qemu-devel@nongnu.org, Roman Kagan , "Denis V. Lunev" , "K. Y. Srinivasan" , Haiyang Zhang On 21/01/2016 15:01, Andrey Smetanin wrote: > The patch implements KVM_EXIT_HYPERV userspace exit > functionality for Hyper-V VMBus hypercalls: > HV_X64_HCALL_POST_MESSAGE, HV_X64_HCALL_SIGNAL_EVENT. > > Changes v2: > * use KVM_EXIT_HYPERV for hypercalls > > Signed-off-by: Andrey Smetanin > Reviewed-by: Roman Kagan > CC: Gleb Natapov > CC: Paolo Bonzini > CC: Joerg Roedel > CC: "K. Y. Srinivasan" > CC: Haiyang Zhang > CC: Roman Kagan > CC: Denis V. Lunev > CC: qemu-devel@nongnu.org > --- > Documentation/virtual/kvm/api.txt | 6 ++++++ > arch/x86/kvm/hyperv.c | 29 ++++++++++++++++++++++------- > arch/x86/kvm/hyperv.h | 1 + > arch/x86/kvm/x86.c | 5 +++++ > include/uapi/linux/kvm.h | 6 ++++++ > 5 files changed, 40 insertions(+), 7 deletions(-) > > diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt > index 053f613..1bf1a07 100644 > --- a/Documentation/virtual/kvm/api.txt > +++ b/Documentation/virtual/kvm/api.txt > @@ -3339,6 +3339,7 @@ EOI was received. > > struct kvm_hyperv_exit { > #define KVM_EXIT_HYPERV_SYNIC 1 > +#define KVM_EXIT_HYPERV_HCALL 2 > __u32 type; > union { > struct { > @@ -3347,6 +3348,11 @@ EOI was received. > __u64 evt_page; > __u64 msg_page; > } synic; > + struct { > + __u64 input; > + __u64 result; > + __u64 params[2]; > + } hcall; > } u; > }; > /* KVM_EXIT_HYPERV */ > diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c > index e1daa8b..26ae973 100644 > --- a/arch/x86/kvm/hyperv.c > +++ b/arch/x86/kvm/hyperv.c > @@ -1093,6 +1093,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) > case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT: > kvm_vcpu_on_spin(vcpu); > break; > + case HV_X64_HCALL_POST_MESSAGE: > + case HV_X64_HCALL_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; > + return 0; > default: > res = HV_STATUS_INVALID_HYPERCALL_CODE; > break; > @@ -1100,12 +1108,19 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) > > set_result: > ret = res | (((u64)rep_done & 0xfff) << 32); > - if (longmode) { > - kvm_register_write(vcpu, VCPU_REGS_RAX, ret); > - } else { > - kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32); > - kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff); > - } > - > + kvm_hv_hypercall_set_result(vcpu, ret); > return 1; > } > + > +void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result) > +{ > + bool longmode; > + > + longmode = is_64_bit_mode(vcpu); > + if (longmode) > + kvm_register_write(vcpu, VCPU_REGS_RAX, result); > + else { > + kvm_register_write(vcpu, VCPU_REGS_RDX, result >> 32); > + kvm_register_write(vcpu, VCPU_REGS_RAX, result & 0xffffffff); > + } > +} > diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h > index 60eccd4..64a4a3b 100644 > --- a/arch/x86/kvm/hyperv.h > +++ b/arch/x86/kvm/hyperv.h > @@ -52,6 +52,7 @@ int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata); > > bool kvm_hv_hypercall_enabled(struct kvm *kvm); > int kvm_hv_hypercall(struct kvm_vcpu *vcpu); > +void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result); > > void kvm_hv_irq_routing_update(struct kvm *kvm); > int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint); > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index f53f5b1..e5c842b 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -6891,6 +6891,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) > } else > WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); > > + if (unlikely(kvm_run->exit_reason == KVM_EXIT_HYPERV) && > + kvm_run->hyperv.type == KVM_EXIT_HYPERV_HCALL) > + kvm_hv_hypercall_set_result(vcpu, > + kvm_run->hyperv.u.hcall.result); Can you use vcpu->arch.complete_userspace_io here instead? Otherwise looks great, thanks. Paolo > + > r = vcpu_run(vcpu); > > out: > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 9da9051..c5519a9 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -157,6 +157,7 @@ struct kvm_s390_skeys { > > struct kvm_hyperv_exit { > #define KVM_EXIT_HYPERV_SYNIC 1 > +#define KVM_EXIT_HYPERV_HCALL 2 > __u32 type; > union { > struct { > @@ -165,6 +166,11 @@ struct kvm_hyperv_exit { > __u64 evt_page; > __u64 msg_page; > } synic; > + struct { > + __u64 input; > + __u64 result; > + __u64 params[2]; > + } hcall; > } u; > }; > >