From patchwork Mon Oct 26 16:22:03 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory Haskins X-Patchwork-Id: 55933 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9QGN6RW019387 for ; Mon, 26 Oct 2009 16:23:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753483AbZJZQWf (ORCPT ); Mon, 26 Oct 2009 12:22:35 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753698AbZJZQWR (ORCPT ); Mon, 26 Oct 2009 12:22:17 -0400 Received: from victor.provo.novell.com ([137.65.250.26]:46582 "EHLO victor.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753646AbZJZQWL (ORCPT ); Mon, 26 Oct 2009 12:22:11 -0400 Received: from dev.haskins.net (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by victor.provo.novell.com with ESMTP (TLS encrypted); Mon, 26 Oct 2009 10:22:07 -0600 Received: from dev.haskins.net (localhost [127.0.0.1]) by dev.haskins.net (Postfix) with ESMTP id 2D4124641FA; Mon, 26 Oct 2009 12:22:03 -0400 (EDT) From: Gregory Haskins Subject: [KVM PATCH v3 2/3] KVM: export lockless GSI attribute To: kvm@vger.kernel.org Cc: alacrityvm-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org Date: Mon, 26 Oct 2009 12:22:03 -0400 Message-ID: <20091026162202.23704.8727.stgit@dev.haskins.net> In-Reply-To: <20091026162148.23704.47286.stgit@dev.haskins.net> References: <20091026162148.23704.47286.stgit@dev.haskins.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 1fe135d..01151a6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -119,6 +119,7 @@ struct kvm_memory_slot { struct kvm_kernel_irq_routing_entry { u32 gsi; u32 type; + bool lockless; int (*set)(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, int irq_source_id, int level); union { @@ -420,6 +421,7 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, unsigned long *deliver_bitmask); #endif int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level); +int kvm_irq_check_lockless(struct kvm *kvm, u32 irq); void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); void kvm_register_irq_ack_notifier(struct kvm *kvm, struct kvm_irq_ack_notifier *kian); diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index db2553f..a7fd487 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -173,6 +173,35 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) return ret; } +int kvm_irq_check_lockless(struct kvm *kvm, u32 irq) +{ + struct kvm_kernel_irq_routing_entry *e; + struct kvm_irq_routing_table *irq_rt; + struct hlist_node *n; + int ret = -ENOENT; + int idx; + + idx = srcu_read_lock(&kvm->irq_routing.srcu); + irq_rt = rcu_dereference(kvm->irq_routing.table); + if (irq < irq_rt->nr_rt_entries) + hlist_for_each_entry(e, n, &irq_rt->map[irq], link) { + if (!e->lockless) { + /* + * all destinations need to be lockless to + * declare that the GSI as a whole is also + * lockless + */ + ret = 0; + break; + } + + ret = 1; + } + srcu_read_unlock(&kvm->irq_routing.srcu, idx); + + return ret; +} + void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) { struct kvm_irq_ack_notifier *kian; @@ -310,18 +339,22 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, int delta; struct kvm_kernel_irq_routing_entry *ei; struct hlist_node *n; + bool lockless = ue->type == KVM_IRQ_ROUTING_MSI; /* * Do not allow GSI to be mapped to the same irqchip more than once. * Allow only one to one mapping between GSI and MSI. + * Do not allow mixed lockless vs locked variants to coexist. */ hlist_for_each_entry(ei, n, &rt->map[ue->gsi], link) if (ei->type == KVM_IRQ_ROUTING_MSI || - ue->u.irqchip.irqchip == ei->irqchip.irqchip) + ue->u.irqchip.irqchip == ei->irqchip.irqchip || + ei->lockless != lockless) return r; e->gsi = ue->gsi; e->type = ue->type; + e->lockless = lockless; switch (ue->type) { case KVM_IRQ_ROUTING_IRQCHIP: delta = 0;