^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * xenfs.c - a filesystem for passing info between the a domain and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * the hypervisor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * 2008-10-07 Alex Zeffertt Replaced /proc/xen/xenbus with xenfs filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * and /proc/xen compatibility mount point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Turned xenfs into a loadable module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <xen/xen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <xen/xenbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "xenfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "../privcmd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/xen/hypervisor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) MODULE_DESCRIPTION("Xen filesystem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static ssize_t capabilities_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) size_t size, loff_t *off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) char *tmp = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (xen_initial_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) tmp = "control_d\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return simple_read_from_buffer(buf, size, off, tmp, strlen(tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const struct file_operations capabilities_file_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .read = capabilities_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int xenfs_fill_super(struct super_block *sb, struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const struct tree_descr xenfs_files[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) { "capabilities", &capabilities_file_ops, S_IRUGO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) { "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {""},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static const struct tree_descr xenfs_init_files[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { "capabilities", &capabilities_file_ops, S_IRUGO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { "xsd_kva", &xsd_kva_file_ops, S_IRUSR|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { "xsd_port", &xsd_port_file_ops, S_IRUSR|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #ifdef CONFIG_XEN_SYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) { "xensyms", &xensyms_ops, S_IRUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {""},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return simple_fill_super(sb, XENFS_SUPER_MAGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) xen_initial_domain() ? xenfs_init_files : xenfs_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int xenfs_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return get_tree_single(fc, xenfs_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct fs_context_operations xenfs_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .get_tree = xenfs_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int xenfs_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) fc->ops = &xenfs_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static struct file_system_type xenfs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .name = "xenfs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .init_fs_context = xenfs_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .kill_sb = kill_litter_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MODULE_ALIAS_FS("xenfs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int __init xenfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (xen_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return register_filesystem(&xenfs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void __exit xenfs_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (xen_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unregister_filesystem(&xenfs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) module_init(xenfs_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) module_exit(xenfs_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)