1 /* $NetBSD: identcpu.c,v 1.117 2020/09/05 07:45:44 maxv Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Frank van der Linden, and by Jason R. Thorpe. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.117 2020/09/05 07:45:44 maxv Exp $"); 34 35 #include "opt_xen.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/device.h> 40 #include <sys/cpu.h> 41 42 #include <crypto/aes/aes_impl.h> 43 #include <crypto/aes/arch/x86/aes_ni.h> 44 #include <crypto/aes/arch/x86/aes_sse2.h> 45 #include <crypto/aes/arch/x86/aes_ssse3.h> 46 #include <crypto/aes/arch/x86/aes_via.h> 47 #include <crypto/chacha/chacha_impl.h> 48 #include <crypto/chacha/arch/x86/chacha_sse2.h> 49 50 #include <uvm/uvm_extern.h> 51 52 #include <machine/specialreg.h> 53 #include <machine/pio.h> 54 #include <machine/cpu.h> 55 56 #include <x86/cputypes.h> 57 #include <x86/cacheinfo.h> 58 #include <x86/cpuvar.h> 59 #include <x86/fpu.h> 60 61 #include <x86/x86/vmtreg.h> /* for vmt_hvcall() */ 62 #include <x86/x86/vmtvar.h> /* for vmt_hvcall() */ 63 64 #ifndef XENPV 65 #include "hyperv.h" 66 #if NHYPERV > 0 67 #include <x86/x86/hypervvar.h> 68 #endif 69 #endif 70 71 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO; 72 73 static const struct x86_cache_info amd_cpuid_l2l3cache_assoc_info[] = 74 AMD_L2L3CACHE_INFO; 75 76 int cpu_vendor; 77 char cpu_brand_string[49]; 78 79 int x86_fpu_save __read_mostly; 80 unsigned int x86_fpu_save_size __read_mostly = sizeof(struct save87); 81 uint64_t x86_xsave_features __read_mostly = 0; 82 size_t x86_xsave_offsets[XSAVE_MAX_COMPONENT+1] __read_mostly; 83 size_t x86_xsave_sizes[XSAVE_MAX_COMPONENT+1] __read_mostly; 84 85 /* 86 * Note: these are just the ones that may not have a cpuid instruction. 87 * We deal with the rest in a different way. 88 */ 89 const int i386_nocpuid_cpus[] = { 90 CPUVENDOR_INTEL, CPUCLASS_386, /* CPU_386SX */ 91 CPUVENDOR_INTEL, CPUCLASS_386, /* CPU_386 */ 92 CPUVENDOR_INTEL, CPUCLASS_486, /* CPU_486SX */ 93 CPUVENDOR_INTEL, CPUCLASS_486, /* CPU_486 */ 94 CPUVENDOR_CYRIX, CPUCLASS_486, /* CPU_486DLC */ 95 CPUVENDOR_CYRIX, CPUCLASS_486, /* CPU_6x86 */ 96 CPUVENDOR_NEXGEN, CPUCLASS_386, /* CPU_NX586 */ 97 }; 98 99 static const char cpu_vendor_names[][10] = { 100 "Unknown", "Intel", "NS/Cyrix", "NexGen", "AMD", "IDT/VIA", "Transmeta", 101 "Vortex86" 102 }; 103 104 static const struct x86_cache_info * 105 cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc) 106 { 107 int i; 108 109 for (i = 0; cai[i].cai_desc != 0; i++) { 110 if (cai[i].cai_desc == desc) 111 return (&cai[i]); 112 } 113 114 return (NULL); 115 } 116 117 /* 118 * Get cache info from one of the following: 119 * Intel Deterministic Cache Parameter Leaf (0x04) 120 * AMD Cache Topology Information Leaf (0x8000001d) 121 */ 122 static void 123 cpu_dcp_cacheinfo(struct cpu_info *ci, uint32_t leaf) 124 { 125 u_int descs[4]; 126 int type, level, ways, partitions, linesize, sets, totalsize; 127 int caitype = -1; 128 int i; 129 130 for (i = 0; ; i++) { 131 x86_cpuid2(leaf, i, descs); 132 type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE); 133 if (type == CPUID_DCP_CACHETYPE_N) 134 break; 135 level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL); 136 switch (level) { 137 case 1: 138 if (type == CPUID_DCP_CACHETYPE_I) 139 caitype = CAI_ICACHE; 140 else if (type == CPUID_DCP_CACHETYPE_D) 141 caitype = CAI_DCACHE; 142 else 143 caitype = -1; 144 break; 145 case 2: 146 if (type == CPUID_DCP_CACHETYPE_U) 147 caitype = CAI_L2CACHE; 148 else 149 caitype = -1; 150 break; 151 case 3: 152 if (type == CPUID_DCP_CACHETYPE_U) 153 caitype = CAI_L3CACHE; 154 else 155 caitype = -1; 156 break; 157 default: 158 caitype = -1; 159 break; 160 } 161 if (caitype == -1) 162 continue; 163 164 ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1; 165 partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS) 166 + 1; 167 linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE) 168 + 1; 169 sets = descs[2] + 1; 170 totalsize = ways * partitions * linesize * sets; 171 ci->ci_cinfo[caitype].cai_totalsize = totalsize; 172 ci->ci_cinfo[caitype].cai_associativity = ways; 173 ci->ci_cinfo[caitype].cai_linesize = linesize; 174 } 175 } 176 177 static void 178 cpu_probe_intel_cache(struct cpu_info *ci) 179 { 180 const struct x86_cache_info *cai; 181 u_int descs[4]; 182 int iterations, i, j; 183 uint8_t desc; 184 185 if (cpuid_level >= 2) { 186 /* Parse the cache info from `cpuid leaf 2', if we have it. */ 187 x86_cpuid(2, descs); 188 iterations = descs[0] & 0xff; 189 while (iterations-- > 0) { 190 for (i = 0; i < 4; i++) { 191 if (descs[i] & 0x80000000) 192 continue; 193 for (j = 0; j < 4; j++) { 194 if (i == 0 && j == 0) 195 continue; 196 desc = (descs[i] >> (j * 8)) & 0xff; 197 if (desc == 0) 198 continue; 199 cai = cache_info_lookup( 200 intel_cpuid_cache_info, desc); 201 if (cai != NULL) { 202 ci->ci_cinfo[cai->cai_index] = 203 *cai; 204 } 205 } 206 } 207 } 208 } 209 210 if (cpuid_level < 4) 211 return; 212 213 /* Parse the cache info from `cpuid leaf 4', if we have it. */ 214 cpu_dcp_cacheinfo(ci, 4); 215 } 216 217 static void 218 cpu_probe_intel_errata(struct cpu_info *ci) 219 { 220 u_int family, model, stepping; 221 222 family = CPUID_TO_FAMILY(ci->ci_signature); 223 model = CPUID_TO_MODEL(ci->ci_signature); 224 stepping = CPUID_TO_STEPPING(ci->ci_signature); 225 226 if (family == 0x6 && model == 0x5C && stepping == 0x9) { /* Apollo Lake */ 227 wrmsr(MSR_MISC_ENABLE, 228 rdmsr(MSR_MISC_ENABLE) & ~IA32_MISC_MWAIT_EN); 229 230 cpu_feature[1] &= ~CPUID2_MONITOR; 231 ci->ci_feat_val[1] &= ~CPUID2_MONITOR; 232 } 233 } 234 235 static void 236 cpu_probe_intel(struct cpu_info *ci) 237 { 238 239 if (cpu_vendor != CPUVENDOR_INTEL) 240 return; 241 242 cpu_probe_intel_cache(ci); 243 cpu_probe_intel_errata(ci); 244 } 245 246 static void 247 cpu_probe_amd_cache(struct cpu_info *ci) 248 { 249 const struct x86_cache_info *cp; 250 struct x86_cache_info *cai; 251 int family, model; 252 u_int descs[4]; 253 u_int lfunc; 254 255 family = CPUID_TO_FAMILY(ci->ci_signature); 256 model = CPUID_TO_MODEL(ci->ci_signature); 257 258 /* K5 model 0 has none of this info. */ 259 if (family == 5 && model == 0) 260 return; 261 262 /* Determine the largest extended function value. */ 263 x86_cpuid(0x80000000, descs); 264 lfunc = descs[0]; 265 266 if (lfunc < 0x80000005) 267 return; 268 269 /* Determine L1 cache/TLB info. */ 270 x86_cpuid(0x80000005, descs); 271 272 /* K6-III and higher have large page TLBs. */ 273 if ((family == 5 && model >= 9) || family >= 6) { 274 cai = &ci->ci_cinfo[CAI_ITLB2]; 275 cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]); 276 cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]); 277 cai->cai_linesize = (4 * 1024 * 1024); 278 279 cai = &ci->ci_cinfo[CAI_DTLB2]; 280 cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]); 281 cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]); 282 cai->cai_linesize = (4 * 1024 * 1024); 283 } 284 285 cai = &ci->ci_cinfo[CAI_ITLB]; 286 cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]); 287 cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]); 288 cai->cai_linesize = (4 * 1024); 289 290 cai = &ci->ci_cinfo[CAI_DTLB]; 291 cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]); 292 cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]); 293 cai->cai_linesize = (4 * 1024); 294 295 cai = &ci->ci_cinfo[CAI_DCACHE]; 296 cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]); 297 cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]); 298 cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]); 299 300 cai = &ci->ci_cinfo[CAI_ICACHE]; 301 cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]); 302 cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]); 303 cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]); 304 305 if (lfunc < 0x80000006) 306 return; 307 308 /* Determine L2 cache/TLB info. */ 309 x86_cpuid(0x80000006, descs); 310 311 cai = &ci->ci_cinfo[CAI_L2CACHE]; 312 cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]); 313 cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]); 314 cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]); 315 316 cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, 317 cai->cai_associativity); 318 if (cp != NULL) 319 cai->cai_associativity = cp->cai_associativity; 320 else 321 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 322 323 if (family < 0xf) 324 return; 325 326 /* Determine L3 cache info on AMD Family 10h and newer processors */ 327 cai = &ci->ci_cinfo[CAI_L3CACHE]; 328 cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]); 329 cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]); 330 cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]); 331 332 cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, 333 cai->cai_associativity); 334 if (cp != NULL) 335 cai->cai_associativity = cp->cai_associativity; 336 else 337 cai->cai_associativity = 0; /* XXX Unknown reserved */ 338 339 if (lfunc < 0x80000019) 340 return; 341 342 /* Determine 1GB TLB info. */ 343 x86_cpuid(0x80000019, descs); 344 345 cai = &ci->ci_cinfo[CAI_L1_1GBDTLB]; 346 cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[1]); 347 cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[1]); 348 cai->cai_linesize = (1 * 1024); 349 350 cai = &ci->ci_cinfo[CAI_L1_1GBITLB]; 351 cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]); 352 cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]); 353 cai->cai_linesize = (1 * 1024); 354 355 cai = &ci->ci_cinfo[CAI_L2_1GBDTLB]; 356 cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]); 357 cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]); 358 cai->cai_linesize = (1 * 1024); 359 360 cai = &ci->ci_cinfo[CAI_L2_1GBITLB]; 361 cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[0]); 362 cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[0]); 363 cai->cai_linesize = (1 * 1024); 364 365 if (lfunc < 0x8000001d) 366 return; 367 368 if (ci->ci_feat_val[3] & CPUID_TOPOEXT) 369 cpu_dcp_cacheinfo(ci, 0x8000001d); 370 } 371 372 static void 373 cpu_probe_amd_errata(struct cpu_info *ci) 374 { 375 u_int model; 376 uint64_t val; 377 int flag; 378 379 model = CPUID_TO_MODEL(ci->ci_signature); 380 381 switch (CPUID_TO_FAMILY(ci->ci_signature)) { 382 case 0x05: /* K5 */ 383 if (model == 0) { 384 /* 385 * According to the AMD Processor Recognition App Note, 386 * the AMD-K5 Model 0 uses the wrong bit to indicate 387 * support for global PTEs, instead using bit 9 (APIC) 388 * rather than bit 13 (i.e. "0x200" vs. 0x2000"). 389 */ 390 flag = ci->ci_feat_val[0]; 391 if ((flag & CPUID_APIC) != 0) 392 flag = (flag & ~CPUID_APIC) | CPUID_PGE; 393 ci->ci_feat_val[0] = flag; 394 } 395 break; 396 397 case 0x10: /* Family 10h */ 398 /* 399 * On Family 10h, certain BIOSes do not enable WC+ support. 400 * This causes WC+ to become CD, and degrades guest 401 * performance at the NPT level. 402 * 403 * Explicitly enable WC+ if we're not a guest. 404 */ 405 if (!ISSET(ci->ci_feat_val[1], CPUID2_RAZ)) { 406 val = rdmsr(MSR_BU_CFG2); 407 val &= ~BU_CFG2_CWPLUS_DIS; 408 wrmsr(MSR_BU_CFG2, val); 409 } 410 break; 411 412 case 0x17: 413 /* 414 * "Revision Guide for AMD Family 17h Models 00h-0Fh 415 * Processors" revision 1.12: 416 * 417 * 1057 MWAIT or MWAITX Instructions May Fail to Correctly 418 * Exit From the Monitor Event Pending State 419 * 420 * 1109 MWAIT Instruction May Hang a Thread 421 */ 422 if (model == 0x01) { 423 cpu_feature[1] &= ~CPUID2_MONITOR; 424 ci->ci_feat_val[1] &= ~CPUID2_MONITOR; 425 } 426 break; 427 } 428 } 429 430 static void 431 cpu_probe_amd(struct cpu_info *ci) 432 { 433 434 if (cpu_vendor != CPUVENDOR_AMD) 435 return; 436 437 cpu_probe_amd_cache(ci); 438 cpu_probe_amd_errata(ci); 439 } 440 441 static inline uint8_t 442 cyrix_read_reg(uint8_t reg) 443 { 444 445 outb(0x22, reg); 446 return inb(0x23); 447 } 448 449 static inline void 450 cyrix_write_reg(uint8_t reg, uint8_t data) 451 { 452 453 outb(0x22, reg); 454 outb(0x23, data); 455 } 456 457 static void 458 cpu_probe_cyrix_cmn(struct cpu_info *ci) 459 { 460 /* 461 * i8254 latch check routine: 462 * National Geode (formerly Cyrix MediaGX) has a serious bug in 463 * its built-in i8254-compatible clock module (cs5510 cs5520). 464 * Set the variable 'clock_broken_latch' to indicate it. 465 * 466 * This bug is not present in the cs5530, and the flag 467 * is disabled again in sys/arch/i386/pci/pcib.c if this later 468 * model device is detected. Ideally, this work-around should not 469 * even be in here, it should be in there. XXX 470 */ 471 uint8_t c3; 472 #ifndef XENPV 473 extern int clock_broken_latch; 474 475 switch (ci->ci_signature) { 476 case 0x440: /* Cyrix MediaGX */ 477 case 0x540: /* GXm */ 478 clock_broken_latch = 1; 479 break; 480 } 481 #endif 482 483 /* set up various cyrix registers */ 484 /* 485 * Enable suspend on halt (powersave mode). 486 * When powersave mode is enabled, the TSC stops counting 487 * while the CPU is halted in idle() waiting for an interrupt. 488 * This means we can't use the TSC for interval time in 489 * microtime(9), and thus it is disabled here. 490 * 491 * It still makes a perfectly good cycle counter 492 * for program profiling, so long as you remember you're 493 * counting cycles, and not time. Further, if you don't 494 * mind not using powersave mode, the TSC works just fine, 495 * so this should really be optional. XXX 496 */ 497 cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08); 498 499 /* 500 * Do not disable the TSC on the Geode GX, it's reported to 501 * work fine. 502 */ 503 if (ci->ci_signature != 0x552) 504 ci->ci_feat_val[0] &= ~CPUID_TSC; 505 506 /* enable access to ccr4/ccr5 */ 507 c3 = cyrix_read_reg(0xC3); 508 cyrix_write_reg(0xC3, c3 | 0x10); 509 /* cyrix's workaround for the "coma bug" */ 510 cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8); 511 cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f); 512 cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff); 513 cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87); 514 /* disable access to ccr4/ccr5 */ 515 cyrix_write_reg(0xC3, c3); 516 } 517 518 static void 519 cpu_probe_cyrix(struct cpu_info *ci) 520 { 521 522 if (cpu_vendor != CPUVENDOR_CYRIX || 523 CPUID_TO_FAMILY(ci->ci_signature) < 4 || 524 CPUID_TO_FAMILY(ci->ci_signature) > 6) 525 return; 526 527 cpu_probe_cyrix_cmn(ci); 528 } 529 530 static void 531 cpu_probe_winchip(struct cpu_info *ci) 532 { 533 534 if (cpu_vendor != CPUVENDOR_IDT || 535 CPUID_TO_FAMILY(ci->ci_signature) != 5) 536 return; 537 538 /* WinChip C6 */ 539 if (CPUID_TO_MODEL(ci->ci_signature) == 4) 540 ci->ci_feat_val[0] &= ~CPUID_TSC; 541 } 542 543 static void 544 cpu_probe_c3(struct cpu_info *ci) 545 { 546 u_int family, model, stepping, descs[4], lfunc, msr; 547 struct x86_cache_info *cai; 548 549 if (cpu_vendor != CPUVENDOR_IDT || 550 CPUID_TO_FAMILY(ci->ci_signature) < 6) 551 return; 552 553 family = CPUID_TO_FAMILY(ci->ci_signature); 554 model = CPUID_TO_MODEL(ci->ci_signature); 555 stepping = CPUID_TO_STEPPING(ci->ci_signature); 556 557 /* Determine the largest extended function value. */ 558 x86_cpuid(0x80000000, descs); 559 lfunc = descs[0]; 560 561 if (family == 6) { 562 /* 563 * VIA Eden ESP. 564 * 565 * Quoting from page 3-4 of: "VIA Eden ESP Processor Datasheet" 566 * http://www.via.com.tw/download/mainboards/6/14/Eden20v115.pdf 567 * 568 * 1. The CMPXCHG8B instruction is provided and always enabled, 569 * however, it appears disabled in the corresponding CPUID 570 * function bit 0 to avoid a bug in an early version of 571 * Windows NT. However, this default can be changed via a 572 * bit in the FCR MSR. 573 */ 574 ci->ci_feat_val[0] |= CPUID_CX8; 575 wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | VIA_ACE_ECX8); 576 } 577 578 if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) { 579 /* VIA Nehemiah or Esther. */ 580 x86_cpuid(0xc0000000, descs); 581 lfunc = descs[0]; 582 if (lfunc >= 0xc0000001) { /* has ACE, RNG */ 583 int rng_enable = 0, ace_enable = 0; 584 x86_cpuid(0xc0000001, descs); 585 lfunc = descs[3]; 586 ci->ci_feat_val[4] = lfunc; 587 /* Check for and enable RNG */ 588 if (lfunc & CPUID_VIA_HAS_RNG) { 589 if (!(lfunc & CPUID_VIA_DO_RNG)) { 590 rng_enable++; 591 ci->ci_feat_val[4] |= CPUID_VIA_DO_RNG; 592 } 593 } 594 /* Check for and enable ACE (AES-CBC) */ 595 if (lfunc & CPUID_VIA_HAS_ACE) { 596 if (!(lfunc & CPUID_VIA_DO_ACE)) { 597 ace_enable++; 598 ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE; 599 } 600 } 601 /* Check for and enable SHA */ 602 if (lfunc & CPUID_VIA_HAS_PHE) { 603 if (!(lfunc & CPUID_VIA_DO_PHE)) { 604 ace_enable++; 605 ci->ci_feat_val[4] |= CPUID_VIA_DO_PHE; 606 } 607 } 608 /* Check for and enable ACE2 (AES-CTR) */ 609 if (lfunc & CPUID_VIA_HAS_ACE2) { 610 if (!(lfunc & CPUID_VIA_DO_ACE2)) { 611 ace_enable++; 612 ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE2; 613 } 614 } 615 /* Check for and enable PMM (modmult engine) */ 616 if (lfunc & CPUID_VIA_HAS_PMM) { 617 if (!(lfunc & CPUID_VIA_DO_PMM)) { 618 ace_enable++; 619 ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM; 620 } 621 } 622 623 /* 624 * Actually do the enables. It's a little gross, 625 * but per the PadLock programming guide, "Enabling 626 * PadLock", condition 3, we must enable SSE too or 627 * else the first use of RNG or ACE instructions 628 * will generate a trap. 629 * 630 * We must do this early because of kernel RNG 631 * initialization but it is safe without the full 632 * FPU-detect as all these CPUs have SSE. 633 */ 634 lcr4(rcr4() | CR4_OSFXSR); 635 636 if (rng_enable) { 637 msr = rdmsr(MSR_VIA_RNG); 638 msr |= MSR_VIA_RNG_ENABLE; 639 /* C7 stepping 8 and subsequent CPUs have dual RNG */ 640 if (model > 0xA || (model == 0xA && stepping > 0x7)) { 641 msr |= MSR_VIA_RNG_2NOISE; 642 } 643 wrmsr(MSR_VIA_RNG, msr); 644 } 645 646 if (ace_enable) { 647 msr = rdmsr(MSR_VIA_ACE); 648 wrmsr(MSR_VIA_ACE, msr | VIA_ACE_ENABLE); 649 } 650 } 651 } 652 653 /* Explicitly disable unsafe ALTINST mode. */ 654 if (ci->ci_feat_val[4] & CPUID_VIA_DO_ACE) { 655 msr = rdmsr(MSR_VIA_ACE); 656 wrmsr(MSR_VIA_ACE, msr & ~VIA_ACE_ALTINST); 657 } 658 659 /* 660 * Determine L1 cache/TLB info. 661 */ 662 if (lfunc < 0x80000005) { 663 /* No L1 cache info available. */ 664 return; 665 } 666 667 x86_cpuid(0x80000005, descs); 668 669 cai = &ci->ci_cinfo[CAI_ITLB]; 670 cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]); 671 cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]); 672 cai->cai_linesize = (4 * 1024); 673 674 cai = &ci->ci_cinfo[CAI_DTLB]; 675 cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]); 676 cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]); 677 cai->cai_linesize = (4 * 1024); 678 679 cai = &ci->ci_cinfo[CAI_DCACHE]; 680 cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]); 681 cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]); 682 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]); 683 if (family == 6 && model == 9 && stepping == 8) { 684 /* Erratum: stepping 8 reports 4 when it should be 2 */ 685 cai->cai_associativity = 2; 686 } 687 688 cai = &ci->ci_cinfo[CAI_ICACHE]; 689 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); 690 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); 691 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); 692 if (family == 6 && model == 9 && stepping == 8) { 693 /* Erratum: stepping 8 reports 4 when it should be 2 */ 694 cai->cai_associativity = 2; 695 } 696 697 /* 698 * Determine L2 cache/TLB info. 699 */ 700 if (lfunc < 0x80000006) { 701 /* No L2 cache info available. */ 702 return; 703 } 704 705 x86_cpuid(0x80000006, descs); 706 707 cai = &ci->ci_cinfo[CAI_L2CACHE]; 708 if (family > 6 || model >= 9) { 709 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); 710 cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]); 711 cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]); 712 } else { 713 cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]); 714 cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]); 715 cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]); 716 } 717 } 718 719 static void 720 cpu_probe_geode(struct cpu_info *ci) 721 { 722 723 if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 || 724 CPUID_TO_FAMILY(ci->ci_signature) != 5) 725 return; 726 727 cpu_probe_cyrix_cmn(ci); 728 cpu_probe_amd_cache(ci); 729 } 730 731 static void 732 cpu_probe_vortex86(struct cpu_info *ci) 733 { 734 #define PCI_MODE1_ADDRESS_REG 0x0cf8 735 #define PCI_MODE1_DATA_REG 0x0cfc 736 #define PCI_MODE1_ENABLE 0x80000000UL 737 738 uint32_t reg, idx; 739 740 if (cpu_vendor != CPUVENDOR_VORTEX86) 741 return; 742 /* 743 * CPU model available from "Customer ID register" in 744 * North Bridge Function 0 PCI space 745 * we can't use pci_conf_read() because the PCI subsystem is not 746 * not initialised early enough 747 */ 748 749 outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE | 0x90); 750 reg = inl(PCI_MODE1_DATA_REG); 751 752 if ((reg & 0xf0ffffff) != 0x30504d44) { 753 idx = 0; 754 } else { 755 idx = (reg >> 24) & 0xf; 756 } 757 758 static const char *cpu_vortex86_flavor[] = { 759 "??", "SX", "DX", "MX", "DX2", "MX+", "DX3", "EX", "EX2", 760 }; 761 idx = idx < __arraycount(cpu_vortex86_flavor) ? idx : 0; 762 snprintf(cpu_brand_string, sizeof(cpu_brand_string), "Vortex86%s", 763 cpu_vortex86_flavor[idx]); 764 765 #undef PCI_MODE1_ENABLE 766 #undef PCI_MODE1_ADDRESS_REG 767 #undef PCI_MODE1_DATA_REG 768 } 769 770 static void 771 cpu_probe_fpu_old(struct cpu_info *ci) 772 { 773 #if defined(__i386__) && !defined(XENPV) 774 775 clts(); 776 fninit(); 777 778 /* Check for 'FDIV' bug on the original Pentium */ 779 if (npx586bug1(4195835, 3145727) != 0) 780 /* NB 120+MHz cpus are not affected */ 781 i386_fpu_fdivbug = 1; 782 783 stts(); 784 #endif 785 } 786 787 static void 788 cpu_probe_fpu(struct cpu_info *ci) 789 { 790 u_int descs[4]; 791 int i; 792 793 x86_fpu_save = FPU_SAVE_FSAVE; 794 795 #ifdef i386 796 /* If we have FXSAVE/FXRESTOR, use them. */ 797 if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) { 798 i386_use_fxsave = 0; 799 cpu_probe_fpu_old(ci); 800 return; 801 } 802 803 i386_use_fxsave = 1; 804 /* 805 * If we have SSE/SSE2, enable XMM exceptions, and 806 * notify userland. 807 */ 808 if (ci->ci_feat_val[0] & CPUID_SSE) 809 i386_has_sse = 1; 810 if (ci->ci_feat_val[0] & CPUID_SSE2) 811 i386_has_sse2 = 1; 812 #else 813 /* 814 * For amd64 i386_use_fxsave, i386_has_sse and i386_has_sse2 are 815 * #defined to 1, because fxsave/sse/sse2 are always present. 816 */ 817 #endif 818 819 x86_fpu_save = FPU_SAVE_FXSAVE; 820 x86_fpu_save_size = sizeof(struct fxsave); 821 822 /* See if XSAVE is supported */ 823 if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0) 824 return; 825 826 #ifdef XENPV 827 /* 828 * Xen kernel can disable XSAVE via "no-xsave" option, in that case 829 * the XSAVE/XRSTOR instructions become privileged and trigger 830 * supervisor trap. OSXSAVE flag seems to be reliably set according 831 * to whether XSAVE is actually available. 832 */ 833 if ((ci->ci_feat_val[1] & CPUID2_OSXSAVE) == 0) 834 return; 835 #endif 836 837 x86_fpu_save = FPU_SAVE_XSAVE; 838 839 x86_cpuid2(0xd, 1, descs); 840 if (descs[0] & CPUID_PES1_XSAVEOPT) 841 x86_fpu_save = FPU_SAVE_XSAVEOPT; 842 843 /* Get features and maximum size of the save area */ 844 x86_cpuid(0xd, descs); 845 if (descs[2] > sizeof(struct fxsave)) 846 x86_fpu_save_size = descs[2]; 847 848 x86_xsave_features = (uint64_t)descs[3] << 32 | descs[0]; 849 850 /* Get component offsets and sizes for the save area */ 851 for (i = XSAVE_YMM_Hi128; i < __arraycount(x86_xsave_offsets); i++) { 852 if (x86_xsave_features & __BIT(i)) { 853 x86_cpuid2(0xd, i, descs); 854 x86_xsave_offsets[i] = descs[1]; 855 x86_xsave_sizes[i] = descs[0]; 856 } 857 } 858 } 859 860 void 861 cpu_probe(struct cpu_info *ci) 862 { 863 u_int descs[4]; 864 int i; 865 uint32_t miscbytes; 866 uint32_t brand[12]; 867 868 if (ci == &cpu_info_primary) { 869 cpu_vendor = i386_nocpuid_cpus[cputype << 1]; 870 cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1]; 871 } 872 873 if (cpuid_level < 0) { 874 /* cpuid instruction not supported */ 875 cpu_probe_fpu_old(ci); 876 return; 877 } 878 879 for (i = 0; i < __arraycount(ci->ci_feat_val); i++) { 880 ci->ci_feat_val[i] = 0; 881 } 882 883 x86_cpuid(0, descs); 884 cpuid_level = descs[0]; 885 ci->ci_max_cpuid = descs[0]; 886 887 ci->ci_vendor[0] = descs[1]; 888 ci->ci_vendor[2] = descs[2]; 889 ci->ci_vendor[1] = descs[3]; 890 ci->ci_vendor[3] = 0; 891 892 if (ci == &cpu_info_primary) { 893 if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0) 894 cpu_vendor = CPUVENDOR_INTEL; 895 else if (memcmp(ci->ci_vendor, "AuthenticAMD", 12) == 0) 896 cpu_vendor = CPUVENDOR_AMD; 897 else if (memcmp(ci->ci_vendor, "CyrixInstead", 12) == 0) 898 cpu_vendor = CPUVENDOR_CYRIX; 899 else if (memcmp(ci->ci_vendor, "Geode by NSC", 12) == 0) 900 cpu_vendor = CPUVENDOR_CYRIX; 901 else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0) 902 cpu_vendor = CPUVENDOR_IDT; 903 else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0) 904 cpu_vendor = CPUVENDOR_TRANSMETA; 905 else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0) 906 cpu_vendor = CPUVENDOR_VORTEX86; 907 else 908 cpu_vendor = CPUVENDOR_UNKNOWN; 909 } 910 911 if (cpuid_level >= 1) { 912 x86_cpuid(1, descs); 913 ci->ci_signature = descs[0]; 914 miscbytes = descs[1]; 915 ci->ci_feat_val[1] = descs[2]; 916 ci->ci_feat_val[0] = descs[3]; 917 918 if (ci == &cpu_info_primary) { 919 /* Determine family + class. */ 920 cpu_class = CPUID_TO_FAMILY(ci->ci_signature) 921 + (CPUCLASS_386 - 3); 922 if (cpu_class > CPUCLASS_686) 923 cpu_class = CPUCLASS_686; 924 } 925 926 /* CLFLUSH line size is next 8 bits */ 927 if (ci->ci_feat_val[0] & CPUID_CLFSH) 928 ci->ci_cflush_lsize 929 = __SHIFTOUT(miscbytes, CPUID_CLFLUSH_SIZE) << 3; 930 ci->ci_initapicid = __SHIFTOUT(miscbytes, CPUID_LOCAL_APIC_ID); 931 } 932 933 /* 934 * Get the basic information from the extended cpuid leafs. 935 * These were first implemented by amd, but most of the values 936 * match with those generated by modern intel cpus. 937 */ 938 x86_cpuid(0x80000000, descs); 939 if (descs[0] >= 0x80000000) 940 ci->ci_max_ext_cpuid = descs[0]; 941 else 942 ci->ci_max_ext_cpuid = 0; 943 944 if (ci->ci_max_ext_cpuid >= 0x80000001) { 945 /* Determine the extended feature flags. */ 946 x86_cpuid(0x80000001, descs); 947 ci->ci_feat_val[3] = descs[2]; /* %ecx */ 948 ci->ci_feat_val[2] = descs[3]; /* %edx */ 949 } 950 951 if (ci->ci_max_ext_cpuid >= 0x80000004) { 952 x86_cpuid(0x80000002, brand); 953 x86_cpuid(0x80000003, brand + 4); 954 x86_cpuid(0x80000004, brand + 8); 955 /* Skip leading spaces on brand */ 956 for (i = 0; i < 48; i++) { 957 if (((char *) brand)[i] != ' ') 958 break; 959 } 960 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); 961 } 962 963 /* 964 * Get the structured extended features. 965 */ 966 if (cpuid_level >= 7) { 967 x86_cpuid(7, descs); 968 ci->ci_feat_val[5] = descs[1]; /* %ebx */ 969 ci->ci_feat_val[6] = descs[2]; /* %ecx */ 970 ci->ci_feat_val[7] = descs[3]; /* %edx */ 971 } 972 973 cpu_probe_intel(ci); 974 cpu_probe_amd(ci); 975 cpu_probe_cyrix(ci); 976 cpu_probe_winchip(ci); 977 cpu_probe_c3(ci); 978 cpu_probe_geode(ci); 979 cpu_probe_vortex86(ci); 980 981 if (ci == &cpu_info_primary) { 982 cpu_probe_fpu(ci); 983 } 984 985 #ifndef XENPV 986 x86_cpu_topology(ci); 987 #endif 988 989 if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) && 990 (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) { 991 /* Enable thermal monitor 1. */ 992 wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) | (1<<3)); 993 } 994 995 ci->ci_feat_val[0] &= ~CPUID_FEAT_BLACKLIST; 996 if (ci == &cpu_info_primary) { 997 /* If first. Boot Processor is the cpu_feature reference. */ 998 for (i = 0; i < __arraycount(cpu_feature); i++) { 999 cpu_feature[i] = ci->ci_feat_val[i]; 1000 } 1001 identify_hypervisor(); 1002 #ifndef XENPV 1003 /* Early patch of text segment. */ 1004 x86_patch(true); 1005 #endif 1006 1007 /* AES */ 1008 #ifdef __x86_64__ /* not yet implemented on i386 */ 1009 if (cpu_feature[1] & CPUID2_AESNI) 1010 aes_md_init(&aes_ni_impl); 1011 else 1012 #endif 1013 if (cpu_feature[4] & CPUID_VIA_HAS_ACE) 1014 aes_md_init(&aes_via_impl); 1015 else if (i386_has_sse && i386_has_sse2 && 1016 (cpu_feature[1] & CPUID2_SSE3) && 1017 (cpu_feature[1] & CPUID2_SSSE3)) 1018 aes_md_init(&aes_ssse3_impl); 1019 else if (i386_has_sse && i386_has_sse2) 1020 aes_md_init(&aes_sse2_impl); 1021 1022 /* ChaCha */ 1023 if (i386_has_sse && i386_has_sse2) 1024 chacha_md_init(&chacha_sse2_impl); 1025 } else { 1026 /* 1027 * If not first. Warn about cpu_feature mismatch for 1028 * secondary CPUs. 1029 */ 1030 for (i = 0; i < __arraycount(cpu_feature); i++) { 1031 if (cpu_feature[i] != ci->ci_feat_val[i]) 1032 aprint_error_dev(ci->ci_dev, 1033 "feature mismatch: cpu_feature[%d] is " 1034 "%#x, but CPU reported %#x\n", 1035 i, cpu_feature[i], ci->ci_feat_val[i]); 1036 } 1037 } 1038 } 1039 1040 /* Write what we know about the cpu to the console... */ 1041 void 1042 cpu_identify(struct cpu_info *ci) 1043 { 1044 1045 cpu_setmodel("%s %d86-class", 1046 cpu_vendor_names[cpu_vendor], cpu_class + 3); 1047 if (cpu_brand_string[0] != '\0') { 1048 aprint_normal_dev(ci->ci_dev, "%s", cpu_brand_string); 1049 } else { 1050 aprint_normal_dev(ci->ci_dev, "%s", cpu_getmodel()); 1051 if (ci->ci_data.cpu_cc_freq != 0) 1052 aprint_normal(", %dMHz", 1053 (int)(ci->ci_data.cpu_cc_freq / 1000000)); 1054 } 1055 if (ci->ci_signature != 0) 1056 aprint_normal(", id 0x%x", ci->ci_signature); 1057 aprint_normal("\n"); 1058 aprint_normal_dev(ci->ci_dev, "node %u, package %u, core %u, smt %u\n", 1059 ci->ci_numa_id, ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id); 1060 if (cpu_brand_string[0] == '\0') { 1061 strlcpy(cpu_brand_string, cpu_getmodel(), 1062 sizeof(cpu_brand_string)); 1063 } 1064 if (cpu_class == CPUCLASS_386) { 1065 panic("NetBSD requires an 80486DX or later processor"); 1066 } 1067 if (cputype == CPU_486DLC) { 1068 aprint_error("WARNING: BUGGY CYRIX CACHE\n"); 1069 } 1070 1071 #if !defined(XENPV) || defined(DOM0OPS) /* on Xen PV rdmsr is for Dom0 only */ 1072 if (cpu_vendor == CPUVENDOR_AMD /* check enablement of an */ 1073 && device_unit(ci->ci_dev) == 0 /* AMD feature only once */ 1074 && ((cpu_feature[3] & CPUID_SVM) == CPUID_SVM)) { 1075 uint64_t val; 1076 1077 val = rdmsr(MSR_VMCR); 1078 if (((val & VMCR_SVMED) == VMCR_SVMED) 1079 && ((val & VMCR_LOCK) == VMCR_LOCK)) { 1080 aprint_normal_dev(ci->ci_dev, 1081 "SVM disabled by the BIOS\n"); 1082 } 1083 } 1084 #endif 1085 1086 #ifdef i386 1087 if (i386_fpu_fdivbug == 1) 1088 aprint_normal_dev(ci->ci_dev, 1089 "WARNING: Pentium FDIV bug detected!\n"); 1090 1091 if (cpu_vendor == CPUVENDOR_TRANSMETA) { 1092 u_int descs[4]; 1093 x86_cpuid(0x80860000, descs); 1094 if (descs[0] >= 0x80860007) 1095 /* Create longrun sysctls */ 1096 tmx86_init_longrun(); 1097 } 1098 #endif /* i386 */ 1099 1100 } 1101 1102 /* 1103 * Hypervisor 1104 */ 1105 vm_guest_t vm_guest = VM_GUEST_NO; 1106 1107 static const char * const vm_bios_vendors[] = { 1108 "QEMU", /* QEMU */ 1109 "Plex86", /* Plex86 */ 1110 "Bochs", /* Bochs */ 1111 "Xen", /* Xen */ 1112 "BHYVE", /* bhyve */ 1113 "Seabios", /* KVM */ 1114 }; 1115 1116 static const char * const vm_system_products[] = { 1117 "VMware Virtual Platform", /* VMWare VM */ 1118 "Virtual Machine", /* Microsoft VirtualPC */ 1119 "VirtualBox", /* Sun xVM VirtualBox */ 1120 "Parallels Virtual Platform", /* Parallels VM */ 1121 "KVM", /* KVM */ 1122 }; 1123 1124 void 1125 identify_hypervisor(void) 1126 { 1127 u_int regs[6]; 1128 char hv_vendor[12]; 1129 const char *p; 1130 int i; 1131 1132 if (vm_guest != VM_GUEST_NO) 1133 return; 1134 1135 /* 1136 * [RFC] CPUID usage for interaction between Hypervisors and Linux. 1137 * http://lkml.org/lkml/2008/10/1/246 1138 * 1139 * KB1009458: Mechanisms to determine if software is running in 1140 * a VMware virtual machine 1141 * http://kb.vmware.com/kb/1009458 1142 */ 1143 if (ISSET(cpu_feature[1], CPUID2_RAZ)) { 1144 vm_guest = VM_GUEST_VM; 1145 x86_cpuid(0x40000000, regs); 1146 if (regs[0] >= 0x40000000) { 1147 memcpy(&hv_vendor[0], ®s[1], sizeof(*regs)); 1148 memcpy(&hv_vendor[4], ®s[2], sizeof(*regs)); 1149 memcpy(&hv_vendor[8], ®s[3], sizeof(*regs)); 1150 if (memcmp(hv_vendor, "VMwareVMware", 12) == 0) 1151 vm_guest = VM_GUEST_VMWARE; 1152 else if (memcmp(hv_vendor, "Microsoft Hv", 12) == 0) { 1153 vm_guest = VM_GUEST_HV; 1154 #if NHYPERV > 0 1155 hyperv_early_init(); 1156 #endif 1157 } else if (memcmp(hv_vendor, "KVMKVMKVM\0\0\0", 12) == 0) 1158 vm_guest = VM_GUEST_KVM; 1159 else if (memcmp(hv_vendor, "XenVMMXenVMM", 12) == 0) 1160 vm_guest = VM_GUEST_XENHVM; 1161 /* FreeBSD bhyve: "bhyve bhyve " */ 1162 /* OpenBSD vmm: "OpenBSDVMM58" */ 1163 /* NetBSD nvmm: "___ NVMM ___" */ 1164 } 1165 return; 1166 } 1167 1168 /* 1169 * Examine SMBIOS strings for older hypervisors. 1170 */ 1171 p = pmf_get_platform("system-serial"); 1172 if (p != NULL) { 1173 if (strncmp(p, "VMware-", 7) == 0 || strncmp(p, "VMW", 3) == 0) { 1174 vmt_hvcall(VM_CMD_GET_VERSION, regs); 1175 if (regs[1] == VM_MAGIC) { 1176 vm_guest = VM_GUEST_VMWARE; 1177 return; 1178 } 1179 } 1180 } 1181 p = pmf_get_platform("bios-vendor"); 1182 if (p != NULL) { 1183 for (i = 0; i < __arraycount(vm_bios_vendors); i++) { 1184 if (strcmp(p, vm_bios_vendors[i]) == 0) { 1185 vm_guest = VM_GUEST_VM; 1186 return; 1187 } 1188 } 1189 } 1190 p = pmf_get_platform("system-product"); 1191 if (p != NULL) { 1192 for (i = 0; i < __arraycount(vm_system_products); i++) { 1193 if (strcmp(p, vm_system_products[i]) == 0) { 1194 vm_guest = VM_GUEST_VM; 1195 return; 1196 } 1197 } 1198 } 1199 } 1200