#include <linux/list.h>
#include <linux/hashtable.h>
#include <linux/sched/signal.h>
#include <linux/sched/mm.h>
#include <linux/mm.h>
#include <linux/mm_inline.h>
#include <linux/mmu_notifier.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/file.h>
#include <linux/bug.h>
#include <linux/anon_inodes.h>
#include <linux/syscalls.h>
#include <linux/userfaultfd_k.h>
#include <linux/mempolicy.h>
#include <linux/ioctl.h>
#include <linux/security.h>
#include <linux/hugetlb.h>
#include <linux/swapops.h>
#include <linux/miscdevice.h>
#include <linux/uio.h>
static int sysctl_unprivileged_userfaultfd __read_mostly;
#ifdef CONFIG_SYSCTL
static struct ctl_table vm_userfaultfd_table[] = …;
#endif
static struct kmem_cache *userfaultfd_ctx_cachep __ro_after_init;
struct userfaultfd_fork_ctx { … };
struct userfaultfd_unmap_ctx { … };
struct userfaultfd_wait_queue { … };
struct userfaultfd_wake_range { … };
#define UFFD_FEATURE_INITIALIZED …
static bool userfaultfd_is_initialized(struct userfaultfd_ctx *ctx)
{ … }
static bool userfaultfd_wp_async_ctx(struct userfaultfd_ctx *ctx)
{ … }
bool userfaultfd_wp_unpopulated(struct vm_area_struct *vma)
{ … }
static void userfaultfd_set_vm_flags(struct vm_area_struct *vma,
vm_flags_t flags)
{ … }
static int userfaultfd_wake_function(wait_queue_entry_t *wq, unsigned mode,
int wake_flags, void *key)
{ … }
static void userfaultfd_ctx_get(struct userfaultfd_ctx *ctx)
{ … }
static void userfaultfd_ctx_put(struct userfaultfd_ctx *ctx)
{ … }
static inline void msg_init(struct uffd_msg *msg)
{ … }
static inline struct uffd_msg userfault_msg(unsigned long address,
unsigned long real_address,
unsigned int flags,
unsigned long reason,
unsigned int features)
{ … }
#ifdef CONFIG_HUGETLB_PAGE
static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
struct vm_fault *vmf,
unsigned long reason)
{ … }
#else
static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
struct vm_fault *vmf,
unsigned long reason)
{
return false;
}
#endif
static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
struct vm_fault *vmf,
unsigned long reason)
{ … }
static inline unsigned int userfaultfd_get_blocking_state(unsigned int flags)
{ … }
vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
{ … }
static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx,
struct userfaultfd_wait_queue *ewq)
{ … }
static void userfaultfd_event_complete(struct userfaultfd_ctx *ctx,
struct userfaultfd_wait_queue *ewq)
{ … }
int dup_userfaultfd(struct vm_area_struct *vma, struct list_head *fcs)
{ … }
static void dup_fctx(struct userfaultfd_fork_ctx *fctx)
{ … }
void dup_userfaultfd_complete(struct list_head *fcs)
{ … }
void mremap_userfaultfd_prep(struct vm_area_struct *vma,
struct vm_userfaultfd_ctx *vm_ctx)
{ … }
void mremap_userfaultfd_complete(struct vm_userfaultfd_ctx *vm_ctx,
unsigned long from, unsigned long to,
unsigned long len)
{ … }
bool userfaultfd_remove(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ … }
static bool has_unmap_ctx(struct userfaultfd_ctx *ctx, struct list_head *unmaps,
unsigned long start, unsigned long end)
{ … }
int userfaultfd_unmap_prep(struct vm_area_struct *vma, unsigned long start,
unsigned long end, struct list_head *unmaps)
{ … }
void userfaultfd_unmap_complete(struct mm_struct *mm, struct list_head *uf)
{ … }
static int userfaultfd_release(struct inode *inode, struct file *file)
{ … }
static inline struct userfaultfd_wait_queue *find_userfault_in(
wait_queue_head_t *wqh)
{ … }
static inline struct userfaultfd_wait_queue *find_userfault(
struct userfaultfd_ctx *ctx)
{ … }
static inline struct userfaultfd_wait_queue *find_userfault_evt(
struct userfaultfd_ctx *ctx)
{ … }
static __poll_t userfaultfd_poll(struct file *file, poll_table *wait)
{ … }
static const struct file_operations userfaultfd_fops;
static int resolve_userfault_fork(struct userfaultfd_ctx *new,
struct inode *inode,
struct uffd_msg *msg)
{ … }
static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
struct uffd_msg *msg, struct inode *inode)
{ … }
static ssize_t userfaultfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
{ … }
static void __wake_userfault(struct userfaultfd_ctx *ctx,
struct userfaultfd_wake_range *range)
{ … }
static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
struct userfaultfd_wake_range *range)
{ … }
static __always_inline int validate_unaligned_range(
struct mm_struct *mm, __u64 start, __u64 len)
{ … }
static __always_inline int validate_range(struct mm_struct *mm,
__u64 start, __u64 len)
{ … }
static int userfaultfd_register(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_wake(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_writeprotect(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg)
{ … }
static inline int userfaultfd_poison(struct userfaultfd_ctx *ctx, unsigned long arg)
{ … }
bool userfaultfd_wp_async(struct vm_area_struct *vma)
{ … }
static inline unsigned int uffd_ctx_features(__u64 user_features)
{ … }
static int userfaultfd_move(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static int userfaultfd_api(struct userfaultfd_ctx *ctx,
unsigned long arg)
{ … }
static long userfaultfd_ioctl(struct file *file, unsigned cmd,
unsigned long arg)
{ … }
#ifdef CONFIG_PROC_FS
static void userfaultfd_show_fdinfo(struct seq_file *m, struct file *f)
{ … }
#endif
static const struct file_operations userfaultfd_fops = …;
static void init_once_userfaultfd_ctx(void *mem)
{ … }
static int new_userfaultfd(int flags)
{ … }
static inline bool userfaultfd_syscall_allowed(int flags)
{ … }
SYSCALL_DEFINE1(userfaultfd, int, flags)
{ … }
static long userfaultfd_dev_ioctl(struct file *file, unsigned int cmd, unsigned long flags)
{ … }
static const struct file_operations userfaultfd_dev_fops = …;
static struct miscdevice userfaultfd_misc = …;
static int __init userfaultfd_init(void)
{ … }
__initcall(userfaultfd_init);