From: Rusty Russell <rusty@rustcorp.com.au>
To: virtualization@lists.linux-foundation.org
Cc: Jeff Garzik <jeff@garzik.org>,
Herbert Xu <herbert@gondor.apana.org.au>,
Christian Borntraeger <borntraeger@de.ibm.com>,
LKML <linux-kernel@vger.kernel.org>, "H. Anvin" <hpa@zytor.com>
Subject: [PATCH 1/2] virtio: hardware random device
Date: Fri, 16 May 2008 15:31:44 +1000 [thread overview]
Message-ID: <200805161531.44725.rusty@rustcorp.com.au> (raw)
In-Reply-To: <200805160943.08788.rusty@rustcorp.com.au>
On Friday 16 May 2008 09:43:08 Rusty Russell wrote:
> Anyway, since there's interest, I'll drag virtio_rng from the bottom of the
> queue, apply Christian's fix (which I somehow missed before, sorry
> Christian), and re-post.
Actually, I didn't miss it. But I've polished the driver a little more,
here are the patches.
===
virtio: An entropy device, as suggested by hpa.
Note that by itself, having a "hardware" random generator does very
little: you should probably run "rngd" in your guest to feed this into
the kernel entropy pool.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
drivers/char/hw_random/Kconfig | 10 ++
drivers/char/hw_random/Makefile | 1
drivers/char/hw_random/virtio-rng.c | 143 ++++++++++++++++++++++++++++++++++++
include/linux/virtio_rng.h | 8 ++
4 files changed, 162 insertions(+)
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -112,3 +112,13 @@ config HW_RANDOM_PASEMI
If unsure, say Y.
+config HW_RANDOM_VIRTIO
+ tristate "VirtIO Random Number Generator support"
+ depends on HW_RANDOM && VIRTIO
+ ---help---
+ This driver provides kernel-side support for the virtual Random Number
+ Generator hardware.
+
+ To compile this driver as a module, choose M here: the
+ module will be called virtio-rng. If unsure, say N.
+
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx
obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
+obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -0,0 +1,143 @@
+/*
+ * Randomness driver for virtio
+ * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+#include <linux/virtio.h>
+#include <linux/virtio_rng.h>
+
+/* The host will fill any buffer we give it with sweet, sweet randomness. We
+ * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a
+ * time. */
+static struct virtqueue *vq;
+static u32 random_data[16];
+static unsigned int data_left;
+static DECLARE_COMPLETION(have_data);
+
+static void random_recv_done(struct virtqueue *vq)
+{
+ int len;
+
+ /* We never get spurious callbacks. */
+ if (!vq->vq_ops->get_buf(vq, &len))
+ BUG();
+
+ data_left = len / sizeof(random_data[0]);
+ complete(&have_data);
+}
+
+static void register_buffer(void)
+{
+ struct scatterlist sg;
+
+ sg_init_one(&sg, &random_data, sizeof(random_data));
+ /* There should always be room for one buffer. */
+ if (vq->vq_ops->add_buf(vq, &sg, 0, 1, &random_data) != 0)
+ BUG();
+ vq->vq_ops->kick(vq);
+}
+
+/* At least we don't udelay() in a loop like some other drivers. */
+static int virtio_data_present(struct hwrng *rng, int wait)
+{
+ if (data_left)
+ return 1;
+
+ if (!wait)
+ return 0;
+
+ wait_for_completion(&have_data);
+ return 1;
+}
+
+/* virtio_data_present() must have succeeded before this is called. */
+static int virtio_data_read(struct hwrng *rng, u32 *data)
+{
+ BUG_ON(!data_left);
+
+ *data = random_data[--data_left];
+
+ if (!data_left) {
+ init_completion(&have_data);
+ register_buffer();
+ }
+ return sizeof(*data);
+}
+
+static struct hwrng virtio_hwrng = {
+ .name = "virtio",
+ .data_present = virtio_data_present,
+ .data_read = virtio_data_read,
+};
+
+static int virtrng_probe(struct virtio_device *vdev)
+{
+ int err;
+
+ /* We expect a single virtqueue. */
+ vq = vdev->config->find_vq(vdev, 0, random_recv_done);
+ if (IS_ERR(vq))
+ return PTR_ERR(vq);
+
+ err = hwrng_register(&virtio_hwrng);
+ if (err) {
+ vdev->config->del_vq(vq);
+ return err;
+ }
+
+ register_buffer();
+ return 0;
+}
+
+static void virtrng_remove(struct virtio_device *vdev)
+{
+ vdev->config->reset(vdev);
+ hwrng_unregister(&virtio_hwrng);
+ vdev->config->del_vq(vq);
+}
+
+static struct virtio_device_id id_table[] = {
+ { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID },
+ { 0 },
+};
+
+static struct virtio_driver virtio_rng = {
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = virtrng_probe,
+ .remove = __devexit_p(virtrng_remove),
+};
+
+static int __init init(void)
+{
+ return register_virtio_driver(&virtio_rng);
+}
+
+static void __exit fini(void)
+{
+ unregister_virtio_driver(&virtio_rng);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio random number driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/virtio_rng.h b/include/linux/virtio_rng.h
new file mode 100644
--- /dev/null
+++ b/include/linux/virtio_rng.h
@@ -0,0 +1,8 @@
+#ifndef _LINUX_VIRTIO_RNG_H
+#define _LINUX_VIRTIO_RNG_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_rng */
+#define VIRTIO_ID_RNG 4
+
+#endif /* _LINUX_VIRTIO_RNG_H */
next prev parent reply other threads:[~2008-05-16 5:32 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-15 18:48 Virt RNG? Jeff Garzik
2008-05-15 19:53 ` Jeremy Fitzhardinge
2008-05-15 19:53 ` Jeremy Fitzhardinge
2008-05-15 20:26 ` Dor Laor
2008-05-15 20:31 ` Christian Borntraeger
2008-05-15 20:44 ` Jeff Garzik
2008-05-15 20:43 ` Jeff Dike
2008-05-15 23:43 ` Rusty Russell
2008-05-16 0:07 ` Henrique de Moraes Holschuh
2008-05-16 5:31 ` Rusty Russell [this message]
2008-05-16 5:39 ` [PATCH 2/2] lguest: virtio-rng support Rusty Russell
2008-05-16 5:39 ` Rusty Russell
2008-05-16 5:39 ` Rusty Russell
2008-05-16 10:49 ` Johannes Berg
2008-05-16 10:49 ` Johannes Berg
2008-05-16 20:25 ` H. Peter Anvin
2008-05-16 20:25 ` H. Peter Anvin
2008-05-17 4:46 ` Rusty Russell
2008-05-17 4:46 ` Rusty Russell
2008-05-17 4:50 ` H. Peter Anvin
2008-05-17 4:50 ` H. Peter Anvin
2008-05-17 6:28 ` Rusty Russell
2008-05-17 6:28 ` Rusty Russell
2008-05-17 6:43 ` Herbert Xu
2008-05-17 6:43 ` Herbert Xu
2008-05-17 7:43 ` Christian Borntraeger
2008-05-17 7:43 ` Christian Borntraeger
2008-05-17 15:56 ` H. Peter Anvin
2008-05-17 15:56 ` H. Peter Anvin
2008-05-17 7:47 ` Jeremy Fitzhardinge
2008-05-17 7:47 ` Jeremy Fitzhardinge
2008-05-19 9:05 ` Rusty Russell
2008-05-19 9:10 ` Jeremy Fitzhardinge
2008-05-19 9:10 ` Jeremy Fitzhardinge
2008-05-19 9:28 ` Rusty Russell
2008-05-19 9:45 ` Jeremy Fitzhardinge
2008-05-19 9:45 ` Jeremy Fitzhardinge
2008-05-19 9:28 ` Rusty Russell
2008-05-19 9:05 ` Rusty Russell
2008-05-17 15:57 ` H. Peter Anvin
2008-05-17 15:57 ` H. Peter Anvin
2008-05-16 7:31 ` [PATCH 1/2] virtio: hardware random device Christian Borntraeger
2008-05-16 7:31 ` Christian Borntraeger
2008-05-16 5:31 ` Rusty Russell
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=200805161531.44725.rusty@rustcorp.com.au \
--to=rusty@rustcorp.com.au \
--cc=borntraeger@de.ibm.com \
--cc=herbert@gondor.apana.org.au \
--cc=hpa@zytor.com \
--cc=jeff@garzik.org \
--cc=linux-kernel@vger.kernel.org \
--cc=virtualization@lists.linux-foundation.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.