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 int mbuf_wait = 32; /* mbuf sleep time in ticks */ 85 long nbuf; 86 long nswbuf_mem; 87 long nswbuf_kva; 88 long nswbuf_raw; 89 long maxswzone; /* max swmeta KVA storage */ 90 long maxbcache; /* max buffer cache KVA storage */ 91 enum vmm_guest_type vmm_guest = VMM_GUEST_NONE; /* Running as VM guest? */ 92 u_quad_t maxtsiz; /* max text size */ 93 u_quad_t dfldsiz; /* initial data size limit */ 94 u_quad_t maxdsiz; /* max data size */ 95 u_quad_t dflssiz; /* initial stack size limit */ 96 u_quad_t maxssiz; /* max stack size */ 97 u_quad_t sgrowsiz; /* amount to grow stack */ 98 u_quad_t maxthrssiz; /* thread stack area */ 99 100 SYSCTL_PROC(_kern, OID_AUTO, vmm_guest, CTLFLAG_RD | CTLTYPE_STRING, 101 NULL, 0, sysctl_kern_vmm_guest, "A", 102 "Virtual machine guest type"); 103 SYSCTL_QUAD(_kern, OID_AUTO, maxssiz, CTLFLAG_RD, &maxssiz, 0, 104 "Maximum user stack size"); 105 SYSCTL_QUAD(_kern, OID_AUTO, maxthrssiz, CTLFLAG_RD, &maxthrssiz, 0, 106 "Nominal threading stack area"); 107 108 /* 109 * These have to be allocated somewhere; allocating 110 * them here forces loader errors if this file is omitted 111 * (if they've been externed everywhere else; hah!). 112 */ 113 struct buf *swbuf_mem; 114 struct buf *swbuf_kva; 115 struct buf *swbuf_raw; 116 117 struct vmm_bname { 118 const char *str; 119 enum vmm_guest_type type; 120 }; 121 122 static struct vmm_bname vmm_bnames[] = { 123 { "QEMU", VMM_GUEST_QEMU }, /* QEMU */ 124 { "Plex86", VMM_GUEST_PLEX86 }, /* Plex86 */ 125 { "Bochs", VMM_GUEST_BOCHS }, /* Bochs */ 126 { "Xen", VMM_GUEST_XEN }, /* Xen */ 127 { "BHYVE", VMM_GUEST_BHYVE }, /* bhyve */ 128 { "Seabios", VMM_GUEST_KVM}, /* KVM */ 129 { NULL, 0 } 130 }; 131 132 static struct vmm_bname vmm_pnames[] = { 133 { "VMware Virtual Platform", VMM_GUEST_VMWARE }, /* VMWare VM */ 134 { "Virtual Machine", VMM_GUEST_HYPERV }, /* MS Hyper-V */ 135 { "VirtualBox", VMM_GUEST_VBOX }, /* Sun VirtualBox */ 136 { "Parallels Virtual Platform", VMM_GUEST_PARALLELS }, /* Parallels VM */ 137 { "KVM", VMM_GUEST_KVM }, /* KVM */ 138 { NULL, 0 } 139 }; 140 141 static const char *const vmm_guest_sysctl_names[] = { 142 "none", 143 "qemu", 144 "plex86", 145 "bochs", 146 "xen", 147 "bhyve", 148 "kvm", 149 "vmware", 150 "hyperv", 151 "vbox", 152 "parallels", 153 "vkernel", 154 "nvmm", 155 "unknown", 156 NULL 157 }; 158 CTASSERT(NELEM(vmm_guest_sysctl_names) - 1 == VMM_GUEST_LAST); 159 160 char vmm_vendor[16]; 161 SYSCTL_STRING(_kern, OID_AUTO, vmm_vendor, CTLFLAG_RD, vmm_vendor, 0, 162 "Virtual machine vendor"); 163 164 /* 165 * Detect known Virtual Machine hosts by inspecting the emulated BIOS. 166 */ 167 enum vmm_guest_type 168 detect_virtual(void) 169 { 170 char *sysenv; 171 int i; 172 173 sysenv = kgetenv("smbios.bios.vendor"); 174 if (sysenv != NULL) { 175 for (i = 0; vmm_bnames[i].str != NULL; i++) 176 if (strcmp(sysenv, vmm_bnames[i].str) == 0) { 177 kfreeenv(sysenv); 178 return (vmm_bnames[i].type); 179 } 180 kfreeenv(sysenv); 181 } 182 sysenv = kgetenv("smbios.system.product"); 183 if (sysenv != NULL) { 184 for (i = 0; vmm_pnames[i].str != NULL; i++) 185 if (strcmp(sysenv, vmm_pnames[i].str) == 0) { 186 kfreeenv(sysenv); 187 return (vmm_pnames[i].type); 188 } 189 kfreeenv(sysenv); 190 } 191 return (VMM_GUEST_NONE); 192 } 193 194 /* 195 * Boot time overrides that are not scaled against main memory 196 */ 197 void 198 init_param1(void) 199 { 200 hz = HZ_DEFAULT; 201 TUNABLE_INT_FETCH("kern.hz", &hz); 202 stathz = hz + 1; 203 TUNABLE_INT_FETCH("kern.stathz", &stathz); 204 profhz = stathz; 205 ustick = 1000000 / hz; 206 nstick = 1000000000 / hz; 207 /* can adjust 30ms in 60s */ 208 ntp_default_tick_delta = howmany(30000000, 60 * hz); 209 210 #ifdef VM_SWZONE_SIZE_MAX 211 maxswzone = VM_SWZONE_SIZE_MAX; 212 #endif 213 TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone); 214 #ifdef VM_BCACHE_SIZE_MAX 215 maxbcache = VM_BCACHE_SIZE_MAX; 216 #endif 217 TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache); 218 maxtsiz = MAXTSIZ; 219 TUNABLE_QUAD_FETCH("kern.maxtsiz", &maxtsiz); 220 dfldsiz = DFLDSIZ; 221 TUNABLE_QUAD_FETCH("kern.dfldsiz", &dfldsiz); 222 maxdsiz = MAXDSIZ; 223 TUNABLE_QUAD_FETCH("kern.maxdsiz", &maxdsiz); 224 dflssiz = DFLSSIZ; 225 TUNABLE_QUAD_FETCH("kern.dflssiz", &dflssiz); 226 maxssiz = MAXSSIZ; 227 TUNABLE_QUAD_FETCH("kern.maxssiz", &maxssiz); 228 sgrowsiz = SGROWSIZ; 229 TUNABLE_QUAD_FETCH("kern.sgrowsiz", &sgrowsiz); 230 maxthrssiz = MAXTHRSSIZ; 231 TUNABLE_QUAD_FETCH("kern.maxthrssiz", &maxthrssiz); 232 } 233 234 /* 235 * Boot time overrides that are scaled against main memory 236 */ 237 void 238 init_param2(int physpages) 239 { 240 size_t limsize; 241 242 /* 243 * Calculate manually becaus the VM page queues / system is not set 244 * up yet. 245 */ 246 limsize = (size_t)physpages * PAGE_SIZE; 247 if (limsize > KvaSize) 248 limsize = KvaSize; 249 if (maxswzone > limsize / 2) /* maxswzone size (1/2 of phys mem) */ 250 maxswzone = limsize / 2; 251 252 limsize /= 1024 * 1024; /* smaller of KVM or physmem in MB */ 253 254 /* Base parameters */ 255 maxusers = MAXUSERS; 256 TUNABLE_INT_FETCH("kern.maxusers", &maxusers); 257 if (maxusers == 0) { 258 maxusers = limsize / 8; /* ~384 per 3G */ 259 if (maxusers < 32) 260 maxusers = 32; 261 /* no upper limit */ 262 } 263 264 /* 265 * The following can be overridden after boot via sysctl. Note: 266 * unless overridden, these macros are ultimately based on maxusers. 267 * 268 * Limit maxproc so that kmap entries cannot be exhausted by 269 * processes. This limitation can be a bit problematic because 270 * processes can have a wide range of complexity. 271 */ 272 maxproc = NPROC; 273 TUNABLE_INT_FETCH("kern.maxproc", &maxproc); 274 if (maxproc < 32) 275 maxproc = 32; 276 if (maxproc > limsize * 40) 277 maxproc = limsize * 40; 278 279 /* 280 * Maximum number of open files 281 */ 282 maxfiles = MAXFILES; 283 TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles); 284 if (maxfiles < 128) 285 maxfiles = 128; 286 287 /* 288 * Limit file descriptors so no single user can exhaust the 289 * system. 290 * 291 * WARNING: Do not set minfilesperproc too high or the user 292 * can exhaust the system with a combination of fork() 293 * and open(). Actual worst case is: 294 * 295 * (minfilesperproc * maxprocperuid) + maxfilesperuser 296 */ 297 maxprocperuid = maxproc / 4; 298 if (maxprocperuid < 128) 299 maxprocperuid = maxproc / 2; 300 minfilesperproc = 8; 301 maxfilesperproc = maxfiles / 4; 302 maxfilesperuser = maxfilesperproc * 2; 303 maxfilesrootres = maxfiles / 20; 304 305 /* 306 * Severe hack to try to prevent pipe() descriptors from 307 * blowing away kernel memory. 308 */ 309 if (KvaSize <= (vm_offset_t)(1536LL * 1024 * 1024) && 310 maxfilesperuser > 20000) { 311 maxfilesperuser = 20000; 312 } 313 314 maxposixlocksperuid = MAXPOSIXLOCKSPERUID; 315 TUNABLE_INT_FETCH("kern.maxposixlocksperuid", &maxposixlocksperuid); 316 317 /* 318 * Unless overridden, NBUF is typically 0 (auto-sized later). 319 */ 320 nbuf = NBUF; 321 TUNABLE_LONG_FETCH("kern.nbuf", &nbuf); 322 323 /* 324 * Calculate the size of the callout wheel. Limit to approximately 325 * 5 minutes worth of table (maxproc would have to be pretty huge), 326 * as more is not likely to gain us anything. 327 */ 328 ncallout = 16 + maxproc + maxfiles; 329 if (ncallout > 5*60*hz) 330 ncallout = 5*60*hz; 331 TUNABLE_INT_FETCH("kern.ncallout", &ncallout); 332 } 333 334 /* 335 * Sysctl stringifying handler for kern.vmm_guest. 336 */ 337 static int 338 sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS) 339 { 340 return (SYSCTL_OUT(req, vmm_guest_sysctl_names[vmm_guest], 341 strlen(vmm_guest_sysctl_names[vmm_guest]))); 342 } 343