1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 3 #pragma once 4 5 /* 6 * Contains declarations that exist in the kernel which have been CUSTOMISED for 7 * testing purposes to faciliate userland VMA testing. 8 */ 9 10 #ifdef CONFIG_MMU 11 extern unsigned long mmap_min_addr; 12 extern unsigned long dac_mmap_min_addr; 13 #else 14 #define mmap_min_addr 0UL 15 #define dac_mmap_min_addr 0UL 16 #endif 17 18 #define VM_WARN_ON(_expr) (WARN_ON(_expr)) 19 #define VM_WARN_ON_ONCE(_expr) (WARN_ON_ONCE(_expr)) 20 #define VM_WARN_ON_VMG(_expr, _vmg) (WARN_ON(_expr)) 21 #define VM_BUG_ON(_expr) (BUG_ON(_expr)) 22 #define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr)) 23 24 #define TASK_SIZE ((1ul << 47)-PAGE_SIZE) 25 26 /* 27 * The shared stubs do not implement this, it amounts to an fprintf(STDERR,...) 28 * either way :) 29 */ 30 #define pr_warn_once pr_err 31 32 #define pgtable_supports_soft_dirty() 1 33 34 struct anon_vma { 35 struct anon_vma *root; 36 struct rb_root_cached rb_root; 37 38 /* Test fields. */ 39 bool was_cloned; 40 bool was_unlinked; 41 }; 42 43 static inline void unlink_anon_vmas(struct vm_area_struct *vma) 44 { 45 /* For testing purposes, indicate that the anon_vma was unlinked. */ 46 vma->anon_vma->was_unlinked = true; 47 } 48 49 static inline void vma_start_write(struct vm_area_struct *vma) 50 { 51 /* Used to indicate to tests that a write operation has begun. */ 52 vma->vm_lock_seq++; 53 } 54 55 static inline __must_check 56 int vma_start_write_killable(struct vm_area_struct *vma) 57 { 58 /* Used to indicate to tests that a write operation has begun. */ 59 vma->vm_lock_seq++; 60 return 0; 61 } 62 63 static inline int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src, 64 enum vma_operation operation) 65 { 66 /* For testing purposes. We indicate that an anon_vma has been cloned. */ 67 if (src->anon_vma != NULL) { 68 dst->anon_vma = src->anon_vma; 69 dst->anon_vma->was_cloned = true; 70 } 71 72 return 0; 73 } 74 75 static inline int __anon_vma_prepare(struct vm_area_struct *vma) 76 { 77 struct anon_vma *anon_vma = calloc(1, sizeof(struct anon_vma)); 78 79 if (!anon_vma) 80 return -ENOMEM; 81 82 anon_vma->root = anon_vma; 83 vma->anon_vma = anon_vma; 84 85 return 0; 86 } 87 88 static inline int anon_vma_prepare(struct vm_area_struct *vma) 89 { 90 if (likely(vma->anon_vma)) 91 return 0; 92 93 return __anon_vma_prepare(vma); 94 } 95 96 static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt) 97 { 98 if (reset_refcnt) 99 refcount_set(&vma->vm_refcnt, 0); 100 } 101 102 static __always_inline vma_flags_t __mk_vma_flags(size_t count, 103 const vma_flag_t *bits) 104 { 105 vma_flags_t flags; 106 int i; 107 108 /* 109 * For testing purposes: allow invalid bit specification so we can 110 * easily test. 111 */ 112 vma_flags_clear_all(&flags); 113 for (i = 0; i < count; i++) 114 if (bits[i] < NUM_VMA_FLAG_BITS) 115 vma_flags_set_flag(&flags, bits[i]); 116 return flags; 117 } 118 119 static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma) 120 { 121 return PAGE_SIZE; 122 } 123 124 /* Place here until needed in the kernel code. */ 125 static __always_inline bool vma_flags_same_mask(vma_flags_t *flags, 126 vma_flags_t flags_other) 127 { 128 const unsigned long *bitmap = flags->__vma_flags; 129 const unsigned long *bitmap_other = flags_other.__vma_flags; 130 131 return bitmap_equal(bitmap, bitmap_other, NUM_VMA_FLAG_BITS); 132 } 133 #define vma_flags_same(flags, ...) \ 134 vma_flags_same_mask(flags, mk_vma_flags(__VA_ARGS__)) 135 #define VMA_SPECIAL_FLAGS mk_vma_flags(VMA_IO_BIT, VMA_DONTEXPAND_BIT, \ 136 VMA_PFNMAP_BIT, VMA_MIXEDMAP_BIT) 137 #ifdef CONFIG_MEM_SOFT_DIRTY 138 #define VMA_STICKY_FLAGS mk_vma_flags(VMA_SOFTDIRTY_BIT, VMA_MAYBE_GUARD_BIT) 139 #else 140 #define VMA_STICKY_FLAGS mk_vma_flags(VMA_MAYBE_GUARD_BIT) 141 #endif 142