xref: /xnu-12377.41.6/bsd/tests/pmap_test_sysctl.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 /*
2  * Copyright (c) 2016 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #include <sys/sysctl.h>
30 
31 extern kern_return_t test_pmap_enter_disconnect(unsigned int);
32 extern kern_return_t test_pmap_compress_remove(unsigned int);
33 extern kern_return_t test_pmap_exec_remove(unsigned int);
34 extern kern_return_t test_pmap_nesting(unsigned int);
35 extern kern_return_t test_pmap_iommu_disconnect(void);
36 extern kern_return_t test_pmap_extended(void);
37 extern void test_pmap_call_overhead(unsigned int);
38 extern uint64_t test_pmap_page_protect_overhead(unsigned int, unsigned int);
39 #if CONFIG_SPTM
40 extern kern_return_t test_pmap_huge_pv_list(unsigned int, unsigned int);
41 extern kern_return_t test_pmap_reentrance(unsigned int);
42 extern kern_return_t test_surt(unsigned int);
43 #endif
44 
45 static int
sysctl_test_pmap_enter_disconnect(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)46 sysctl_test_pmap_enter_disconnect(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
47 {
48 	unsigned int num_loops;
49 	int error, changed;
50 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
51 	if (error || !changed) {
52 		return error;
53 	}
54 	return test_pmap_enter_disconnect(num_loops);
55 }
56 
57 SYSCTL_PROC(_kern, OID_AUTO, pmap_enter_disconnect_test,
58     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
59     0, 0, sysctl_test_pmap_enter_disconnect, "I", "");
60 
61 static int
sysctl_test_pmap_compress_remove(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)62 sysctl_test_pmap_compress_remove(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
63 {
64 	unsigned int num_loops;
65 	int error, changed;
66 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
67 	if (error || !changed) {
68 		return error;
69 	}
70 	return test_pmap_compress_remove(num_loops);
71 }
72 
73 SYSCTL_PROC(_kern, OID_AUTO, pmap_compress_remove_test,
74     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
75     0, 0, sysctl_test_pmap_compress_remove, "I", "");
76 
77 static int
sysctl_test_pmap_exec_remove(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)78 sysctl_test_pmap_exec_remove(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
79 {
80 	unsigned int num_loops;
81 	int error, changed;
82 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
83 	if (error || !changed) {
84 		return error;
85 	}
86 	return test_pmap_exec_remove(num_loops);
87 }
88 
89 SYSCTL_PROC(_kern, OID_AUTO, pmap_exec_remove_test,
90     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
91     0, 0, sysctl_test_pmap_exec_remove, "I", "");
92 
93 static int
sysctl_test_pmap_nesting(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)94 sysctl_test_pmap_nesting(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
95 {
96 	unsigned int num_loops;
97 	int error, changed;
98 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
99 	if (error || !changed) {
100 		return error;
101 	}
102 	return test_pmap_nesting(num_loops);
103 }
104 SYSCTL_PROC(_kern, OID_AUTO, pmap_nesting_test,
105     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
106     0, 0, sysctl_test_pmap_nesting, "I", "");
107 
108 static int
sysctl_test_pmap_iommu_disconnect(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)109 sysctl_test_pmap_iommu_disconnect(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
110 {
111 	unsigned int run = 0;
112 	int error, changed;
113 	error = sysctl_io_number(req, 0, sizeof(run), &run, &changed);
114 	if (error || !changed) {
115 		return error;
116 	}
117 	return test_pmap_iommu_disconnect();
118 }
119 
120 SYSCTL_PROC(_kern, OID_AUTO, pmap_iommu_disconnect_test,
121     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
122     0, 0, sysctl_test_pmap_iommu_disconnect, "I", "");
123 
124 static int
sysctl_test_pmap_extended(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)125 sysctl_test_pmap_extended(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
126 {
127 	unsigned int run = 0;
128 	int error, changed;
129 	error = sysctl_io_number(req, 0, sizeof(run), &run, &changed);
130 	if (error || !changed) {
131 		return error;
132 	}
133 	return test_pmap_extended();
134 }
135 
136 SYSCTL_PROC(_kern, OID_AUTO, pmap_extended_test,
137     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
138     0, 0, sysctl_test_pmap_extended, "I", "");
139 
140 static int
sysctl_test_pmap_call_overhead(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)141 sysctl_test_pmap_call_overhead(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
142 {
143 	unsigned int num_loops;
144 	int error, changed;
145 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
146 	if (error || !changed) {
147 		return error;
148 	}
149 	test_pmap_call_overhead(num_loops);
150 	return 0;
151 }
152 
153 SYSCTL_PROC(_kern, OID_AUTO, pmap_call_overhead_test,
154     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
155     0, 0, sysctl_test_pmap_call_overhead, "I", "");
156 
157 static int
sysctl_test_pmap_page_protect_overhead(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)158 sysctl_test_pmap_page_protect_overhead(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
159 {
160 	struct {
161 		unsigned int num_loops;
162 		unsigned int num_aliases;
163 	} ppo_in;
164 
165 	int error;
166 	uint64_t duration;
167 
168 	error = SYSCTL_IN(req, &ppo_in, sizeof(ppo_in));
169 	if (error) {
170 		return error;
171 	}
172 
173 	duration = test_pmap_page_protect_overhead(ppo_in.num_loops, ppo_in.num_aliases);
174 	error = SYSCTL_OUT(req, &duration, sizeof(duration));
175 	return error;
176 }
177 
178 SYSCTL_PROC(_kern, OID_AUTO, pmap_page_protect_overhead_test,
179     CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_test_pmap_page_protect_overhead, "-", "");
180 
181 #if CONFIG_SPTM
182 static int
sysctl_test_pmap_huge_pv_list(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)183 sysctl_test_pmap_huge_pv_list(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
184 {
185 	struct {
186 		unsigned int num_loops;
187 		unsigned int num_mappings;
188 	} hugepv_in;
189 
190 	int error = SYSCTL_IN(req, &hugepv_in, sizeof(hugepv_in));
191 	if (error) {
192 		return error;
193 	}
194 	return test_pmap_huge_pv_list(hugepv_in.num_loops, hugepv_in.num_mappings);
195 }
196 
197 SYSCTL_PROC(_kern, OID_AUTO, pmap_huge_pv_list_test,
198     CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_test_pmap_huge_pv_list, "-", "");
199 
200 static int
sysctl_test_pmap_reentrance(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)201 sysctl_test_pmap_reentrance(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
202 {
203 	unsigned int num_loops;
204 	int error, changed;
205 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
206 	if (error || !changed) {
207 		return error;
208 	}
209 	return test_pmap_reentrance(num_loops);
210 }
211 
212 SYSCTL_PROC(_kern, OID_AUTO, pmap_reentrance_test,
213     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
214     0, 0, sysctl_test_pmap_reentrance, "I", "");
215 
216 #if __ARM64_PMAP_SUBPAGE_L1__
217 extern unsigned int surt_list_len(void);
218 static int
sysctl_surt_list_len(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)219 sysctl_surt_list_len(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
220 {
221 	unsigned int len = surt_list_len();
222 	return SYSCTL_OUT(req, &len, sizeof(len));
223 }
224 
225 SYSCTL_PROC(_kern, OID_AUTO, surt_list_len,
226     CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
227     0, 0, sysctl_surt_list_len, "I", "");
228 
229 static int
sysctl_test_surt(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)230 sysctl_test_surt(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
231 {
232 	unsigned int num_surts;
233 	int error, changed;
234 	error = sysctl_io_number(req, 0, sizeof(num_surts), &num_surts, &changed);
235 	if (error || !changed) {
236 		return error;
237 	}
238 	return test_surt(num_surts);
239 }
240 
241 SYSCTL_PROC(_kern, OID_AUTO, surt_test,
242     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
243     0, 0, sysctl_test_surt, "I", "");
244 #endif /* __ARM64_PMAP_SUBPAGE_L1__ */
245 #endif /* CONFIG_SPTM */
246