1 /* 2 * xenfs.c - a filesystem for passing info between the a domain and 3 * the hypervisor. 4 * 5 * 2008-10-07 Alex Zeffertt Replaced /proc/xen/xenbus with xenfs filesystem 6 * and /proc/xen compatibility mount point. 7 * Turned xenfs into a loadable module. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/errno.h> 12 #include <linux/module.h> 13 #include <linux/fs.h> 14 #include <linux/magic.h> 15 16 #include <xen/xen.h> 17 18 #include "xenfs.h" 19 20 #include <asm/xen/hypervisor.h> 21 22 MODULE_DESCRIPTION("Xen filesystem"); 23 MODULE_LICENSE("GPL"); 24 25 static struct inode *xenfs_make_inode(struct super_block *sb, int mode) 26 { 27 struct inode *ret = new_inode(sb); 28 29 if (ret) { 30 ret->i_mode = mode; 31 ret->i_uid = ret->i_gid = 0; 32 ret->i_blocks = 0; 33 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; 34 } 35 return ret; 36 } 37 38 static struct dentry *xenfs_create_file(struct super_block *sb, 39 struct dentry *parent, 40 const char *name, 41 const struct file_operations *fops, 42 void *data, 43 int mode) 44 { 45 struct dentry *dentry; 46 struct inode *inode; 47 48 dentry = d_alloc_name(parent, name); 49 if (!dentry) 50 return NULL; 51 52 inode = xenfs_make_inode(sb, S_IFREG | mode); 53 if (!inode) { 54 dput(dentry); 55 return NULL; 56 } 57 58 inode->i_fop = fops; 59 inode->i_private = data; 60 61 d_add(dentry, inode); 62 return dentry; 63 } 64 65 static ssize_t capabilities_read(struct file *file, char __user *buf, 66 size_t size, loff_t *off) 67 { 68 char *tmp = ""; 69 70 if (xen_initial_domain()) 71 tmp = "control_d\n"; 72 73 return simple_read_from_buffer(buf, size, off, tmp, strlen(tmp)); 74 } 75 76 static const struct file_operations capabilities_file_ops = { 77 .read = capabilities_read, 78 .llseek = default_llseek, 79 }; 80 81 static int xenfs_fill_super(struct super_block *sb, void *data, int silent) 82 { 83 static struct tree_descr xenfs_files[] = { 84 [1] = {}, 85 { "xenbus", &xenbus_file_ops, S_IRUSR|S_IWUSR }, 86 { "capabilities", &capabilities_file_ops, S_IRUGO }, 87 { "privcmd", &privcmd_file_ops, S_IRUSR|S_IWUSR }, 88 {""}, 89 }; 90 int rc; 91 92 rc = simple_fill_super(sb, XENFS_SUPER_MAGIC, xenfs_files); 93 if (rc < 0) 94 return rc; 95 96 if (xen_initial_domain()) { 97 xenfs_create_file(sb, sb->s_root, "xsd_kva", 98 &xsd_kva_file_ops, NULL, S_IRUSR|S_IWUSR); 99 xenfs_create_file(sb, sb->s_root, "xsd_port", 100 &xsd_port_file_ops, NULL, S_IRUSR|S_IWUSR); 101 } 102 103 return rc; 104 } 105 106 static struct dentry *xenfs_mount(struct file_system_type *fs_type, 107 int flags, const char *dev_name, 108 void *data) 109 { 110 return mount_single(fs_type, flags, data, xenfs_fill_super); 111 } 112 113 static struct file_system_type xenfs_type = { 114 .owner = THIS_MODULE, 115 .name = "xenfs", 116 .mount = xenfs_mount, 117 .kill_sb = kill_litter_super, 118 }; 119 120 static int __init xenfs_init(void) 121 { 122 if (xen_domain()) 123 return register_filesystem(&xenfs_type); 124 125 printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n"); 126 return 0; 127 } 128 129 static void __exit xenfs_exit(void) 130 { 131 if (xen_domain()) 132 unregister_filesystem(&xenfs_type); 133 } 134 135 module_init(xenfs_init); 136 module_exit(xenfs_exit); 137 138