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