All of lore.kernel.org
 help / color / mirror / Atom feed
* [Virtio-for-kvm] [PATCH 2/13] [Mostly resend] virtio additions
@ 2007-12-21 15:17 Dor Laor
  0 siblings, 0 replies; only message in thread
From: Dor Laor @ 2007-12-21 15:17 UTC (permalink / raw)
  To: kvm-devel, virtualization, Rusty Russell, Anthony Liguori

 From 2334d90a3b9f8b9207163e9e0fad714e88a28771 Mon Sep 17 00:00:00 2001
From: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>
Date: Wed, 7 Nov 2007 21:02:22 +1100
Subject: [PATCH] virtio: An entropy device, as suggested by hpa.

Signed-off-by: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>
---
 Documentation/lguest/lguest.c       |   53 +++++++++++++++
 drivers/char/hw_random/Kconfig      |   10 +++
 drivers/char/hw_random/Makefile     |    1 +
 drivers/char/hw_random/virtio-rng.c |  124 
+++++++++++++++++++++++++++++++++++
 include/linux/virtio_rng.h          |    8 ++
 5 files changed, 196 insertions(+), 0 deletions(-)
 create mode 100644 drivers/char/hw_random/virtio-rng.c
 create mode 100644 include/linux/virtio_rng.h

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 029cc7c..314e977 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -41,6 +41,7 @@
 #include "linux/virtio_net.h"
 #include "linux/virtio_blk.h"
 #include "linux/virtio_console.h"
+#include "linux/virtio_rng.h"
 #include "linux/virtio_ring.h"
 #include "asm-x86/bootparam.h"
 /*L:110 We can ignore the 38 include files we need for this program, 
but I do
@@ -1535,6 +1536,54 @@ static void setup_block_file(const char *filename)
 }
 /* That's the end of device setup. */
 
+/* This is the routine which handles console input (ie. stdin). */
+static bool handle_rng_input(int fd, struct device *dev)
+{
+    int len;
+    unsigned int head, in_num, out_num;
+    struct iovec iov[dev->vq->vring.num];
+
+    printf("Got input on rng fd!\n");
+    /* First we need a buffer from the Guests's virtqueue. */
+    head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+
+    /* If they're not ready for input, stop listening to this file
+     * descriptor.  We'll start again once they add an input buffer. */
+    if (head == dev->vq->vring.num) {
+        printf("But no buffer!\n");
+        return false;
+    }
+
+    if (out_num)
+        errx(1, "Output buffers in rng?");
+
+    /* This is why we convert to iovecs: the readv() call uses them, and so
+     * it reads straight into the Guest's buffer. */
+    len = readv(dev->fd, iov, in_num);
+    /* Tell the Guest about the new input. */
+    add_used_and_trigger(fd, dev->vq, head, len);
+
+    /* Everything went OK! */
+    return true;
+}
+
+static void setup_rng(void)
+{
+    struct device *dev;
+    int fd;
+
+    fd = open_or_die("/dev/urandom", O_RDONLY);
+
+    /* The device responds to return from I/O thread. */
+    dev = new_device("rng", VIRTIO_ID_RNG, fd, handle_rng_input);
+
+    /* The device has one virtqueue, where the Guest places inbufs. */
+    add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
+
+    verbose("device %u: rng\n", devices.device_num);
+}
+/* That's the end of device setup. */
+
 /*L:220 Finally we reach the core of the Launcher, which runs the 
Guest, serves
  * its input and output, and finally, lays it to rest. */
 static void __attribute__((noreturn)) run_guest(int lguest_fd)
@@ -1581,6 +1630,7 @@ static struct option opts[] = {
     { "verbose", 0, NULL, 'v' },
     { "tunnet", 1, NULL, 't' },
     { "block", 1, NULL, 'b' },
+    { "rng", 0, NULL, 'r' },
     { "initrd", 1, NULL, 'i' },
     { NULL },
 };
@@ -1648,6 +1698,9 @@ int main(int argc, char *argv[])
         case 'b':
             setup_block_file(optarg);
             break;
+        case 'r':
+            setup_rng();
+            break;
         case 'i':
             initrd_name = optarg;
             break;
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 2d7cd48..de20022 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -105,3 +105,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
index c8b7300..b4940dd 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
 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
index 0000000..f723cc3
--- /dev/null
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -0,0 +1,124 @@
+/*
+ * Randomness driver for virtio
+ *  Copyright (C) 2007 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>
+
+static struct virtqueue *vq;
+static u32 random_data;
+static bool have_data;
+
+static bool random_recv_done(struct virtqueue *vq)
+{
+    have_data = true;
+
+    /* Don't suppress callbacks: there can't be any more since we
+     * have used up the only buffer. */
+    return true;
+}
+
+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);
+}
+
+static int virtio_data_present(struct hwrng *rng)
+{
+    return have_data;
+}
+
+static int virtio_data_read(struct hwrng *rng, u32 *data)
+{
+    BUG_ON(!have_data);
+    *data = random_data;
+
+    have_data = false;
+    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)
+{
+    hwrng_unregister(&virtio_hwrng);
+    vq->vq_ops->shutdown(vq);
+    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
index 0000000..331afb6
--- /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 */
-- 
1.5.3.3


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2007-12-21 15:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-21 15:17 [Virtio-for-kvm] [PATCH 2/13] [Mostly resend] virtio additions Dor Laor

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.