1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2 3 #include <linux/slab.h> 4 #include <linux/types.h> 5 #include <linux/mm.h> 6 #include <linux/fs.h> 7 #include <linux/miscdevice.h> 8 #include <linux/module.h> 9 #include <linux/capability.h> 10 11 #include <xen/xen.h> 12 #include <xen/page.h> 13 #include <xen/xenbus.h> 14 #include <xen/xenbus_dev.h> 15 #include <xen/grant_table.h> 16 #include <xen/events.h> 17 #include <asm/xen/hypervisor.h> 18 19 #include "xenbus_comms.h" 20 21 MODULE_LICENSE("GPL"); 22 23 static int xenbus_backend_open(struct inode *inode, struct file *filp) 24 { 25 if (!capable(CAP_SYS_ADMIN)) 26 return -EPERM; 27 28 return nonseekable_open(inode, filp); 29 } 30 31 static long xenbus_alloc(domid_t domid) 32 { 33 struct evtchn_alloc_unbound arg; 34 int err = -EEXIST; 35 36 xs_suspend(); 37 38 /* If xenstored_ready is nonzero, that means we have already talked to 39 * xenstore and set up watches. These watches will be restored by 40 * xs_resume, but that requires communication over the port established 41 * below that is not visible to anyone until the ioctl returns. 42 * 43 * This can be resolved by splitting the ioctl into two parts 44 * (postponing the resume until xenstored is active) but this is 45 * unnecessarily complex for the intended use where xenstored is only 46 * started once - so return -EEXIST if it's already running. 47 */ 48 if (xenstored_ready) 49 goto out_err; 50 51 gnttab_grant_foreign_access_ref(GNTTAB_RESERVED_XENSTORE, domid, 52 virt_to_gfn(xen_store_interface), 0 /* writable */); 53 54 arg.dom = DOMID_SELF; 55 arg.remote_dom = domid; 56 57 err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &arg); 58 if (err) 59 goto out_err; 60 61 if (xen_store_evtchn > 0) 62 xb_deinit_comms(); 63 64 xen_store_evtchn = arg.port; 65 66 xs_resume(); 67 68 return arg.port; 69 70 out_err: 71 xs_suspend_cancel(); 72 return err; 73 } 74 75 static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, 76 unsigned long data) 77 { 78 if (!capable(CAP_SYS_ADMIN)) 79 return -EPERM; 80 81 switch (cmd) { 82 case IOCTL_XENBUS_BACKEND_EVTCHN: 83 if (xen_store_evtchn > 0) 84 return xen_store_evtchn; 85 return -ENODEV; 86 case IOCTL_XENBUS_BACKEND_SETUP: 87 return xenbus_alloc(data); 88 default: 89 return -ENOTTY; 90 } 91 } 92 93 static int xenbus_backend_mmap(struct file *file, struct vm_area_struct *vma) 94 { 95 size_t size = vma->vm_end - vma->vm_start; 96 97 if (!capable(CAP_SYS_ADMIN)) 98 return -EPERM; 99 100 if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0)) 101 return -EINVAL; 102 103 if (remap_pfn_range(vma, vma->vm_start, 104 virt_to_pfn(xen_store_interface), 105 size, vma->vm_page_prot)) 106 return -EAGAIN; 107 108 return 0; 109 } 110 111 static const struct file_operations xenbus_backend_fops = { 112 .open = xenbus_backend_open, 113 .mmap = xenbus_backend_mmap, 114 .unlocked_ioctl = xenbus_backend_ioctl, 115 }; 116 117 static struct miscdevice xenbus_backend_dev = { 118 .minor = MISC_DYNAMIC_MINOR, 119 .name = "xen/xenbus_backend", 120 .fops = &xenbus_backend_fops, 121 }; 122 123 static int __init xenbus_backend_init(void) 124 { 125 int err; 126 127 if (!xen_initial_domain()) 128 return -ENODEV; 129 130 err = misc_register(&xenbus_backend_dev); 131 if (err) 132 pr_err("Could not register xenbus backend device\n"); 133 return err; 134 } 135 136 static void __exit xenbus_backend_exit(void) 137 { 138 misc_deregister(&xenbus_backend_dev); 139 } 140 141 module_init(xenbus_backend_init); 142 module_exit(xenbus_backend_exit); 143