xref: /linux/tools/testing/vma/include/custom.h (revision 3ee584538259c356c66146ac46f2e4fd2ba28bee)
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 struct anon_vma {
33 	struct anon_vma *root;
34 	struct rb_root_cached rb_root;
35 
36 	/* Test fields. */
37 	bool was_cloned;
38 	bool was_unlinked;
39 };
40 
41 static inline void unlink_anon_vmas(struct vm_area_struct *vma)
42 {
43 	/* For testing purposes, indicate that the anon_vma was unlinked. */
44 	vma->anon_vma->was_unlinked = true;
45 }
46 
47 static inline void vma_start_write(struct vm_area_struct *vma)
48 {
49 	/* Used to indicate to tests that a write operation has begun. */
50 	vma->vm_lock_seq++;
51 }
52 
53 static inline __must_check
54 int vma_start_write_killable(struct vm_area_struct *vma)
55 {
56 	/* Used to indicate to tests that a write operation has begun. */
57 	vma->vm_lock_seq++;
58 	return 0;
59 }
60 
61 static inline int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src,
62 				 enum vma_operation operation)
63 {
64 	/* For testing purposes. We indicate that an anon_vma has been cloned. */
65 	if (src->anon_vma != NULL) {
66 		dst->anon_vma = src->anon_vma;
67 		dst->anon_vma->was_cloned = true;
68 	}
69 
70 	return 0;
71 }
72 
73 static inline int __anon_vma_prepare(struct vm_area_struct *vma)
74 {
75 	struct anon_vma *anon_vma = calloc(1, sizeof(struct anon_vma));
76 
77 	if (!anon_vma)
78 		return -ENOMEM;
79 
80 	anon_vma->root = anon_vma;
81 	vma->anon_vma = anon_vma;
82 
83 	return 0;
84 }
85 
86 static inline int anon_vma_prepare(struct vm_area_struct *vma)
87 {
88 	if (likely(vma->anon_vma))
89 		return 0;
90 
91 	return __anon_vma_prepare(vma);
92 }
93 
94 static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt)
95 {
96 	if (reset_refcnt)
97 		refcount_set(&vma->vm_refcnt, 0);
98 }
99 
100 static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
101 {
102 	return PAGE_SIZE;
103 }
104 
105 #define VMA_SPECIAL_FLAGS mk_vma_flags(VMA_IO_BIT, VMA_DONTEXPAND_BIT, \
106 				       VMA_PFNMAP_BIT, VMA_MIXEDMAP_BIT)
107