# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 87ea297c1d3adeaa277cdef44bc03d399cf90a86
# Parent c7e4e2fc4f4a8d68366fb153ed20d2edd7fd750b
Add driver to use the kernel's xenbus connection from user-space.
The driver exports xs_talkv to user-space, allowing programs running in
the domain to use the kernel's xenbus connection. Intended use is driver
domain device configuration where the driver domain is not the domain
running xenstored.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
diff -r c7e4e2fc4f4a -r 87ea297c1d3a
linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile Sat Sep 3 16:32:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile Sat Sep 3 16:52:12 2005
@@ -4,3 +4,4 @@
xenbus-objs += xenbus_comms.o
xenbus-objs += xenbus_xs.o
xenbus-objs += xenbus_probe.o
+xenbus-objs += xenbus_dev.o
diff -r c7e4e2fc4f4a -r 87ea297c1d3a
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Sat Sep 3
16:32:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Sat Sep 3
16:52:12 2005
@@ -106,10 +106,10 @@
}
/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-static void *xs_talkv(enum xsd_sockmsg_type type,
- const struct kvec *iovec,
- unsigned int num_vecs,
- unsigned int *len)
+void *xs_talkv(enum xsd_sockmsg_type type,
+ const struct kvec *iovec,
+ unsigned int num_vecs,
+ unsigned int *len)
{
struct xsd_sockmsg msg;
void *ret = NULL;
@@ -557,7 +557,7 @@
BUG_ON(!w);
w->callback(w, node);
kfree(node);
- } else
+ } else if (node)
printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
PTR_ERR(node));
up(&xenbus_lock);
diff -r c7e4e2fc4f4a -r 87ea297c1d3a
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- /dev/null Sat Sep 3 16:32:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Sat Sep 3
16:52:12 2005
@@ -0,0 +1,186 @@
+/*
+ * xenbus_dev.c
+ *
+ * Driver giving user-space access to the kernel's xenbus connection
+ * to xenstore.
+ *
+ * Copyright (c) 2005, Christian Limpach
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/uio.h>
+#include <linux/notifier.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+
+#include "xenstored.h"
+#include "xenbus_comms.h"
+
+#include <asm/uaccess.h>
+#include <asm-xen/xenbus.h>
+#include <asm-xen/linux-public/xenbus_dev.h>
+#include <asm-xen/xen_proc.h>
+
+struct xenbus_dev_data {
+ int in_transaction;
+};
+
+static struct proc_dir_entry *xenbus_dev_intf;
+
+void *xs_talkv(enum xsd_sockmsg_type type, const struct kvec *iovec,
+ unsigned int num_vecs, unsigned int *len);
+
+static int xenbus_dev_talkv(struct xenbus_dev_data *u, unsigned long data)
+{
+ struct xenbus_dev_talkv xt;
+ unsigned int len;
+ void *resp, *base;
+ struct kvec *iovec;
+ int ret = -EFAULT, v = 0;
+
+ if (copy_from_user(&xt, (void *)data, sizeof(xt)))
+ return -EFAULT;
+
+ iovec = kmalloc(xt.num_vecs * sizeof(struct kvec), GFP_KERNEL);
+ if (iovec == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(iovec, xt.iovec,
+ xt.num_vecs * sizeof(struct kvec)))
+ goto out;
+
+ for (v = 0; v < xt.num_vecs; v++) {
+ base = iovec[v].iov_base;
+ iovec[v].iov_base = kmalloc(iovec[v].iov_len, GFP_KERNEL);
+ if (iovec[v].iov_base == NULL ||
+ copy_from_user(iovec[v].iov_base, base, iovec[v].iov_len))
+ {
+ if (iovec[v].iov_base)
+ kfree(iovec[v].iov_base);
+ else
+ ret = -ENOMEM;
+ v--;
+ goto out;
+ }
+ }
+
+ resp = xs_talkv(xt.type, iovec, xt.num_vecs, &len);
+ if (IS_ERR(resp)) {
+ ret = PTR_ERR(resp);
+ goto out;
+ }
+
+ switch (xt.type) {
+ case XS_TRANSACTION_START:
+ u->in_transaction = 1;
+ break;
+ case XS_TRANSACTION_END:
+ u->in_transaction = 0;
+ break;
+ default:
+ break;
+ }
+
+ ret = len;
+ if (len > xt.len)
+ len = xt.len;
+
+ if (copy_to_user(xt.buf, resp, len))
+ ret = -EFAULT;
+
+ kfree(resp);
+ out:
+ while (v-- > 0)
+ kfree(iovec[v].iov_base);
+ kfree(iovec);
+ return ret;
+}
+
+static int xenbus_dev_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long data)
+{
+ struct xenbus_dev_data *u = filp->private_data;
+ int ret = -ENOSYS;
+
+ switch (cmd) {
+ case IOCTL_XENBUS_DEV_TALKV:
+ ret = xenbus_dev_talkv(u, data);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int xenbus_dev_open(struct inode *inode, struct file *filp)
+{
+ struct xenbus_dev_data *u;
+
+ u = kmalloc(sizeof(*u), GFP_KERNEL);
+ if (u == NULL)
+ return -ENOMEM;
+
+ memset(u, 0, sizeof(*u));
+
+ filp->private_data = u;
+
+ down(&xenbus_lock);
+
+ return 0;
+}
+
+static int xenbus_dev_release(struct inode *inode, struct file *filp)
+{
+ struct xenbus_dev_data *u = filp->private_data;
+
+ if (u->in_transaction)
+ xenbus_transaction_end(1);
+
+ up(&xenbus_lock);
+
+ kfree(u);
+
+ return 0;
+}
+
+static struct file_operations xenbus_dev_file_ops = {
+ ioctl: xenbus_dev_ioctl,
+ open: xenbus_dev_open,
+ release: xenbus_dev_release
+};
+
+static int __init
+xenbus_dev_init(void)
+{
+ xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400);
+ if (xenbus_dev_intf)
+ xenbus_dev_intf->proc_fops = &xenbus_dev_file_ops;
+
+ return 0;
+}
+
+__initcall(xenbus_dev_init);
diff -r c7e4e2fc4f4a -r 87ea297c1d3a
linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h
--- /dev/null Sat Sep 3 16:32:53 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h Sat Sep
3 16:52:12 2005
@@ -0,0 +1,47 @@
+/*
+ * xenbus_dev.h
+ *
+ * Copyright (c) 2005, Christian Limpach
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _XENBUS_DEV_H_
+#define _XENBUS_DEV_H_
+
+struct xenbus_dev_talkv {
+ enum xsd_sockmsg_type type;
+ const struct kvec *iovec;
+ unsigned int num_vecs;
+ char *buf;
+ unsigned int len;
+};
+
+/*
+ * @cmd: IOCTL_XENBUS_DEV_TALKV
+ * @arg: struct xenbus_dev_talkv
+ * Return: 0 on success, error code on failure.
+ */
+#define IOCTL_XENBUS_DEV_TALKV \
+ _IOC(_IOC_NONE, 'X', 0, sizeof(struct xenbus_dev_talkv))
+
+#endif /* _XENBUS_DEV_H_ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|