18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/slab.h> 38c2ecf20Sopenharmony_ci#include <linux/types.h> 48c2ecf20Sopenharmony_ci#include <linux/mm.h> 58c2ecf20Sopenharmony_ci#include <linux/fs.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <xen/page.h> 88c2ecf20Sopenharmony_ci#include <xen/xenbus.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "xenfs.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic ssize_t xsd_read(struct file *file, char __user *buf, 138c2ecf20Sopenharmony_ci size_t size, loff_t *off) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci const char *str = (const char *)file->private_data; 168c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, size, off, str, strlen(str)); 178c2ecf20Sopenharmony_ci} 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic int xsd_release(struct inode *inode, struct file *file) 208c2ecf20Sopenharmony_ci{ 218c2ecf20Sopenharmony_ci kfree(file->private_data); 228c2ecf20Sopenharmony_ci return 0; 238c2ecf20Sopenharmony_ci} 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic int xsd_kva_open(struct inode *inode, struct file *file) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci file->private_data = (void *)kasprintf(GFP_KERNEL, "0x%p", 288c2ecf20Sopenharmony_ci xen_store_interface); 298c2ecf20Sopenharmony_ci if (!file->private_data) 308c2ecf20Sopenharmony_ci return -ENOMEM; 318c2ecf20Sopenharmony_ci return 0; 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci size_t size = vma->vm_end - vma->vm_start; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0)) 398c2ecf20Sopenharmony_ci return -EINVAL; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci if (remap_pfn_range(vma, vma->vm_start, 428c2ecf20Sopenharmony_ci virt_to_pfn(xen_store_interface), 438c2ecf20Sopenharmony_ci size, vma->vm_page_prot)) 448c2ecf20Sopenharmony_ci return -EAGAIN; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci return 0; 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciconst struct file_operations xsd_kva_file_ops = { 508c2ecf20Sopenharmony_ci .open = xsd_kva_open, 518c2ecf20Sopenharmony_ci .mmap = xsd_kva_mmap, 528c2ecf20Sopenharmony_ci .read = xsd_read, 538c2ecf20Sopenharmony_ci .release = xsd_release, 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic int xsd_port_open(struct inode *inode, struct file *file) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci file->private_data = (void *)kasprintf(GFP_KERNEL, "%d", 598c2ecf20Sopenharmony_ci xen_store_evtchn); 608c2ecf20Sopenharmony_ci if (!file->private_data) 618c2ecf20Sopenharmony_ci return -ENOMEM; 628c2ecf20Sopenharmony_ci return 0; 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciconst struct file_operations xsd_port_file_ops = { 668c2ecf20Sopenharmony_ci .open = xsd_port_open, 678c2ecf20Sopenharmony_ci .read = xsd_read, 688c2ecf20Sopenharmony_ci .release = xsd_release, 698c2ecf20Sopenharmony_ci}; 70