qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Liu Ping Fan <qemulist@gmail.com>
To: kvm@vger.kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	qemu-devel@nongnu.org, Gleb Natapov <gleb@redhat.com>
Subject: [Qemu-devel] [PATCH] KVM: IRQFD: equip irqfd and resamplefd with polarity
Date: Thu, 12 Sep 2013 13:28:27 +0800	[thread overview]
Message-ID: <1378963707-1259-1-git-send-email-pingfank@linux.vnet.ibm.com> (raw)

Nowadays, irqfd can emulate trigger mode, but it can not emulate
trigger polarity. While in some cases, ioapic ioredtbl[x] expects
_low_ active. So equipping irqfd with the ability. Correspondingly,
resamplefd will have the same polarity as irqfd.

Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
This helps to step around making the interrupt component re-entrance
in qemu
---
 include/linux/kvm_host.h |  1 +
 include/uapi/linux/kvm.h |  2 ++
 virt/kvm/eventfd.c       | 32 ++++++++++++++++++++++----------
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index a63d83e..0b8c3b1 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -678,6 +678,7 @@ bool kvm_is_mmio_pfn(pfn_t pfn);
 struct kvm_irq_ack_notifier {
 	struct hlist_node link;
 	unsigned gsi;
+	int polarity; /* 0 high active */
 	void (*irq_acked)(struct kvm_irq_ack_notifier *kian);
 };
 
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index acccd08..bba3a1b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -740,6 +740,8 @@ struct kvm_xen_hvm_config {
  * emlation.  See Documentation/virtual/kvm/api.txt.
  */
 #define KVM_IRQFD_FLAG_RESAMPLE (1 << 1)
+/* 0: high-active */
+#define KVM_IRQFD_FLAG_POLARITY (1<<2)
 
 struct kvm_irqfd {
 	__u32 fd;
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 1550637..865c656 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -77,6 +77,7 @@ struct _irqfd {
 	struct kvm_kernel_irq_routing_entry __rcu *irq_entry;
 	/* Used for level IRQ fast-path */
 	int gsi;
+	int polarity; /* 0 high active */
 	struct work_struct inject;
 	/* The resampler used by this irqfd (resampler-only) */
 	struct _irqfd_resampler *resampler;
@@ -100,13 +101,13 @@ irqfd_inject(struct work_struct *work)
 	struct kvm *kvm = irqfd->kvm;
 
 	if (!irqfd->resampler) {
-		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1,
-				false);
-		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0,
-				false);
+		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi,
+				!irqfd->polarity, false);
+		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi,
+				!!irqfd->polarity, false);
 	} else
 		kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
-			    irqfd->gsi, 1, false);
+			    irqfd->gsi, !irqfd->polarity, false);
 }
 
 /*
@@ -123,7 +124,8 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
 	resampler = container_of(kian, struct _irqfd_resampler, notifier);
 
 	kvm_set_irq(resampler->kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
-		    resampler->notifier.gsi, 0, false);
+		resampler->notifier.gsi,
+		!!resampler->notifier.polarity, false);
 
 	rcu_read_lock();
 
@@ -148,7 +150,7 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd)
 		list_del(&resampler->link);
 		kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier);
 		kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
-			    resampler->notifier.gsi, 0, false);
+			    resampler->notifier.gsi, !!irqfd->polarity, false);
 		kfree(resampler);
 	}
 
@@ -302,6 +304,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 
 	irqfd->kvm = kvm;
 	irqfd->gsi = args->gsi;
+	irqfd->polarity = !!(args->flags & KVM_IRQFD_FLAG_POLARITY);
 	INIT_LIST_HEAD(&irqfd->list);
 	INIT_WORK(&irqfd->inject, irqfd_inject);
 	INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
@@ -337,8 +340,15 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 		list_for_each_entry(resampler,
 				    &kvm->irqfds.resampler_list, link) {
 			if (resampler->notifier.gsi == irqfd->gsi) {
-				irqfd->resampler = resampler;
-				break;
+				if (likely(resampler->notifier.polarity ==
+					irqfd->polarity)) {
+					irqfd->resampler = resampler;
+					break;
+				} else {
+					ret = -EBUSY;
+					mutex_unlock(&kvm->irqfds.resampler_lock);
+					goto fail;
+				}
 			}
 		}
 
@@ -353,6 +363,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 			resampler->kvm = kvm;
 			INIT_LIST_HEAD(&resampler->list);
 			resampler->notifier.gsi = irqfd->gsi;
+			resampler->notifier.polarity = irqfd->polarity;
 			resampler->notifier.irq_acked = irqfd_resampler_ack;
 			INIT_LIST_HEAD(&resampler->link);
 
@@ -489,7 +500,8 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
 int
 kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	if (args->flags & ~(KVM_IRQFD_FLAG_DEASSIGN | KVM_IRQFD_FLAG_RESAMPLE))
+	if (args->flags & ~(KVM_IRQFD_FLAG_DEASSIGN | KVM_IRQFD_FLAG_RESAMPLE
+		| KVM_IRQFD_FLAG_POLARITY))
 		return -EINVAL;
 
 	if (args->flags & KVM_IRQFD_FLAG_DEASSIGN)
-- 
1.8.1.4

                 reply	other threads:[~2013-09-12  5:28 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1378963707-1259-1-git-send-email-pingfank@linux.vnet.ibm.com \
    --to=qemulist@gmail.com \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).