Skip to content

Commit

Permalink
xen: add /proc/xen/xsd_{kva,port} to xenfs
Browse files Browse the repository at this point in the history
These are used by the userspace xenstore daemon, which runs in dom0.
Xenstored is what's behind the xenfs "xenbus" filesystem.

[ Impact: provide mapping and port to usermode for xenstore ]

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
  • Loading branch information
Ian Campbell authored and Jeremy Fitzhardinge committed Oct 20, 2010
1 parent cd07202 commit 655d406
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 2 deletions.
3 changes: 2 additions & 1 deletion drivers/xen/xenfs/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
obj-$(CONFIG_XENFS) += xenfs.o

xenfs-objs = super.o xenbus.o
xenfs-y = super.o xenbus.o
xenfs-$(CONFIG_XEN_DOM0) += xenstored.o
54 changes: 53 additions & 1 deletion drivers/xen/xenfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,46 @@
MODULE_DESCRIPTION("Xen filesystem");
MODULE_LICENSE("GPL");

static struct inode *xenfs_make_inode(struct super_block *sb, int mode)
{
struct inode *ret = new_inode(sb);

if (ret) {
ret->i_mode = mode;
ret->i_uid = ret->i_gid = 0;
ret->i_blocks = 0;
ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
}
return ret;
}

static struct dentry *xenfs_create_file(struct super_block *sb,
struct dentry *parent,
const char *name,
const struct file_operations *fops,
void *data,
int mode)
{
struct dentry *dentry;
struct inode *inode;

dentry = d_alloc_name(parent, name);
if (!dentry)
return NULL;

inode = xenfs_make_inode(sb, S_IFREG | mode);
if (!inode) {
dput(dentry);
return NULL;
}

inode->i_fop = fops;
inode->i_private = data;

d_add(dentry, inode);
return dentry;
}

static ssize_t capabilities_read(struct file *file, char __user *buf,
size_t size, loff_t *off)
{
Expand All @@ -45,8 +85,20 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
{ "capabilities", &capabilities_file_ops, S_IRUGO },
{""},
};
int rc;

rc = simple_fill_super(sb, XENFS_SUPER_MAGIC, xenfs_files);
if (rc < 0)
return rc;

if (xen_initial_domain()) {
xenfs_create_file(sb, sb->s_root, "xsd_kva",
&xsd_kva_file_ops, NULL, S_IRUSR|S_IWUSR);
xenfs_create_file(sb, sb->s_root, "xsd_port",
&xsd_port_file_ops, NULL, S_IRUSR|S_IWUSR);
}

return simple_fill_super(sb, XENFS_SUPER_MAGIC, xenfs_files);
return rc;
}

static int xenfs_get_sb(struct file_system_type *fs_type,
Expand Down
2 changes: 2 additions & 0 deletions drivers/xen/xenfs/xenfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
#define _XENFS_XENBUS_H

extern const struct file_operations xenbus_file_ops;
extern const struct file_operations xsd_kva_file_ops;
extern const struct file_operations xsd_port_file_ops;

#endif /* _XENFS_XENBUS_H */
68 changes: 68 additions & 0 deletions drivers/xen/xenfs/xenstored.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/fs.h>

#include <xen/page.h>

#include "xenfs.h"
#include "../xenbus/xenbus_comms.h"

static ssize_t xsd_read(struct file *file, char __user *buf,
size_t size, loff_t *off)
{
const char *str = (const char *)file->private_data;
return simple_read_from_buffer(buf, size, off, str, strlen(str));
}

static int xsd_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);
return 0;
}

static int xsd_kva_open(struct inode *inode, struct file *file)
{
file->private_data = (void *)kasprintf(GFP_KERNEL, "0x%p",
xen_store_interface);
if (!file->private_data)
return -ENOMEM;
return 0;
}

static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
{
size_t size = vma->vm_end - vma->vm_start;

if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
return -EINVAL;

if (remap_pfn_range(vma, vma->vm_start,
virt_to_pfn(xen_store_interface),
size, vma->vm_page_prot))
return -EAGAIN;

return 0;
}

const struct file_operations xsd_kva_file_ops = {
.open = xsd_kva_open,
.mmap = xsd_kva_mmap,
.read = xsd_read,
.release = xsd_release,
};

static int xsd_port_open(struct inode *inode, struct file *file)
{
file->private_data = (void *)kasprintf(GFP_KERNEL, "%d",
xen_store_evtchn);
if (!file->private_data)
return -ENOMEM;
return 0;
}

const struct file_operations xsd_port_file_ops = {
.open = xsd_port_open,
.read = xsd_read,
.release = xsd_release,
};

0 comments on commit 655d406

Please sign in to comment.