[PATCH RFC 12/39] KVM: x86/xen: store virq when assigning evtchn

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Enable virq offload to the hypervisor. The primary user for this is
the timer virq.

Signed-off-by: Joao Martins <joao.m.martins@xxxxxxxxxx>
---
 arch/x86/include/asm/kvm_host.h |  2 ++
 arch/x86/kvm/xen.c              | 23 ++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f31fcaf8fa7c..92b76127eb43 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -550,6 +550,8 @@ struct kvm_vcpu_xen {
 	gpa_t steal_time_addr;
 	struct vcpu_runstate_info *steal_time;
 	struct kvm_xen_callback cb;
+#define KVM_XEN_NR_VIRQS 24
+	unsigned int virq_to_port[KVM_XEN_NR_VIRQS];
 };
 
 struct kvm_vcpu_arch {
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index 1fbdfa7c4356..42c1fe01600d 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -101,6 +101,20 @@ static void kvm_xen_evtchnfd_upcall(struct kvm_vcpu *vcpu, struct evtchnfd *e)
 	kvm_xen_do_upcall(vcpu->kvm, e->vcpu, vx->cb.via, vx->cb.vector, 0);
 }
 
+void kvm_xen_set_virq(struct kvm *kvm, struct evtchnfd *evt)
+{
+	int virq = evt->virq.type;
+	struct kvm_vcpu_xen *vcpu_xen;
+	struct kvm_vcpu *vcpu;
+
+	vcpu = kvm_get_vcpu(kvm, evt->vcpu);
+	if (!vcpu)
+		return;
+
+	vcpu_xen = vcpu_to_xen_vcpu(vcpu);
+	vcpu_xen->virq_to_port[virq] = evt->port;
+}
+
 int kvm_xen_set_evtchn(struct kvm_kernel_irq_routing_entry *e,
 		   struct kvm *kvm, int irq_source_id, int level,
 		   bool line_status)
@@ -620,6 +634,10 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm, struct idr *port_to_evt,
 			return PTR_ERR(eventfd);
 	}
 
+	if (args->type == XEN_EVTCHN_TYPE_VIRQ &&
+	    args->virq.type >= KVM_XEN_NR_VIRQS)
+		return -EINVAL;
+
 	evtchnfd =  kzalloc(sizeof(struct evtchnfd), GFP_KERNEL);
 	if (!evtchnfd)
 		return -ENOMEM;
@@ -636,8 +654,11 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm, struct idr *port_to_evt,
 			GFP_KERNEL);
 	mutex_unlock(port_lock);
 
-	if (ret >= 0)
+	if (ret >= 0) {
+		if (evtchnfd->type == XEN_EVTCHN_TYPE_VIRQ)
+			kvm_xen_set_virq(kvm, evtchnfd);
 		return 0;
+	}
 
 	if (ret == -ENOSPC)
 		ret = -EEXIST;
-- 
2.11.0




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux