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 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 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 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 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