From: "Michael S. Tsirkin" <mst@redhat.com>
To: Gregory Haskins <ghaskins@novell.com>,
kvm@vger.kernel.org, avi@redhat.com, mtosatti@redhat.com
Subject: [PATCH 3/3] virt_irq: virtual device for injecting interrupts
Date: Sun, 31 May 2009 21:59:32 +0300 [thread overview]
Message-ID: <20090531185932.GD10043@redhat.com> (raw)
In-Reply-To: <cover.1243796281.git.mst@sherwood.(none)>
virt_irq is an alternative to irqfd interface, based
on the virt core infrastructure, which also serves
as an example of virt core usage.
The main advantage here compared to irqfd is the use of fd
created by the virt core, which avoids any possibility of
deadlock issues with eventfd and kvm file descriptors
referencing each other.
As a minor positive side effect, we don't need an
extra lock and don't need to schedule work to inject
the interrupt.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/virt/Kconfig | 6 +++
drivers/virt/Makefile | 1 +
drivers/virt/virt_irq.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/virt_irq.h | 19 +++++++++++
4 files changed, 104 insertions(+), 0 deletions(-)
create mode 100644 drivers/virt/virt_irq.c
create mode 100644 include/linux/virt_irq.h
diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index ace7b2e..060c8da 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -3,3 +3,9 @@ config VIRT_CORE
---help---
Core support for binding kernel drivers to virtual devices.
Make sure to also select any drivers you wish to use.
+
+config VIRT_IRQ
+ tristate "Virtual device for injecting interrupts from userspace"
+ depends on VIRT_CORE
+ ---help---
+ Simple virtual device that supports injecting interrupts.
diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
index 7a77047..0072530 100644
--- a/drivers/virt/Makefile
+++ b/drivers/virt/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_VIRT_CORE) += virt_core.o
+obj-$(CONFIG_VIRT_IRQ) += virt_irq.o
diff --git a/drivers/virt/virt_irq.c b/drivers/virt/virt_irq.c
new file mode 100644
index 0000000..c10087e
--- /dev/null
+++ b/drivers/virt/virt_irq.c
@@ -0,0 +1,78 @@
+/*
+ * Virt irq device: simple virtual device for interrupt injection.
+ *
+ * Copyright (c) 2009 Red Hat Inc.
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/virt.h>
+#include <linux/virt_irq.h>
+
+struct virt_irq_dev {
+ int irq;
+};
+
+static ssize_t virt_irq_write(struct file *f, const char __user *p, size_t s,
+ loff_t *o)
+{
+ struct virt_dev *dev = virt_dev_get(f);
+ struct virt_irq_dev *vdev = dev->driver_ctx;
+ int r = dev->hypervisor->set_irq(dev->hypervisor, vdev->irq, 0, 1);
+ dev->hypervisor->set_irq(dev->hypervisor, vdev->irq, 0, 0);
+ return r < 0 ? r : 0;
+}
+
+int virt_irq_probe(struct virt_driver *driver, struct virt_dev *dev,
+ const void *id, int id_len)
+{
+ struct virt_irq_dev *vdev;
+ const struct virt_irq_id *irq_id;
+ if (!dev->hypervisor->set_irq)
+ return -ENODEV;
+ if (id_len != sizeof id)
+ return -ENODEV;
+ irq_id = id;
+ if (memcmp(irq_id->name, "irq", sizeof irq_id->name))
+ return -ENODEV;
+
+ vdev = kmalloc(sizeof *vdev, GFP_KERNEL);
+ if (!vdev)
+ return -ENOMEM;
+ vdev->irq = irq_id->irq;
+ dev->driver_ctx = vdev;
+ return 0;
+}
+
+void virt_irq_remove(struct virt_driver *driver, struct virt_dev *dev)
+{
+ kfree(dev->driver_ctx);
+}
+
+static struct file_operations virt_irq_fops = {
+ .owner = THIS_MODULE,
+ .write = virt_irq_write,
+};
+
+static struct virt_driver virt_irq_driver = {
+ .name = "virt_irq",
+ .device_probe = virt_irq_probe,
+ .device_remove = virt_irq_remove,
+};
+
+static int __init virt_irq_init(void)
+{
+ virt_driver_register(&virt_irq_driver, &virt_irq_fops);
+ return 0;
+}
+
+static void __exit virt_irq_cleanup(void)
+{
+ virt_driver_unregister(&virt_irq_driver);
+}
+
+module_init(virt_irq_init);
+module_exit(virt_irq_cleanup);
diff --git a/include/linux/virt_irq.h b/include/linux/virt_irq.h
new file mode 100644
index 0000000..6b3421d
--- /dev/null
+++ b/include/linux/virt_irq.h
@@ -0,0 +1,19 @@
+#ifndef LINUX_VIRT_IRQ_H
+#define LINUX_VIRT_IRQ_H
+
+#include <linux/types.h>
+
+/* Format for IRQ device id */
+
+struct virt_irq_id {
+ __u8 name[4]; /* Must be "irq\0" */
+ __u32 irq;
+};
+
+static inline void virt_irq_id_init(struct virt_irq_id *id, int irq)
+{
+ memcpy(id->name, "irq", sizeof id->name);
+ id->irq = irq;
+}
+
+#endif
--
1.6.3.1.175.g3be7e0
prev parent reply other threads:[~2009-05-31 18:59 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1243796281.git.mst@sherwood.(none)>
2009-05-31 18:59 ` [PATCH 1/3] virt-core: binding together drivers and hypervisors Michael S. Tsirkin
2009-05-31 18:59 ` [PATCH 2/3] kvm: virtual device support Michael S. Tsirkin
2009-05-31 18:59 ` Michael S. Tsirkin [this message]
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=20090531185932.GD10043@redhat.com \
--to=mst@redhat.com \
--cc=avi@redhat.com \
--cc=ghaskins@novell.com \
--cc=kvm@vger.kernel.org \
--cc=mtosatti@redhat.com \
/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