xref: /linux/tools/testing/vma/include/custom.h (revision 40286d6379aacfcc053253ef78dc78b09addffda)
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 TASK_SIZE ((1ul << 47)-PAGE_SIZE)
19 
20 /*
21  * The shared stubs do not implement this, it amounts to an fprintf(STDERR,...)
22  * either way :)
23  */
24 #define pr_warn_once pr_err
25 
26 struct anon_vma {
27 	struct anon_vma *root;
28 	struct rb_root_cached rb_root;
29 
30 	/* Test fields. */
31 	bool was_cloned;
32 	bool was_unlinked;
33 };
34 
35 static inline void unlink_anon_vmas(struct vm_area_struct *vma)
36 {
37 	/* For testing purposes, indicate that the anon_vma was unlinked. */
38 	vma->anon_vma->was_unlinked = true;
39 }
40 
41 static inline void vma_start_write(struct vm_area_struct *vma)
42 {
43 	/* Used to indicate to tests that a write operation has begun. */
44 	vma->vm_lock_seq++;
45 }
46 
47 static inline __must_check
48 int vma_start_write_killable(struct vm_area_struct *vma)
49 {
50 	/* Used to indicate to tests that a write operation has begun. */
51 	vma->vm_lock_seq++;
52 	return 0;
53 }
54 
55 static inline int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src,
56 				 enum vma_operation operation)
57 {
58 	/* For testing purposes. We indicate that an anon_vma has been cloned. */
59 	if (src->anon_vma != NULL) {
60 		dst->anon_vma = src->anon_vma;
61 		dst->anon_vma->was_cloned = true;
62 	}
63 
64 	return 0;
65 }
66 
67 static inline int __anon_vma_prepare(struct vm_area_struct *vma)
68 {
69 	struct anon_vma *anon_vma = calloc(1, sizeof(struct anon_vma));
70 
71 	if (!anon_vma)
72 		return -ENOMEM;
73 
74 	anon_vma->root = anon_vma;
75 	vma->anon_vma = anon_vma;
76 
77 	return 0;
78 }
79 
80 static inline int anon_vma_prepare(struct vm_area_struct *vma)
81 {
82 	if (likely(vma->anon_vma))
83 		return 0;
84 
85 	return __anon_vma_prepare(vma);
86 }
87 
88 static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt)
89 {
90 	if (reset_refcnt)
91 		refcount_set(&vma->vm_refcnt, 0);
92 }
93 
94 static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
95 {
96 	return PAGE_SIZE;
97 }
98