linux/include/linux/userfaultfd_k.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 *  include/linux/userfaultfd_k.h
   4 *
   5 *  Copyright (C) 2015  Red Hat, Inc.
   6 *
   7 */
   8
   9#ifndef _LINUX_USERFAULTFD_K_H
  10#define _LINUX_USERFAULTFD_K_H
  11
  12#ifdef CONFIG_USERFAULTFD
  13
  14#include <linux/userfaultfd.h> /* linux/include/uapi/linux/userfaultfd.h */
  15
  16#include <linux/fcntl.h>
  17#include <linux/mm.h>
  18#include <asm-generic/pgtable_uffd.h>
  19
  20/*
  21 * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining
  22 * new flags, since they might collide with O_* ones. We want
  23 * to re-use O_* flags that couldn't possibly have a meaning
  24 * from userfaultfd, in order to leave a free define-space for
  25 * shared O_* flags.
  26 */
  27#define UFFD_CLOEXEC O_CLOEXEC
  28#define UFFD_NONBLOCK O_NONBLOCK
  29
  30#define UFFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK)
  31#define UFFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS)
  32
  33extern int sysctl_unprivileged_userfaultfd;
  34
  35extern vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason);
  36
  37extern ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start,
  38                            unsigned long src_start, unsigned long len,
  39                            bool *mmap_changing, __u64 mode);
  40extern ssize_t mfill_zeropage(struct mm_struct *dst_mm,
  41                              unsigned long dst_start,
  42                              unsigned long len,
  43                              bool *mmap_changing);
  44extern int mwriteprotect_range(struct mm_struct *dst_mm,
  45                               unsigned long start, unsigned long len,
  46                               bool enable_wp, bool *mmap_changing);
  47
  48/* mm helpers */
  49static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma,
  50                                        struct vm_userfaultfd_ctx vm_ctx)
  51{
  52        return vma->vm_userfaultfd_ctx.ctx == vm_ctx.ctx;
  53}
  54
  55static inline bool userfaultfd_missing(struct vm_area_struct *vma)
  56{
  57        return vma->vm_flags & VM_UFFD_MISSING;
  58}
  59
  60static inline bool userfaultfd_wp(struct vm_area_struct *vma)
  61{
  62        return vma->vm_flags & VM_UFFD_WP;
  63}
  64
  65static inline bool userfaultfd_pte_wp(struct vm_area_struct *vma,
  66                                      pte_t pte)
  67{
  68        return userfaultfd_wp(vma) && pte_uffd_wp(pte);
  69}
  70
  71static inline bool userfaultfd_huge_pmd_wp(struct vm_area_struct *vma,
  72                                           pmd_t pmd)
  73{
  74        return userfaultfd_wp(vma) && pmd_uffd_wp(pmd);
  75}
  76
  77static inline bool userfaultfd_armed(struct vm_area_struct *vma)
  78{
  79        return vma->vm_flags & (VM_UFFD_MISSING | VM_UFFD_WP);
  80}
  81
  82extern int dup_userfaultfd(struct vm_area_struct *, struct list_head *);
  83extern void dup_userfaultfd_complete(struct list_head *);
  84
  85extern void mremap_userfaultfd_prep(struct vm_area_struct *,
  86                                    struct vm_userfaultfd_ctx *);
  87extern void mremap_userfaultfd_complete(struct vm_userfaultfd_ctx *,
  88                                        unsigned long from, unsigned long to,
  89                                        unsigned long len);
  90
  91extern bool userfaultfd_remove(struct vm_area_struct *vma,
  92                               unsigned long start,
  93                               unsigned long end);
  94
  95extern int userfaultfd_unmap_prep(struct vm_area_struct *vma,
  96                                  unsigned long start, unsigned long end,
  97                                  struct list_head *uf);
  98extern void userfaultfd_unmap_complete(struct mm_struct *mm,
  99                                       struct list_head *uf);
 100
 101#else /* CONFIG_USERFAULTFD */
 102
 103/* mm helpers */
 104static inline vm_fault_t handle_userfault(struct vm_fault *vmf,
 105                                unsigned long reason)
 106{
 107        return VM_FAULT_SIGBUS;
 108}
 109
 110static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma,
 111                                        struct vm_userfaultfd_ctx vm_ctx)
 112{
 113        return true;
 114}
 115
 116static inline bool userfaultfd_missing(struct vm_area_struct *vma)
 117{
 118        return false;
 119}
 120
 121static inline bool userfaultfd_wp(struct vm_area_struct *vma)
 122{
 123        return false;
 124}
 125
 126static inline bool userfaultfd_pte_wp(struct vm_area_struct *vma,
 127                                      pte_t pte)
 128{
 129        return false;
 130}
 131
 132static inline bool userfaultfd_huge_pmd_wp(struct vm_area_struct *vma,
 133                                           pmd_t pmd)
 134{
 135        return false;
 136}
 137
 138
 139static inline bool userfaultfd_armed(struct vm_area_struct *vma)
 140{
 141        return false;
 142}
 143
 144static inline int dup_userfaultfd(struct vm_area_struct *vma,
 145                                  struct list_head *l)
 146{
 147        return 0;
 148}
 149
 150static inline void dup_userfaultfd_complete(struct list_head *l)
 151{
 152}
 153
 154static inline void mremap_userfaultfd_prep(struct vm_area_struct *vma,
 155                                           struct vm_userfaultfd_ctx *ctx)
 156{
 157}
 158
 159static inline void mremap_userfaultfd_complete(struct vm_userfaultfd_ctx *ctx,
 160                                               unsigned long from,
 161                                               unsigned long to,
 162                                               unsigned long len)
 163{
 164}
 165
 166static inline bool userfaultfd_remove(struct vm_area_struct *vma,
 167                                      unsigned long start,
 168                                      unsigned long end)
 169{
 170        return true;
 171}
 172
 173static inline int userfaultfd_unmap_prep(struct vm_area_struct *vma,
 174                                         unsigned long start, unsigned long end,
 175                                         struct list_head *uf)
 176{
 177        return 0;
 178}
 179
 180static inline void userfaultfd_unmap_complete(struct mm_struct *mm,
 181                                              struct list_head *uf)
 182{
 183}
 184
 185#endif /* CONFIG_USERFAULTFD */
 186
 187#endif /* _LINUX_USERFAULTFD_K_H */
 188