1 /*
2 * Copyright (c) 1980, 1986, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)param.c 8.3 (Berkeley) 8/20/94
35 * $FreeBSD: src/sys/kern/subr_param.c,v 1.42.2.10 2002/03/09 21:05:47 silby Exp $
36 */
37
38 #include "opt_param.h"
39 #include "opt_maxusers.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/sysctl.h>
46 #include <vm/pmap.h>
47 #include <machine/vmparam.h>
48
49 /*
50 * System parameter formulae.
51 */
52
53 #ifndef HZ_DEFAULT
54 #define HZ_DEFAULT 100
55 #endif
56 #define NPROC (20 + 16 * maxusers)
57 #ifndef NBUF
58 #define NBUF 0
59 #endif
60 #ifndef MAXFILES
61 #define MAXFILES (maxproc * 16)
62 #endif
63 #ifndef MAXPOSIXLOCKSPERUID
64 #define MAXPOSIXLOCKSPERUID (maxproc * 4)
65 #endif
66
67 static int sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS);
68
69 int hz;
70 int stathz;
71 int profhz;
72 int ustick; /* tick interval in microseconds */
73 int nstick; /* tick interval in nanoseconds */
74 int maxusers; /* base tunable */
75 int maxproc; /* maximum # of processes */
76 int maxprocperuid; /* max # of procs per user */
77 int maxfiles; /* system wide open files limit */
78 int maxfilesrootres; /* descriptors reserved for root use */
79 int minfilesperproc; /* per-proc min open files (safety) */
80 int maxfilesperproc; /* per-proc open files limit */
81 int maxfilesperuser; /* per-user open files limit */
82 int maxposixlocksperuid; /* max # POSIX locks per uid */
83 int ncallout; /* maximum # of timer events */
84 long nbuf;
85 long nswbuf_mem;
86 long nswbuf_kva;
87 long nswbuf_raw;
88 long maxswzone; /* max swmeta KVA storage */
89 long maxbcache; /* max buffer cache KVA storage */
90 enum vmm_guest_type vmm_guest = VMM_GUEST_NONE; /* Running as VM guest? */
91 u_quad_t maxtsiz; /* max text size */
92 u_quad_t dfldsiz; /* initial data size limit */
93 u_quad_t maxdsiz; /* max data size */
94 u_quad_t dflssiz; /* initial stack size limit */
95 u_quad_t maxssiz; /* max stack size */
96 u_quad_t sgrowsiz; /* amount to grow stack */
97 u_quad_t maxthrssiz; /* thread stack area */
98
99 SYSCTL_PROC(_kern, OID_AUTO, vmm_guest, CTLFLAG_RD | CTLTYPE_STRING,
100 NULL, 0, sysctl_kern_vmm_guest, "A",
101 "Virtual machine guest type");
102 SYSCTL_QUAD(_kern, OID_AUTO, maxssiz, CTLFLAG_RD, &maxssiz, 0,
103 "Maximum user stack size");
104 SYSCTL_QUAD(_kern, OID_AUTO, maxthrssiz, CTLFLAG_RD, &maxthrssiz, 0,
105 "Nominal threading stack area");
106
107 /*
108 * These have to be allocated somewhere; allocating
109 * them here forces loader errors if this file is omitted
110 * (if they've been externed everywhere else; hah!).
111 */
112 struct buf *swbuf_mem;
113 struct buf *swbuf_kva;
114 struct buf *swbuf_raw;
115
116 struct vmm_bname {
117 const char *str;
118 enum vmm_guest_type type;
119 };
120
121 static struct vmm_bname vmm_bnames[] = {
122 { "QEMU", VMM_GUEST_QEMU }, /* QEMU */
123 { "Plex86", VMM_GUEST_PLEX86 }, /* Plex86 */
124 { "Bochs", VMM_GUEST_BOCHS }, /* Bochs */
125 { "Xen", VMM_GUEST_XEN }, /* Xen */
126 { "BHYVE", VMM_GUEST_BHYVE }, /* bhyve */
127 { "Seabios", VMM_GUEST_KVM}, /* KVM */
128 { NULL, 0 }
129 };
130
131 static struct vmm_bname vmm_pnames[] = {
132 { "VMware Virtual Platform", VMM_GUEST_VMWARE }, /* VMWare VM */
133 { "Virtual Machine", VMM_GUEST_HYPERV }, /* MS Hyper-V */
134 { "VirtualBox", VMM_GUEST_VBOX }, /* Sun VirtualBox */
135 { "Parallels Virtual Platform", VMM_GUEST_PARALLELS }, /* Parallels VM */
136 { "KVM", VMM_GUEST_KVM }, /* KVM */
137 { NULL, 0 }
138 };
139
140 static const char *const vmm_guest_sysctl_names[] = {
141 "none",
142 "qemu",
143 "plex86",
144 "bochs",
145 "xen",
146 "bhyve",
147 "kvm",
148 "vmware",
149 "hyperv",
150 "vbox",
151 "parallels",
152 "vkernel",
153 "nvmm",
154 "unknown",
155 NULL
156 };
157 CTASSERT(NELEM(vmm_guest_sysctl_names) - 1 == VMM_GUEST_LAST);
158
159 char vmm_vendor[16];
160 SYSCTL_STRING(_kern, OID_AUTO, vmm_vendor, CTLFLAG_RD, vmm_vendor, 0,
161 "Virtual machine vendor");
162
163 /*
164 * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
165 */
166 enum vmm_guest_type
detect_virtual(void)167 detect_virtual(void)
168 {
169 char *sysenv;
170 int i;
171
172 sysenv = kgetenv("smbios.bios.vendor");
173 if (sysenv != NULL) {
174 for (i = 0; vmm_bnames[i].str != NULL; i++)
175 if (strcmp(sysenv, vmm_bnames[i].str) == 0) {
176 kfreeenv(sysenv);
177 return (vmm_bnames[i].type);
178 }
179 kfreeenv(sysenv);
180 }
181 sysenv = kgetenv("smbios.system.product");
182 if (sysenv != NULL) {
183 for (i = 0; vmm_pnames[i].str != NULL; i++)
184 if (strcmp(sysenv, vmm_pnames[i].str) == 0) {
185 kfreeenv(sysenv);
186 return (vmm_pnames[i].type);
187 }
188 kfreeenv(sysenv);
189 }
190 return (VMM_GUEST_NONE);
191 }
192
193 /*
194 * Boot time overrides that are not scaled against main memory
195 */
196 void
init_param1(void)197 init_param1(void)
198 {
199 hz = HZ_DEFAULT;
200 TUNABLE_INT_FETCH("kern.hz", &hz);
201 stathz = hz + 1;
202 TUNABLE_INT_FETCH("kern.stathz", &stathz);
203 profhz = stathz;
204 ustick = 1000000 / hz;
205 nstick = 1000000000 / hz;
206 /* can adjust 30ms in 60s */
207 ntp_default_tick_delta = howmany(30000000, 60 * hz);
208
209 #ifdef VM_SWZONE_SIZE_MAX
210 maxswzone = VM_SWZONE_SIZE_MAX;
211 #endif
212 TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone);
213 #ifdef VM_BCACHE_SIZE_MAX
214 maxbcache = VM_BCACHE_SIZE_MAX;
215 #endif
216 TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
217 maxtsiz = MAXTSIZ;
218 TUNABLE_QUAD_FETCH("kern.maxtsiz", &maxtsiz);
219 dfldsiz = DFLDSIZ;
220 TUNABLE_QUAD_FETCH("kern.dfldsiz", &dfldsiz);
221 maxdsiz = MAXDSIZ;
222 TUNABLE_QUAD_FETCH("kern.maxdsiz", &maxdsiz);
223 dflssiz = DFLSSIZ;
224 TUNABLE_QUAD_FETCH("kern.dflssiz", &dflssiz);
225 maxssiz = MAXSSIZ;
226 TUNABLE_QUAD_FETCH("kern.maxssiz", &maxssiz);
227 sgrowsiz = SGROWSIZ;
228 TUNABLE_QUAD_FETCH("kern.sgrowsiz", &sgrowsiz);
229 maxthrssiz = MAXTHRSSIZ;
230 TUNABLE_QUAD_FETCH("kern.maxthrssiz", &maxthrssiz);
231 }
232
233 /*
234 * Boot time overrides that are scaled against main memory
235 */
236 void
init_param2(int physpages)237 init_param2(int physpages)
238 {
239 size_t limsize;
240
241 /*
242 * Calculate manually becaus the VM page queues / system is not set
243 * up yet.
244 */
245 limsize = (size_t)physpages * PAGE_SIZE;
246 if (limsize > KvaSize)
247 limsize = KvaSize;
248 if (maxswzone > limsize / 2) /* maxswzone size (1/2 of phys mem) */
249 maxswzone = limsize / 2;
250
251 limsize /= 1024 * 1024; /* smaller of KVM or physmem in MB */
252
253 /* Base parameters */
254 maxusers = MAXUSERS;
255 TUNABLE_INT_FETCH("kern.maxusers", &maxusers);
256 if (maxusers == 0) {
257 maxusers = limsize / 8; /* ~384 per 3G */
258 if (maxusers < 32)
259 maxusers = 32;
260 /* no upper limit */
261 }
262
263 /*
264 * The following can be overridden after boot via sysctl. Note:
265 * unless overridden, these macros are ultimately based on maxusers.
266 *
267 * Limit maxproc so that kmap entries cannot be exhausted by
268 * processes. This limitation can be a bit problematic because
269 * processes can have a wide range of complexity.
270 */
271 maxproc = NPROC;
272 TUNABLE_INT_FETCH("kern.maxproc", &maxproc);
273 if (maxproc < 32)
274 maxproc = 32;
275 if (maxproc > limsize * 40)
276 maxproc = limsize * 40;
277
278 /*
279 * Maximum number of open files
280 */
281 maxfiles = MAXFILES;
282 TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles);
283 if (maxfiles < 128)
284 maxfiles = 128;
285
286 /*
287 * Limit file descriptors so no single user can exhaust the
288 * system.
289 *
290 * WARNING: Do not set minfilesperproc too high or the user
291 * can exhaust the system with a combination of fork()
292 * and open(). Actual worst case is:
293 *
294 * (minfilesperproc * maxprocperuid) + maxfilesperuser
295 */
296 maxprocperuid = maxproc / 4;
297 if (maxprocperuid < 128)
298 maxprocperuid = maxproc / 2;
299 minfilesperproc = 8;
300 maxfilesperproc = maxfiles / 4;
301 maxfilesperuser = maxfilesperproc * 2;
302 maxfilesrootres = maxfiles / 20;
303
304 /*
305 * Severe hack to try to prevent pipe() descriptors from
306 * blowing away kernel memory.
307 */
308 if (KvaSize <= (vm_offset_t)(1536LL * 1024 * 1024) &&
309 maxfilesperuser > 20000) {
310 maxfilesperuser = 20000;
311 }
312
313 maxposixlocksperuid = MAXPOSIXLOCKSPERUID;
314 TUNABLE_INT_FETCH("kern.maxposixlocksperuid", &maxposixlocksperuid);
315
316 /*
317 * Unless overridden, NBUF is typically 0 (auto-sized later).
318 */
319 nbuf = NBUF;
320 TUNABLE_LONG_FETCH("kern.nbuf", &nbuf);
321
322 /*
323 * Calculate the size of the callout wheel. Limit to approximately
324 * 5 minutes worth of table (maxproc would have to be pretty huge),
325 * as more is not likely to gain us anything.
326 */
327 ncallout = 16 + maxproc + maxfiles;
328 if (ncallout > 5*60*hz)
329 ncallout = 5*60*hz;
330 TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
331 }
332
333 /*
334 * Sysctl stringifying handler for kern.vmm_guest.
335 */
336 static int
sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS)337 sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS)
338 {
339 return (SYSCTL_OUT(req, vmm_guest_sysctl_names[vmm_guest],
340 strlen(vmm_guest_sysctl_names[vmm_guest])));
341 }
342