xref: /xnu-11215/bsd/tests/pmap_test_sysctl.c (revision 8d741a5d)
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 #endif
43 
44 static int
sysctl_test_pmap_enter_disconnect(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)45 sysctl_test_pmap_enter_disconnect(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
46 {
47 	unsigned int num_loops;
48 	int error, changed;
49 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
50 	if (error || !changed) {
51 		return error;
52 	}
53 	return test_pmap_enter_disconnect(num_loops);
54 }
55 
56 SYSCTL_PROC(_kern, OID_AUTO, pmap_enter_disconnect_test,
57     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
58     0, 0, sysctl_test_pmap_enter_disconnect, "I", "");
59 
60 static int
sysctl_test_pmap_compress_remove(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)61 sysctl_test_pmap_compress_remove(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
62 {
63 	unsigned int num_loops;
64 	int error, changed;
65 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
66 	if (error || !changed) {
67 		return error;
68 	}
69 	return test_pmap_compress_remove(num_loops);
70 }
71 
72 SYSCTL_PROC(_kern, OID_AUTO, pmap_compress_remove_test,
73     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
74     0, 0, sysctl_test_pmap_compress_remove, "I", "");
75 
76 static int
sysctl_test_pmap_exec_remove(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)77 sysctl_test_pmap_exec_remove(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
78 {
79 	unsigned int num_loops;
80 	int error, changed;
81 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
82 	if (error || !changed) {
83 		return error;
84 	}
85 	return test_pmap_exec_remove(num_loops);
86 }
87 
88 SYSCTL_PROC(_kern, OID_AUTO, pmap_exec_remove_test,
89     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
90     0, 0, sysctl_test_pmap_exec_remove, "I", "");
91 
92 static int
sysctl_test_pmap_nesting(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)93 sysctl_test_pmap_nesting(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
94 {
95 	unsigned int num_loops;
96 	int error, changed;
97 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
98 	if (error || !changed) {
99 		return error;
100 	}
101 	return test_pmap_nesting(num_loops);
102 }
103 SYSCTL_PROC(_kern, OID_AUTO, pmap_nesting_test,
104     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
105     0, 0, sysctl_test_pmap_nesting, "I", "");
106 
107 static int
sysctl_test_pmap_iommu_disconnect(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)108 sysctl_test_pmap_iommu_disconnect(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
109 {
110 	unsigned int run = 0;
111 	int error, changed;
112 	error = sysctl_io_number(req, 0, sizeof(run), &run, &changed);
113 	if (error || !changed) {
114 		return error;
115 	}
116 	return test_pmap_iommu_disconnect();
117 }
118 
119 SYSCTL_PROC(_kern, OID_AUTO, pmap_iommu_disconnect_test,
120     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
121     0, 0, sysctl_test_pmap_iommu_disconnect, "I", "");
122 
123 static int
sysctl_test_pmap_extended(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)124 sysctl_test_pmap_extended(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
125 {
126 	unsigned int run = 0;
127 	int error, changed;
128 	error = sysctl_io_number(req, 0, sizeof(run), &run, &changed);
129 	if (error || !changed) {
130 		return error;
131 	}
132 	return test_pmap_extended();
133 }
134 
135 SYSCTL_PROC(_kern, OID_AUTO, pmap_extended_test,
136     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
137     0, 0, sysctl_test_pmap_extended, "I", "");
138 
139 static int
sysctl_test_pmap_call_overhead(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)140 sysctl_test_pmap_call_overhead(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
141 {
142 	unsigned int num_loops;
143 	int error, changed;
144 	error = sysctl_io_number(req, 0, sizeof(num_loops), &num_loops, &changed);
145 	if (error || !changed) {
146 		return error;
147 	}
148 	test_pmap_call_overhead(num_loops);
149 	return 0;
150 }
151 
152 SYSCTL_PROC(_kern, OID_AUTO, pmap_call_overhead_test,
153     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
154     0, 0, sysctl_test_pmap_call_overhead, "I", "");
155 
156 static int
sysctl_test_pmap_page_protect_overhead(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)157 sysctl_test_pmap_page_protect_overhead(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
158 {
159 	struct {
160 		unsigned int num_loops;
161 		unsigned int num_aliases;
162 	} ppo_in;
163 
164 	int error;
165 	uint64_t duration;
166 
167 	error = SYSCTL_IN(req, &ppo_in, sizeof(ppo_in));
168 	if (error) {
169 		return error;
170 	}
171 
172 	duration = test_pmap_page_protect_overhead(ppo_in.num_loops, ppo_in.num_aliases);
173 	error = SYSCTL_OUT(req, &duration, sizeof(duration));
174 	return error;
175 }
176 
177 SYSCTL_PROC(_kern, OID_AUTO, pmap_page_protect_overhead_test,
178     CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_test_pmap_page_protect_overhead, "-", "");
179 
180 #if CONFIG_SPTM
181 
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 #endif
217