109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21107ba88SAlex Zeffertt /*
31107ba88SAlex Zeffertt * xenfs.c - a filesystem for passing info between the a domain and
41107ba88SAlex Zeffertt * the hypervisor.
51107ba88SAlex Zeffertt *
61107ba88SAlex Zeffertt * 2008-10-07 Alex Zeffertt Replaced /proc/xen/xenbus with xenfs filesystem
71107ba88SAlex Zeffertt * and /proc/xen compatibility mount point.
81107ba88SAlex Zeffertt * Turned xenfs into a loadable module.
91107ba88SAlex Zeffertt */
101107ba88SAlex Zeffertt
11283c0972SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12283c0972SJoe Perches
131107ba88SAlex Zeffertt #include <linux/kernel.h>
141107ba88SAlex Zeffertt #include <linux/errno.h>
151107ba88SAlex Zeffertt #include <linux/module.h>
161107ba88SAlex Zeffertt #include <linux/fs.h>
17*2345771fSDavid Howells #include <linux/fs_context.h>
181107ba88SAlex Zeffertt #include <linux/magic.h>
191107ba88SAlex Zeffertt
201ccbf534SJeremy Fitzhardinge #include <xen/xen.h>
21332f791dSJuergen Gross #include <xen/xenbus.h>
221ccbf534SJeremy Fitzhardinge
231107ba88SAlex Zeffertt #include "xenfs.h"
24d8414d3cSBastian Blank #include "../privcmd.h"
251107ba88SAlex Zeffertt
261107ba88SAlex Zeffertt #include <asm/xen/hypervisor.h>
271107ba88SAlex Zeffertt
281107ba88SAlex Zeffertt MODULE_DESCRIPTION("Xen filesystem");
291107ba88SAlex Zeffertt MODULE_LICENSE("GPL");
301107ba88SAlex Zeffertt
capabilities_read(struct file * file,char __user * buf,size_t size,loff_t * off)31818fd206SJeremy Fitzhardinge static ssize_t capabilities_read(struct file *file, char __user *buf,
32818fd206SJeremy Fitzhardinge size_t size, loff_t *off)
33818fd206SJeremy Fitzhardinge {
34818fd206SJeremy Fitzhardinge char *tmp = "";
35818fd206SJeremy Fitzhardinge
36818fd206SJeremy Fitzhardinge if (xen_initial_domain())
37818fd206SJeremy Fitzhardinge tmp = "control_d\n";
38818fd206SJeremy Fitzhardinge
39818fd206SJeremy Fitzhardinge return simple_read_from_buffer(buf, size, off, tmp, strlen(tmp));
40818fd206SJeremy Fitzhardinge }
41818fd206SJeremy Fitzhardinge
42818fd206SJeremy Fitzhardinge static const struct file_operations capabilities_file_ops = {
43818fd206SJeremy Fitzhardinge .read = capabilities_read,
446038f373SArnd Bergmann .llseek = default_llseek,
45818fd206SJeremy Fitzhardinge };
46818fd206SJeremy Fitzhardinge
xenfs_fill_super(struct super_block * sb,struct fs_context * fc)47*2345771fSDavid Howells static int xenfs_fill_super(struct super_block *sb, struct fs_context *fc)
481107ba88SAlex Zeffertt {
49cda37124SEric Biggers static const struct tree_descr xenfs_files[] = {
5078c3e473SAl Viro [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR },
51818fd206SJeremy Fitzhardinge { "capabilities", &capabilities_file_ops, S_IRUGO },
52d8414d3cSBastian Blank { "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR },
531107ba88SAlex Zeffertt {""},
541107ba88SAlex Zeffertt };
551107ba88SAlex Zeffertt
56cda37124SEric Biggers static const struct tree_descr xenfs_init_files[] = {
5778c3e473SAl Viro [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR },
5878c3e473SAl Viro { "capabilities", &capabilities_file_ops, S_IRUGO },
5978c3e473SAl Viro { "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR },
6078c3e473SAl Viro { "xsd_kva", &xsd_kva_file_ops, S_IRUSR|S_IWUSR},
6178c3e473SAl Viro { "xsd_port", &xsd_port_file_ops, S_IRUSR|S_IWUSR},
62a11f4f0aSBoris Ostrovsky #ifdef CONFIG_XEN_SYMS
63a11f4f0aSBoris Ostrovsky { "xensyms", &xensyms_ops, S_IRUSR},
64a11f4f0aSBoris Ostrovsky #endif
6578c3e473SAl Viro {""},
6678c3e473SAl Viro };
67655d406aSIan Campbell
6878c3e473SAl Viro return simple_fill_super(sb, XENFS_SUPER_MAGIC,
6978c3e473SAl Viro xen_initial_domain() ? xenfs_init_files : xenfs_files);
701107ba88SAlex Zeffertt }
711107ba88SAlex Zeffertt
xenfs_get_tree(struct fs_context * fc)72*2345771fSDavid Howells static int xenfs_get_tree(struct fs_context *fc)
731107ba88SAlex Zeffertt {
74*2345771fSDavid Howells return get_tree_single(fc, xenfs_fill_super);
75*2345771fSDavid Howells }
76*2345771fSDavid Howells
77*2345771fSDavid Howells static const struct fs_context_operations xenfs_context_ops = {
78*2345771fSDavid Howells .get_tree = xenfs_get_tree,
79*2345771fSDavid Howells };
80*2345771fSDavid Howells
xenfs_init_fs_context(struct fs_context * fc)81*2345771fSDavid Howells static int xenfs_init_fs_context(struct fs_context *fc)
82*2345771fSDavid Howells {
83*2345771fSDavid Howells fc->ops = &xenfs_context_ops;
84*2345771fSDavid Howells return 0;
851107ba88SAlex Zeffertt }
861107ba88SAlex Zeffertt
871107ba88SAlex Zeffertt static struct file_system_type xenfs_type = {
881107ba88SAlex Zeffertt .owner = THIS_MODULE,
891107ba88SAlex Zeffertt .name = "xenfs",
90*2345771fSDavid Howells .init_fs_context = xenfs_init_fs_context,
911107ba88SAlex Zeffertt .kill_sb = kill_litter_super,
921107ba88SAlex Zeffertt };
937f78e035SEric W. Biederman MODULE_ALIAS_FS("xenfs");
941107ba88SAlex Zeffertt
xenfs_init(void)951107ba88SAlex Zeffertt static int __init xenfs_init(void)
961107ba88SAlex Zeffertt {
979045d47eSJeremy Fitzhardinge if (xen_domain())
989045d47eSJeremy Fitzhardinge return register_filesystem(&xenfs_type);
999045d47eSJeremy Fitzhardinge
1001107ba88SAlex Zeffertt return 0;
1011107ba88SAlex Zeffertt }
1021107ba88SAlex Zeffertt
xenfs_exit(void)1031107ba88SAlex Zeffertt static void __exit xenfs_exit(void)
1041107ba88SAlex Zeffertt {
10543df95c4SJeremy Fitzhardinge if (xen_domain())
1061107ba88SAlex Zeffertt unregister_filesystem(&xenfs_type);
1071107ba88SAlex Zeffertt }
1081107ba88SAlex Zeffertt
1091107ba88SAlex Zeffertt module_init(xenfs_init);
1101107ba88SAlex Zeffertt module_exit(xenfs_exit);
1111107ba88SAlex Zeffertt
112