#undef DEBUG
#define pr_fmt(fmt) …
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/sched/mm.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/refcount.h>
#include <linux/workqueue.h>
#include <xen/xen.h>
#include <xen/grant_table.h>
#include <xen/balloon.h>
#include <xen/gntdev.h>
#include <xen/events.h>
#include <xen/page.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include "gntdev-common.h"
#ifdef CONFIG_XEN_GNTDEV_DMABUF
#include "gntdev-dmabuf.h"
#endif
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
static unsigned int limit = …;
module_param(limit, uint, 0644);
MODULE_PARM_DESC(…) …;
static int use_ptemod;
static void unmap_grant_pages(struct gntdev_grant_map *map,
int offset, int pages);
static struct miscdevice gntdev_miscdev;
bool gntdev_test_page_count(unsigned int count)
{ … }
static void gntdev_print_maps(struct gntdev_priv *priv,
char *text, int text_index)
{ … }
static void gntdev_free_map(struct gntdev_grant_map *map)
{ … }
struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count,
int dma_flags)
{ … }
void gntdev_add_map(struct gntdev_priv *priv, struct gntdev_grant_map *add)
{ … }
static struct gntdev_grant_map *gntdev_find_map_index(struct gntdev_priv *priv,
int index, int count)
{ … }
void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
{ … }
static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data)
{ … }
int gntdev_map_grant_pages(struct gntdev_grant_map *map)
{ … }
static void __unmap_grant_pages_done(int result,
struct gntab_unmap_queue_data *data)
{ … }
static void __unmap_grant_pages(struct gntdev_grant_map *map, int offset,
int pages)
{ … }
static void unmap_grant_pages(struct gntdev_grant_map *map, int offset,
int pages)
{ … }
static void gntdev_vma_open(struct vm_area_struct *vma)
{ … }
static void gntdev_vma_close(struct vm_area_struct *vma)
{ … }
static struct page *gntdev_vma_find_special_page(struct vm_area_struct *vma,
unsigned long addr)
{ … }
static const struct vm_operations_struct gntdev_vmops = …;
static bool gntdev_invalidate(struct mmu_interval_notifier *mn,
const struct mmu_notifier_range *range,
unsigned long cur_seq)
{ … }
static const struct mmu_interval_notifier_ops gntdev_mmu_ops = …;
static int gntdev_open(struct inode *inode, struct file *flip)
{ … }
static int gntdev_release(struct inode *inode, struct file *flip)
{ … }
static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv,
struct ioctl_gntdev_map_grant_ref __user *u)
{ … }
static long gntdev_ioctl_unmap_grant_ref(struct gntdev_priv *priv,
struct ioctl_gntdev_unmap_grant_ref __user *u)
{ … }
static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv,
struct ioctl_gntdev_get_offset_for_vaddr __user *u)
{ … }
static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
{ … }
#define GNTDEV_COPY_BATCH …
struct gntdev_copy_batch { … };
static int gntdev_get_page(struct gntdev_copy_batch *batch, void __user *virt,
unsigned long *gfn)
{ … }
static void gntdev_put_pages(struct gntdev_copy_batch *batch)
{ … }
static int gntdev_copy(struct gntdev_copy_batch *batch)
{ … }
static int gntdev_grant_copy_seg(struct gntdev_copy_batch *batch,
struct gntdev_grant_copy_segment *seg,
s16 __user *status)
{ … }
static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u)
{ … }
static long gntdev_ioctl(struct file *flip,
unsigned int cmd, unsigned long arg)
{ … }
static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
{ … }
static const struct file_operations gntdev_fops = …;
static struct miscdevice gntdev_miscdev = …;
static int __init gntdev_init(void)
{ … }
static void __exit gntdev_exit(void)
{ … }
module_init(…) …;
module_exit(gntdev_exit);