File:  [Qemu by Fabrice Bellard] / qemu / target-i386 / cpuid.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:31:13 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    1: /*
    2:  *  i386 CPUID helper functions
    3:  *
    4:  *  Copyright (c) 2003 Fabrice Bellard
    5:  *
    6:  * This library is free software; you can redistribute it and/or
    7:  * modify it under the terms of the GNU Lesser General Public
    8:  * License as published by the Free Software Foundation; either
    9:  * version 2 of the License, or (at your option) any later version.
   10:  *
   11:  * This library is distributed in the hope that it will be useful,
   12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * Lesser General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU Lesser General Public
   17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
   18:  */
   19: #include <stdlib.h>
   20: #include <stdio.h>
   21: #include <string.h>
   22: #include <inttypes.h>
   23: 
   24: #include "cpu.h"
   25: #include "kvm.h"
   26: 
   27: #include "qemu-option.h"
   28: #include "qemu-config.h"
   29: 
   30: /* feature flags taken from "Intel Processor Identification and the CPUID
   31:  * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
   32:  * between feature naming conventions, aliases may be added.
   33:  */
   34: static const char *feature_name[] = {
   35:     "fpu", "vme", "de", "pse",
   36:     "tsc", "msr", "pae", "mce",
   37:     "cx8", "apic", NULL, "sep",
   38:     "mtrr", "pge", "mca", "cmov",
   39:     "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
   40:     NULL, "ds" /* Intel dts */, "acpi", "mmx",
   41:     "fxsr", "sse", "sse2", "ss",
   42:     "ht" /* Intel htt */, "tm", "ia64", "pbe",
   43: };
   44: static const char *ext_feature_name[] = {
   45:     "pni|sse3" /* Intel,AMD sse3 */, "pclmuldq", "dtes64", "monitor",
   46:     "ds_cpl", "vmx", "smx", "est",
   47:     "tm2", "ssse3", "cid", NULL,
   48:     "fma", "cx16", "xtpr", "pdcm",
   49:     NULL, NULL, "dca", "sse4.1|sse4_1",
   50:     "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
   51:     NULL, "aes", "xsave", "osxsave",
   52:     "avx", NULL, NULL, "hypervisor",
   53: };
   54: static const char *ext2_feature_name[] = {
   55:     "fpu", "vme", "de", "pse",
   56:     "tsc", "msr", "pae", "mce",
   57:     "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
   58:     "mtrr", "pge", "mca", "cmov",
   59:     "pat", "pse36", NULL, NULL /* Linux mp */,
   60:     "nx" /* Intel xd */, NULL, "mmxext", "mmx",
   61:     "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp",
   62:     NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
   63: };
   64: static const char *ext3_feature_name[] = {
   65:     "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
   66:     "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
   67:     "3dnowprefetch", "osvw", "ibs", "xop",
   68:     "skinit", "wdt", NULL, NULL,
   69:     "fma4", NULL, "cvt16", "nodeid_msr",
   70:     NULL, NULL, NULL, NULL,
   71:     NULL, NULL, NULL, NULL,
   72:     NULL, NULL, NULL, NULL,
   73: };
   74: 
   75: static const char *kvm_feature_name[] = {
   76:     "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL,
   77:     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
   78:     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
   79:     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
   80: };
   81: 
   82: static const char *svm_feature_name[] = {
   83:     "npt", "lbrv", "svm_lock", "nrip_save",
   84:     "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
   85:     NULL, NULL, "pause_filter", NULL,
   86:     "pfthreshold", NULL, NULL, NULL,
   87:     NULL, NULL, NULL, NULL,
   88:     NULL, NULL, NULL, NULL,
   89:     NULL, NULL, NULL, NULL,
   90:     NULL, NULL, NULL, NULL,
   91: };
   92: 
   93: /* collects per-function cpuid data
   94:  */
   95: typedef struct model_features_t {
   96:     uint32_t *guest_feat;
   97:     uint32_t *host_feat;
   98:     uint32_t check_feat;
   99:     const char **flag_names;
  100:     uint32_t cpuid;
  101:     } model_features_t;
  102: 
  103: int check_cpuid = 0;
  104: int enforce_cpuid = 0;
  105: 
  106: void host_cpuid(uint32_t function, uint32_t count,
  107:                 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
  108: {
  109: #if defined(CONFIG_KVM)
  110:     uint32_t vec[4];
  111: 
  112: #ifdef __x86_64__
  113:     asm volatile("cpuid"
  114:                  : "=a"(vec[0]), "=b"(vec[1]),
  115:                    "=c"(vec[2]), "=d"(vec[3])
  116:                  : "0"(function), "c"(count) : "cc");
  117: #else
  118:     asm volatile("pusha \n\t"
  119:                  "cpuid \n\t"
  120:                  "mov %%eax, 0(%2) \n\t"
  121:                  "mov %%ebx, 4(%2) \n\t"
  122:                  "mov %%ecx, 8(%2) \n\t"
  123:                  "mov %%edx, 12(%2) \n\t"
  124:                  "popa"
  125:                  : : "a"(function), "c"(count), "S"(vec)
  126:                  : "memory", "cc");
  127: #endif
  128: 
  129:     if (eax)
  130:         *eax = vec[0];
  131:     if (ebx)
  132:         *ebx = vec[1];
  133:     if (ecx)
  134:         *ecx = vec[2];
  135:     if (edx)
  136:         *edx = vec[3];
  137: #endif
  138: }
  139: 
  140: #define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
  141: 
  142: /* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
  143:  * a substring.  ex if !NULL points to the first char after a substring,
  144:  * otherwise the string is assumed to sized by a terminating nul.
  145:  * Return lexical ordering of *s1:*s2.
  146:  */
  147: static int sstrcmp(const char *s1, const char *e1, const char *s2,
  148:     const char *e2)
  149: {
  150:     for (;;) {
  151:         if (!*s1 || !*s2 || *s1 != *s2)
  152:             return (*s1 - *s2);
  153:         ++s1, ++s2;
  154:         if (s1 == e1 && s2 == e2)
  155:             return (0);
  156:         else if (s1 == e1)
  157:             return (*s2);
  158:         else if (s2 == e2)
  159:             return (*s1);
  160:     }
  161: }
  162: 
  163: /* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
  164:  * '|' delimited (possibly empty) strings in which case search for a match
  165:  * within the alternatives proceeds left to right.  Return 0 for success,
  166:  * non-zero otherwise.
  167:  */
  168: static int altcmp(const char *s, const char *e, const char *altstr)
  169: {
  170:     const char *p, *q;
  171: 
  172:     for (q = p = altstr; ; ) {
  173:         while (*p && *p != '|')
  174:             ++p;
  175:         if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
  176:             return (0);
  177:         if (!*p)
  178:             return (1);
  179:         else
  180:             q = ++p;
  181:     }
  182: }
  183: 
  184: /* search featureset for flag *[s..e), if found set corresponding bit in
  185:  * *pval and return true, otherwise return false
  186:  */
  187: static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
  188:                            const char **featureset)
  189: {
  190:     uint32_t mask;
  191:     const char **ppc;
  192:     bool found = false;
  193: 
  194:     for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
  195:         if (*ppc && !altcmp(s, e, *ppc)) {
  196:             *pval |= mask;
  197:             found = true;
  198:         }
  199:     }
  200:     return found;
  201: }
  202: 
  203: static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
  204:                                     uint32_t *ext_features,
  205:                                     uint32_t *ext2_features,
  206:                                     uint32_t *ext3_features,
  207:                                     uint32_t *kvm_features,
  208:                                     uint32_t *svm_features)
  209: {
  210:     if (!lookup_feature(features, flagname, NULL, feature_name) &&
  211:         !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
  212:         !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
  213:         !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
  214:         !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
  215:         !lookup_feature(svm_features, flagname, NULL, svm_feature_name))
  216:             fprintf(stderr, "CPU feature %s not found\n", flagname);
  217: }
  218: 
  219: typedef struct x86_def_t {
  220:     struct x86_def_t *next;
  221:     const char *name;
  222:     uint32_t level;
  223:     uint32_t vendor1, vendor2, vendor3;
  224:     int family;
  225:     int model;
  226:     int stepping;
  227:     int tsc_khz;
  228:     uint32_t features, ext_features, ext2_features, ext3_features;
  229:     uint32_t kvm_features, svm_features;
  230:     uint32_t xlevel;
  231:     char model_id[48];
  232:     int vendor_override;
  233:     uint32_t flags;
  234:     /* Store the results of Centaur's CPUID instructions */
  235:     uint32_t ext4_features;
  236:     uint32_t xlevel2;
  237: } x86_def_t;
  238: 
  239: #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
  240: #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
  241:           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
  242: #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
  243:           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
  244:           CPUID_PSE36 | CPUID_FXSR)
  245: #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
  246: #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
  247:           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
  248:           CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
  249:           CPUID_PAE | CPUID_SEP | CPUID_APIC)
  250: #define EXT2_FEATURE_MASK 0x0183F3FF
  251: 
  252: #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
  253:           CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
  254:           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
  255:           CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
  256:           CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
  257:           /* partly implemented:
  258:           CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
  259:           CPUID_PSE36 (needed for Solaris) */
  260:           /* missing:
  261:           CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
  262: #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
  263:           CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
  264:           CPUID_EXT_HYPERVISOR)
  265:           /* missing:
  266:           CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
  267:           CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
  268: #define TCG_EXT2_FEATURES ((TCG_FEATURES & EXT2_FEATURE_MASK) | \
  269:           CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
  270:           CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
  271:           /* missing:
  272:           CPUID_EXT2_PDPE1GB */
  273: #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
  274:           CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
  275: #define TCG_SVM_FEATURES 0
  276: 
  277: /* maintains list of cpu model definitions
  278:  */
  279: static x86_def_t *x86_defs = {NULL};
  280: 
  281: /* built-in cpu model definitions (deprecated)
  282:  */
  283: static x86_def_t builtin_x86_defs[] = {
  284:     {
  285:         .name = "qemu64",
  286:         .level = 4,
  287:         .vendor1 = CPUID_VENDOR_AMD_1,
  288:         .vendor2 = CPUID_VENDOR_AMD_2,
  289:         .vendor3 = CPUID_VENDOR_AMD_3,
  290:         .family = 6,
  291:         .model = 2,
  292:         .stepping = 3,
  293:         .features = PPRO_FEATURES |
  294:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
  295:             CPUID_PSE36,
  296:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
  297:         .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
  298:             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
  299:         .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
  300:             CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
  301:         .xlevel = 0x8000000A,
  302:         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
  303:     },
  304:     {
  305:         .name = "phenom",
  306:         .level = 5,
  307:         .vendor1 = CPUID_VENDOR_AMD_1,
  308:         .vendor2 = CPUID_VENDOR_AMD_2,
  309:         .vendor3 = CPUID_VENDOR_AMD_3,
  310:         .family = 16,
  311:         .model = 2,
  312:         .stepping = 3,
  313:         .features = PPRO_FEATURES |
  314:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
  315:             CPUID_PSE36 | CPUID_VME | CPUID_HT,
  316:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
  317:             CPUID_EXT_POPCNT,
  318:         .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
  319:             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
  320:             CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
  321:             CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
  322:         /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
  323:                     CPUID_EXT3_CR8LEG,
  324:                     CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
  325:                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
  326:         .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
  327:             CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
  328:         .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
  329:         .xlevel = 0x8000001A,
  330:         .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
  331:     },
  332:     {
  333:         .name = "core2duo",
  334:         .level = 10,
  335:         .family = 6,
  336:         .model = 15,
  337:         .stepping = 11,
  338:         .features = PPRO_FEATURES |
  339:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
  340:             CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
  341:             CPUID_HT | CPUID_TM | CPUID_PBE,
  342:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
  343:             CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
  344:             CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
  345:         .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
  346:         .ext3_features = CPUID_EXT3_LAHF_LM,
  347:         .xlevel = 0x80000008,
  348:         .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
  349:     },
  350:     {
  351:         .name = "kvm64",
  352:         .level = 5,
  353:         .vendor1 = CPUID_VENDOR_INTEL_1,
  354:         .vendor2 = CPUID_VENDOR_INTEL_2,
  355:         .vendor3 = CPUID_VENDOR_INTEL_3,
  356:         .family = 15,
  357:         .model = 6,
  358:         .stepping = 1,
  359:         /* Missing: CPUID_VME, CPUID_HT */
  360:         .features = PPRO_FEATURES |
  361:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
  362:             CPUID_PSE36,
  363:         /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
  364:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
  365:         /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
  366:         .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
  367:             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
  368:         /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
  369:                     CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
  370:                     CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
  371:                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
  372:         .ext3_features = 0,
  373:         .xlevel = 0x80000008,
  374:         .model_id = "Common KVM processor"
  375:     },
  376:     {
  377:         .name = "qemu32",
  378:         .level = 4,
  379:         .family = 6,
  380:         .model = 3,
  381:         .stepping = 3,
  382:         .features = PPRO_FEATURES,
  383:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
  384:         .xlevel = 0x80000004,
  385:         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
  386:     },
  387:     {
  388:         .name = "kvm32",
  389:         .level = 5,
  390:         .family = 15,
  391:         .model = 6,
  392:         .stepping = 1,
  393:         .features = PPRO_FEATURES |
  394:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
  395:         .ext_features = CPUID_EXT_SSE3,
  396:         .ext2_features = PPRO_FEATURES & EXT2_FEATURE_MASK,
  397:         .ext3_features = 0,
  398:         .xlevel = 0x80000008,
  399:         .model_id = "Common 32-bit KVM processor"
  400:     },
  401:     {
  402:         .name = "coreduo",
  403:         .level = 10,
  404:         .family = 6,
  405:         .model = 14,
  406:         .stepping = 8,
  407:         .features = PPRO_FEATURES | CPUID_VME |
  408:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
  409:             CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
  410:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
  411:             CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
  412:         .ext2_features = CPUID_EXT2_NX,
  413:         .xlevel = 0x80000008,
  414:         .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
  415:     },
  416:     {
  417:         .name = "486",
  418:         .level = 1,
  419:         .family = 4,
  420:         .model = 0,
  421:         .stepping = 0,
  422:         .features = I486_FEATURES,
  423:         .xlevel = 0,
  424:     },
  425:     {
  426:         .name = "pentium",
  427:         .level = 1,
  428:         .family = 5,
  429:         .model = 4,
  430:         .stepping = 3,
  431:         .features = PENTIUM_FEATURES,
  432:         .xlevel = 0,
  433:     },
  434:     {
  435:         .name = "pentium2",
  436:         .level = 2,
  437:         .family = 6,
  438:         .model = 5,
  439:         .stepping = 2,
  440:         .features = PENTIUM2_FEATURES,
  441:         .xlevel = 0,
  442:     },
  443:     {
  444:         .name = "pentium3",
  445:         .level = 2,
  446:         .family = 6,
  447:         .model = 7,
  448:         .stepping = 3,
  449:         .features = PENTIUM3_FEATURES,
  450:         .xlevel = 0,
  451:     },
  452:     {
  453:         .name = "athlon",
  454:         .level = 2,
  455:         .vendor1 = CPUID_VENDOR_AMD_1,
  456:         .vendor2 = CPUID_VENDOR_AMD_2,
  457:         .vendor3 = CPUID_VENDOR_AMD_3,
  458:         .family = 6,
  459:         .model = 2,
  460:         .stepping = 3,
  461:         .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
  462:         .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
  463:         .xlevel = 0x80000008,
  464:         /* XXX: put another string ? */
  465:         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
  466:     },
  467:     {
  468:         .name = "n270",
  469:         /* original is on level 10 */
  470:         .level = 5,
  471:         .family = 6,
  472:         .model = 28,
  473:         .stepping = 2,
  474:         .features = PPRO_FEATURES |
  475:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
  476:             CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
  477:             /* Some CPUs got no CPUID_SEP */
  478:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
  479:             CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
  480:         .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
  481:         .ext3_features = CPUID_EXT3_LAHF_LM,
  482:         .xlevel = 0x8000000A,
  483:         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
  484:     },
  485: };
  486: 
  487: static int cpu_x86_fill_model_id(char *str)
  488: {
  489:     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
  490:     int i;
  491: 
  492:     for (i = 0; i < 3; i++) {
  493:         host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
  494:         memcpy(str + i * 16 +  0, &eax, 4);
  495:         memcpy(str + i * 16 +  4, &ebx, 4);
  496:         memcpy(str + i * 16 +  8, &ecx, 4);
  497:         memcpy(str + i * 16 + 12, &edx, 4);
  498:     }
  499:     return 0;
  500: }
  501: 
  502: static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
  503: {
  504:     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
  505: 
  506:     x86_cpu_def->name = "host";
  507:     host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
  508:     x86_cpu_def->level = eax;
  509:     x86_cpu_def->vendor1 = ebx;
  510:     x86_cpu_def->vendor2 = edx;
  511:     x86_cpu_def->vendor3 = ecx;
  512: 
  513:     host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
  514:     x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
  515:     x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
  516:     x86_cpu_def->stepping = eax & 0x0F;
  517:     x86_cpu_def->ext_features = ecx;
  518:     x86_cpu_def->features = edx;
  519: 
  520:     host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
  521:     x86_cpu_def->xlevel = eax;
  522: 
  523:     host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
  524:     x86_cpu_def->ext2_features = edx;
  525:     x86_cpu_def->ext3_features = ecx;
  526:     cpu_x86_fill_model_id(x86_cpu_def->model_id);
  527:     x86_cpu_def->vendor_override = 0;
  528: 
  529:     /* Call Centaur's CPUID instruction. */
  530:     if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
  531:         x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
  532:         x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
  533:         host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
  534:         if (eax >= 0xC0000001) {
  535:             /* Support VIA max extended level */
  536:             x86_cpu_def->xlevel2 = eax;
  537:             host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
  538:             x86_cpu_def->ext4_features = edx;
  539:         }
  540:     }
  541: 
  542:     /*
  543:      * Every SVM feature requires emulation support in KVM - so we can't just
  544:      * read the host features here. KVM might even support SVM features not
  545:      * available on the host hardware. Just set all bits and mask out the
  546:      * unsupported ones later.
  547:      */
  548:     x86_cpu_def->svm_features = -1;
  549: 
  550:     return 0;
  551: }
  552: 
  553: static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
  554: {
  555:     int i;
  556: 
  557:     for (i = 0; i < 32; ++i)
  558:         if (1 << i & mask) {
  559:             fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
  560:                 " flag '%s' [0x%08x]\n",
  561:                 f->cpuid >> 16, f->cpuid & 0xffff,
  562:                 f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
  563:             break;
  564:         }
  565:     return 0;
  566: }
  567: 
  568: /* best effort attempt to inform user requested cpu flags aren't making
  569:  * their way to the guest.  Note: ft[].check_feat ideally should be
  570:  * specified via a guest_def field to suppress report of extraneous flags.
  571:  */
  572: static int check_features_against_host(x86_def_t *guest_def)
  573: {
  574:     x86_def_t host_def;
  575:     uint32_t mask;
  576:     int rv, i;
  577:     struct model_features_t ft[] = {
  578:         {&guest_def->features, &host_def.features,
  579:             ~0, feature_name, 0x00000000},
  580:         {&guest_def->ext_features, &host_def.ext_features,
  581:             ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
  582:         {&guest_def->ext2_features, &host_def.ext2_features,
  583:             ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
  584:         {&guest_def->ext3_features, &host_def.ext3_features,
  585:             ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
  586: 
  587:     cpu_x86_fill_host(&host_def);
  588:     for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
  589:         for (mask = 1; mask; mask <<= 1)
  590:             if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
  591:                 !(*ft[i].host_feat & mask)) {
  592:                     unavailable_host_feature(&ft[i], mask);
  593:                     rv = 1;
  594:                 }
  595:     return rv;
  596: }
  597: 
  598: static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
  599: {
  600:     unsigned int i;
  601:     x86_def_t *def;
  602: 
  603:     char *s = g_strdup(cpu_model);
  604:     char *featurestr, *name = strtok(s, ",");
  605:     /* Features to be added*/
  606:     uint32_t plus_features = 0, plus_ext_features = 0;
  607:     uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
  608:     uint32_t plus_kvm_features = 0, plus_svm_features = 0;
  609:     /* Features to be removed */
  610:     uint32_t minus_features = 0, minus_ext_features = 0;
  611:     uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
  612:     uint32_t minus_kvm_features = 0, minus_svm_features = 0;
  613:     uint32_t numvalue;
  614: 
  615:     for (def = x86_defs; def; def = def->next)
  616:         if (name && !strcmp(name, def->name))
  617:             break;
  618:     if (kvm_enabled() && name && strcmp(name, "host") == 0) {
  619:         cpu_x86_fill_host(x86_cpu_def);
  620:     } else if (!def) {
  621:         goto error;
  622:     } else {
  623:         memcpy(x86_cpu_def, def, sizeof(*def));
  624:     }
  625: 
  626:     plus_kvm_features = ~0; /* not supported bits will be filtered out later */
  627: 
  628:     add_flagname_to_bitmaps("hypervisor", &plus_features,
  629:         &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
  630:         &plus_kvm_features, &plus_svm_features);
  631: 
  632:     featurestr = strtok(NULL, ",");
  633: 
  634:     while (featurestr) {
  635:         char *val;
  636:         if (featurestr[0] == '+') {
  637:             add_flagname_to_bitmaps(featurestr + 1, &plus_features,
  638:                             &plus_ext_features, &plus_ext2_features,
  639:                             &plus_ext3_features, &plus_kvm_features,
  640:                             &plus_svm_features);
  641:         } else if (featurestr[0] == '-') {
  642:             add_flagname_to_bitmaps(featurestr + 1, &minus_features,
  643:                             &minus_ext_features, &minus_ext2_features,
  644:                             &minus_ext3_features, &minus_kvm_features,
  645:                             &minus_svm_features);
  646:         } else if ((val = strchr(featurestr, '='))) {
  647:             *val = 0; val++;
  648:             if (!strcmp(featurestr, "family")) {
  649:                 char *err;
  650:                 numvalue = strtoul(val, &err, 0);
  651:                 if (!*val || *err) {
  652:                     fprintf(stderr, "bad numerical value %s\n", val);
  653:                     goto error;
  654:                 }
  655:                 x86_cpu_def->family = numvalue;
  656:             } else if (!strcmp(featurestr, "model")) {
  657:                 char *err;
  658:                 numvalue = strtoul(val, &err, 0);
  659:                 if (!*val || *err || numvalue > 0xff) {
  660:                     fprintf(stderr, "bad numerical value %s\n", val);
  661:                     goto error;
  662:                 }
  663:                 x86_cpu_def->model = numvalue;
  664:             } else if (!strcmp(featurestr, "stepping")) {
  665:                 char *err;
  666:                 numvalue = strtoul(val, &err, 0);
  667:                 if (!*val || *err || numvalue > 0xf) {
  668:                     fprintf(stderr, "bad numerical value %s\n", val);
  669:                     goto error;
  670:                 }
  671:                 x86_cpu_def->stepping = numvalue ;
  672:             } else if (!strcmp(featurestr, "level")) {
  673:                 char *err;
  674:                 numvalue = strtoul(val, &err, 0);
  675:                 if (!*val || *err) {
  676:                     fprintf(stderr, "bad numerical value %s\n", val);
  677:                     goto error;
  678:                 }
  679:                 x86_cpu_def->level = numvalue;
  680:             } else if (!strcmp(featurestr, "xlevel")) {
  681:                 char *err;
  682:                 numvalue = strtoul(val, &err, 0);
  683:                 if (!*val || *err) {
  684:                     fprintf(stderr, "bad numerical value %s\n", val);
  685:                     goto error;
  686:                 }
  687:                 if (numvalue < 0x80000000) {
  688:                     numvalue += 0x80000000;
  689:                 }
  690:                 x86_cpu_def->xlevel = numvalue;
  691:             } else if (!strcmp(featurestr, "vendor")) {
  692:                 if (strlen(val) != 12) {
  693:                     fprintf(stderr, "vendor string must be 12 chars long\n");
  694:                     goto error;
  695:                 }
  696:                 x86_cpu_def->vendor1 = 0;
  697:                 x86_cpu_def->vendor2 = 0;
  698:                 x86_cpu_def->vendor3 = 0;
  699:                 for(i = 0; i < 4; i++) {
  700:                     x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
  701:                     x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
  702:                     x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
  703:                 }
  704:                 x86_cpu_def->vendor_override = 1;
  705:             } else if (!strcmp(featurestr, "model_id")) {
  706:                 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
  707:                         val);
  708:             } else if (!strcmp(featurestr, "tsc_freq")) {
  709:                 int64_t tsc_freq;
  710:                 char *err;
  711: 
  712:                 tsc_freq = strtosz_suffix_unit(val, &err,
  713:                                                STRTOSZ_DEFSUFFIX_B, 1000);
  714:                 if (tsc_freq < 0 || *err) {
  715:                     fprintf(stderr, "bad numerical value %s\n", val);
  716:                     goto error;
  717:                 }
  718:                 x86_cpu_def->tsc_khz = tsc_freq / 1000;
  719:             } else {
  720:                 fprintf(stderr, "unrecognized feature %s\n", featurestr);
  721:                 goto error;
  722:             }
  723:         } else if (!strcmp(featurestr, "check")) {
  724:             check_cpuid = 1;
  725:         } else if (!strcmp(featurestr, "enforce")) {
  726:             check_cpuid = enforce_cpuid = 1;
  727:         } else {
  728:             fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
  729:             goto error;
  730:         }
  731:         featurestr = strtok(NULL, ",");
  732:     }
  733:     x86_cpu_def->features |= plus_features;
  734:     x86_cpu_def->ext_features |= plus_ext_features;
  735:     x86_cpu_def->ext2_features |= plus_ext2_features;
  736:     x86_cpu_def->ext3_features |= plus_ext3_features;
  737:     x86_cpu_def->kvm_features |= plus_kvm_features;
  738:     x86_cpu_def->svm_features |= plus_svm_features;
  739:     x86_cpu_def->features &= ~minus_features;
  740:     x86_cpu_def->ext_features &= ~minus_ext_features;
  741:     x86_cpu_def->ext2_features &= ~minus_ext2_features;
  742:     x86_cpu_def->ext3_features &= ~minus_ext3_features;
  743:     x86_cpu_def->kvm_features &= ~minus_kvm_features;
  744:     x86_cpu_def->svm_features &= ~minus_svm_features;
  745:     if (check_cpuid) {
  746:         if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
  747:             goto error;
  748:     }
  749:     g_free(s);
  750:     return 0;
  751: 
  752: error:
  753:     g_free(s);
  754:     return -1;
  755: }
  756: 
  757: /* generate a composite string into buf of all cpuid names in featureset
  758:  * selected by fbits.  indicate truncation at bufsize in the event of overflow.
  759:  * if flags, suppress names undefined in featureset.
  760:  */
  761: static void listflags(char *buf, int bufsize, uint32_t fbits,
  762:     const char **featureset, uint32_t flags)
  763: {
  764:     const char **p = &featureset[31];
  765:     char *q, *b, bit;
  766:     int nc;
  767: 
  768:     b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
  769:     *buf = '\0';
  770:     for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
  771:         if (fbits & 1 << bit && (*p || !flags)) {
  772:             if (*p)
  773:                 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
  774:             else
  775:                 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
  776:             if (bufsize <= nc) {
  777:                 if (b) {
  778:                     memcpy(b, "...", sizeof("..."));
  779:                 }
  780:                 return;
  781:             }
  782:             q += nc;
  783:             bufsize -= nc;
  784:         }
  785: }
  786: 
  787: /* generate CPU information:
  788:  * -?        list model names
  789:  * -?model   list model names/IDs
  790:  * -?dump    output all model (x86_def_t) data
  791:  * -?cpuid   list all recognized cpuid flag names
  792:  */
  793: void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
  794: {
  795:     unsigned char model = !strcmp("?model", optarg);
  796:     unsigned char dump = !strcmp("?dump", optarg);
  797:     unsigned char cpuid = !strcmp("?cpuid", optarg);
  798:     x86_def_t *def;
  799:     char buf[256];
  800: 
  801:     if (cpuid) {
  802:         (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
  803:         listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
  804:         (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
  805:         listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
  806:         (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
  807:         listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
  808:         (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
  809:         listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
  810:         (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
  811:         return;
  812:     }
  813:     for (def = x86_defs; def; def = def->next) {
  814:         snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
  815:         if (model || dump) {
  816:             (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
  817:         } else {
  818:             (*cpu_fprintf)(f, "x86 %16s\n", buf);
  819:         }
  820:         if (dump) {
  821:             memcpy(buf, &def->vendor1, sizeof (def->vendor1));
  822:             memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
  823:             memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
  824:             buf[12] = '\0';
  825:             (*cpu_fprintf)(f,
  826:                 "  family %d model %d stepping %d level %d xlevel 0x%x"
  827:                 " vendor \"%s\"\n",
  828:                 def->family, def->model, def->stepping, def->level,
  829:                 def->xlevel, buf);
  830:             listflags(buf, sizeof (buf), def->features, feature_name, 0);
  831:             (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
  832:                 buf);
  833:             listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
  834:                 0);
  835:             (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
  836:                 buf);
  837:             listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
  838:                 0);
  839:             (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
  840:                 def->ext2_features, buf);
  841:             listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
  842:                 0);
  843:             (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
  844:                 def->ext3_features, buf);
  845:             (*cpu_fprintf)(f, "\n");
  846:         }
  847:     }
  848:     if (kvm_enabled()) {
  849:         (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
  850:     }
  851: }
  852: 
  853: int cpu_x86_register (CPUX86State *env, const char *cpu_model)
  854: {
  855:     x86_def_t def1, *def = &def1;
  856: 
  857:     memset(def, 0, sizeof(*def));
  858: 
  859:     if (cpu_x86_find_by_name(def, cpu_model) < 0)
  860:         return -1;
  861:     if (def->vendor1) {
  862:         env->cpuid_vendor1 = def->vendor1;
  863:         env->cpuid_vendor2 = def->vendor2;
  864:         env->cpuid_vendor3 = def->vendor3;
  865:     } else {
  866:         env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
  867:         env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
  868:         env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
  869:     }
  870:     env->cpuid_vendor_override = def->vendor_override;
  871:     env->cpuid_level = def->level;
  872:     if (def->family > 0x0f)
  873:         env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
  874:     else
  875:         env->cpuid_version = def->family << 8;
  876:     env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
  877:     env->cpuid_version |= def->stepping;
  878:     env->cpuid_features = def->features;
  879:     env->cpuid_ext_features = def->ext_features;
  880:     env->cpuid_ext2_features = def->ext2_features;
  881:     env->cpuid_ext3_features = def->ext3_features;
  882:     env->cpuid_xlevel = def->xlevel;
  883:     env->cpuid_kvm_features = def->kvm_features;
  884:     env->cpuid_svm_features = def->svm_features;
  885:     env->cpuid_ext4_features = def->ext4_features;
  886:     env->cpuid_xlevel2 = def->xlevel2;
  887:     env->tsc_khz = def->tsc_khz;
  888:     if (!kvm_enabled()) {
  889:         env->cpuid_features &= TCG_FEATURES;
  890:         env->cpuid_ext_features &= TCG_EXT_FEATURES;
  891:         env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
  892: #ifdef TARGET_X86_64
  893:             | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
  894: #endif
  895:             );
  896:         env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
  897:         env->cpuid_svm_features &= TCG_SVM_FEATURES;
  898:     }
  899:     {
  900:         const char *model_id = def->model_id;
  901:         int c, len, i;
  902:         if (!model_id)
  903:             model_id = "";
  904:         len = strlen(model_id);
  905:         for(i = 0; i < 48; i++) {
  906:             if (i >= len)
  907:                 c = '\0';
  908:             else
  909:                 c = (uint8_t)model_id[i];
  910:             env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
  911:         }
  912:     }
  913:     return 0;
  914: }
  915: 
  916: #if !defined(CONFIG_USER_ONLY)
  917: /* copy vendor id string to 32 bit register, nul pad as needed
  918:  */
  919: static void cpyid(const char *s, uint32_t *id)
  920: {
  921:     char *d = (char *)id;
  922:     char i;
  923: 
  924:     for (i = sizeof (*id); i--; )
  925:         *d++ = *s ? *s++ : '\0';
  926: }
  927: 
  928: /* interpret radix and convert from string to arbitrary scalar,
  929:  * otherwise flag failure
  930:  */
  931: #define setscalar(pval, str, perr)                      \
  932: {                                                       \
  933:     char *pend;                                         \
  934:     unsigned long ul;                                   \
  935:                                                         \
  936:     ul = strtoul(str, &pend, 0);                        \
  937:     *str && !*pend ? (*pval = ul) : (*perr = 1);        \
  938: }
  939: 
  940: /* map cpuid options to feature bits, otherwise return failure
  941:  * (option tags in *str are delimited by whitespace)
  942:  */
  943: static void setfeatures(uint32_t *pval, const char *str,
  944:     const char **featureset, int *perr)
  945: {
  946:     const char *p, *q;
  947: 
  948:     for (q = p = str; *p || *q; q = p) {
  949:         while (iswhite(*p))
  950:             q = ++p;
  951:         while (*p && !iswhite(*p))
  952:             ++p;
  953:         if (!*q && !*p)
  954:             return;
  955:         if (!lookup_feature(pval, q, p, featureset)) {
  956:             fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
  957:                 (int)(p - q), q);
  958:             *perr = 1;
  959:             return;
  960:         }
  961:     }
  962: }
  963: 
  964: /* map config file options to x86_def_t form
  965:  */
  966: static int cpudef_setfield(const char *name, const char *str, void *opaque)
  967: {
  968:     x86_def_t *def = opaque;
  969:     int err = 0;
  970: 
  971:     if (!strcmp(name, "name")) {
  972:         g_free((void *)def->name);
  973:         def->name = g_strdup(str);
  974:     } else if (!strcmp(name, "model_id")) {
  975:         strncpy(def->model_id, str, sizeof (def->model_id));
  976:     } else if (!strcmp(name, "level")) {
  977:         setscalar(&def->level, str, &err)
  978:     } else if (!strcmp(name, "vendor")) {
  979:         cpyid(&str[0], &def->vendor1);
  980:         cpyid(&str[4], &def->vendor2);
  981:         cpyid(&str[8], &def->vendor3);
  982:     } else if (!strcmp(name, "family")) {
  983:         setscalar(&def->family, str, &err)
  984:     } else if (!strcmp(name, "model")) {
  985:         setscalar(&def->model, str, &err)
  986:     } else if (!strcmp(name, "stepping")) {
  987:         setscalar(&def->stepping, str, &err)
  988:     } else if (!strcmp(name, "feature_edx")) {
  989:         setfeatures(&def->features, str, feature_name, &err);
  990:     } else if (!strcmp(name, "feature_ecx")) {
  991:         setfeatures(&def->ext_features, str, ext_feature_name, &err);
  992:     } else if (!strcmp(name, "extfeature_edx")) {
  993:         setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
  994:     } else if (!strcmp(name, "extfeature_ecx")) {
  995:         setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
  996:     } else if (!strcmp(name, "xlevel")) {
  997:         setscalar(&def->xlevel, str, &err)
  998:     } else {
  999:         fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
 1000:         return (1);
 1001:     }
 1002:     if (err) {
 1003:         fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
 1004:         return (1);
 1005:     }
 1006:     return (0);
 1007: }
 1008: 
 1009: /* register config file entry as x86_def_t
 1010:  */
 1011: static int cpudef_register(QemuOpts *opts, void *opaque)
 1012: {
 1013:     x86_def_t *def = g_malloc0(sizeof (x86_def_t));
 1014: 
 1015:     qemu_opt_foreach(opts, cpudef_setfield, def, 1);
 1016:     def->next = x86_defs;
 1017:     x86_defs = def;
 1018:     return (0);
 1019: }
 1020: 
 1021: void cpu_clear_apic_feature(CPUX86State *env)
 1022: {
 1023:     env->cpuid_features &= ~CPUID_APIC;
 1024: }
 1025: 
 1026: #endif /* !CONFIG_USER_ONLY */
 1027: 
 1028: /* register "cpudef" models defined in configuration file.  Here we first
 1029:  * preload any built-in definitions
 1030:  */
 1031: void x86_cpudef_setup(void)
 1032: {
 1033:     int i;
 1034: 
 1035:     for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
 1036:         builtin_x86_defs[i].next = x86_defs;
 1037:         builtin_x86_defs[i].flags = 1;
 1038:         x86_defs = &builtin_x86_defs[i];
 1039:     }
 1040: #if !defined(CONFIG_USER_ONLY)
 1041:     qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
 1042: #endif
 1043: }
 1044: 
 1045: static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
 1046:                              uint32_t *ecx, uint32_t *edx)
 1047: {
 1048:     *ebx = env->cpuid_vendor1;
 1049:     *edx = env->cpuid_vendor2;
 1050:     *ecx = env->cpuid_vendor3;
 1051: 
 1052:     /* sysenter isn't supported on compatibility mode on AMD, syscall
 1053:      * isn't supported in compatibility mode on Intel.
 1054:      * Normally we advertise the actual cpu vendor, but you can override
 1055:      * this if you want to use KVM's sysenter/syscall emulation
 1056:      * in compatibility mode and when doing cross vendor migration
 1057:      */
 1058:     if (kvm_enabled() && ! env->cpuid_vendor_override) {
 1059:         host_cpuid(0, 0, NULL, ebx, ecx, edx);
 1060:     }
 1061: }
 1062: 
 1063: void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
 1064:                    uint32_t *eax, uint32_t *ebx,
 1065:                    uint32_t *ecx, uint32_t *edx)
 1066: {
 1067:     /* test if maximum index reached */
 1068:     if (index & 0x80000000) {
 1069:         if (index > env->cpuid_xlevel) {
 1070:             if (env->cpuid_xlevel2 > 0) {
 1071:                 /* Handle the Centaur's CPUID instruction. */
 1072:                 if (index > env->cpuid_xlevel2) {
 1073:                     index = env->cpuid_xlevel2;
 1074:                 } else if (index < 0xC0000000) {
 1075:                     index = env->cpuid_xlevel;
 1076:                 }
 1077:             } else {
 1078:                 index =  env->cpuid_xlevel;
 1079:             }
 1080:         }
 1081:     } else {
 1082:         if (index > env->cpuid_level)
 1083:             index = env->cpuid_level;
 1084:     }
 1085: 
 1086:     switch(index) {
 1087:     case 0:
 1088:         *eax = env->cpuid_level;
 1089:         get_cpuid_vendor(env, ebx, ecx, edx);
 1090:         break;
 1091:     case 1:
 1092:         *eax = env->cpuid_version;
 1093:         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
 1094:         *ecx = env->cpuid_ext_features;
 1095:         *edx = env->cpuid_features;
 1096:         if (env->nr_cores * env->nr_threads > 1) {
 1097:             *ebx |= (env->nr_cores * env->nr_threads) << 16;
 1098:             *edx |= 1 << 28;    /* HTT bit */
 1099:         }
 1100:         break;
 1101:     case 2:
 1102:         /* cache info: needed for Pentium Pro compatibility */
 1103:         *eax = 1;
 1104:         *ebx = 0;
 1105:         *ecx = 0;
 1106:         *edx = 0x2c307d;
 1107:         break;
 1108:     case 4:
 1109:         /* cache info: needed for Core compatibility */
 1110:         if (env->nr_cores > 1) {
 1111:             *eax = (env->nr_cores - 1) << 26;
 1112:         } else {
 1113:             *eax = 0;
 1114:         }
 1115:         switch (count) {
 1116:             case 0: /* L1 dcache info */
 1117:                 *eax |= 0x0000121;
 1118:                 *ebx = 0x1c0003f;
 1119:                 *ecx = 0x000003f;
 1120:                 *edx = 0x0000001;
 1121:                 break;
 1122:             case 1: /* L1 icache info */
 1123:                 *eax |= 0x0000122;
 1124:                 *ebx = 0x1c0003f;
 1125:                 *ecx = 0x000003f;
 1126:                 *edx = 0x0000001;
 1127:                 break;
 1128:             case 2: /* L2 cache info */
 1129:                 *eax |= 0x0000143;
 1130:                 if (env->nr_threads > 1) {
 1131:                     *eax |= (env->nr_threads - 1) << 14;
 1132:                 }
 1133:                 *ebx = 0x3c0003f;
 1134:                 *ecx = 0x0000fff;
 1135:                 *edx = 0x0000001;
 1136:                 break;
 1137:             default: /* end of info */
 1138:                 *eax = 0;
 1139:                 *ebx = 0;
 1140:                 *ecx = 0;
 1141:                 *edx = 0;
 1142:                 break;
 1143:         }
 1144:         break;
 1145:     case 5:
 1146:         /* mwait info: needed for Core compatibility */
 1147:         *eax = 0; /* Smallest monitor-line size in bytes */
 1148:         *ebx = 0; /* Largest monitor-line size in bytes */
 1149:         *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
 1150:         *edx = 0;
 1151:         break;
 1152:     case 6:
 1153:         /* Thermal and Power Leaf */
 1154:         *eax = 0;
 1155:         *ebx = 0;
 1156:         *ecx = 0;
 1157:         *edx = 0;
 1158:         break;
 1159:     case 7:
 1160:         if (kvm_enabled()) {
 1161:             KVMState *s = env->kvm_state;
 1162: 
 1163:             *eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX);
 1164:             *ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX);
 1165:             *ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX);
 1166:             *edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX);
 1167:         } else {
 1168:             *eax = 0;
 1169:             *ebx = 0;
 1170:             *ecx = 0;
 1171:             *edx = 0;
 1172:         }
 1173:         break;
 1174:     case 9:
 1175:         /* Direct Cache Access Information Leaf */
 1176:         *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
 1177:         *ebx = 0;
 1178:         *ecx = 0;
 1179:         *edx = 0;
 1180:         break;
 1181:     case 0xA:
 1182:         /* Architectural Performance Monitoring Leaf */
 1183:         *eax = 0;
 1184:         *ebx = 0;
 1185:         *ecx = 0;
 1186:         *edx = 0;
 1187:         break;
 1188:     case 0xD:
 1189:         /* Processor Extended State */
 1190:         if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
 1191:             *eax = 0;
 1192:             *ebx = 0;
 1193:             *ecx = 0;
 1194:             *edx = 0;
 1195:             break;
 1196:         }
 1197:         if (kvm_enabled()) {
 1198:             KVMState *s = env->kvm_state;
 1199: 
 1200:             *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
 1201:             *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
 1202:             *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
 1203:             *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
 1204:         } else {
 1205:             *eax = 0;
 1206:             *ebx = 0;
 1207:             *ecx = 0;
 1208:             *edx = 0;
 1209:         }
 1210:         break;
 1211:     case 0x80000000:
 1212:         *eax = env->cpuid_xlevel;
 1213:         *ebx = env->cpuid_vendor1;
 1214:         *edx = env->cpuid_vendor2;
 1215:         *ecx = env->cpuid_vendor3;
 1216:         break;
 1217:     case 0x80000001:
 1218:         *eax = env->cpuid_version;
 1219:         *ebx = 0;
 1220:         *ecx = env->cpuid_ext3_features;
 1221:         *edx = env->cpuid_ext2_features;
 1222: 
 1223:         /* The Linux kernel checks for the CMPLegacy bit and
 1224:          * discards multiple thread information if it is set.
 1225:          * So dont set it here for Intel to make Linux guests happy.
 1226:          */
 1227:         if (env->nr_cores * env->nr_threads > 1) {
 1228:             uint32_t tebx, tecx, tedx;
 1229:             get_cpuid_vendor(env, &tebx, &tecx, &tedx);
 1230:             if (tebx != CPUID_VENDOR_INTEL_1 ||
 1231:                 tedx != CPUID_VENDOR_INTEL_2 ||
 1232:                 tecx != CPUID_VENDOR_INTEL_3) {
 1233:                 *ecx |= 1 << 1;    /* CmpLegacy bit */
 1234:             }
 1235:         }
 1236:         break;
 1237:     case 0x80000002:
 1238:     case 0x80000003:
 1239:     case 0x80000004:
 1240:         *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
 1241:         *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
 1242:         *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
 1243:         *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
 1244:         break;
 1245:     case 0x80000005:
 1246:         /* cache info (L1 cache) */
 1247:         *eax = 0x01ff01ff;
 1248:         *ebx = 0x01ff01ff;
 1249:         *ecx = 0x40020140;
 1250:         *edx = 0x40020140;
 1251:         break;
 1252:     case 0x80000006:
 1253:         /* cache info (L2 cache) */
 1254:         *eax = 0;
 1255:         *ebx = 0x42004200;
 1256:         *ecx = 0x02008140;
 1257:         *edx = 0;
 1258:         break;
 1259:     case 0x80000008:
 1260:         /* virtual & phys address size in low 2 bytes. */
 1261: /* XXX: This value must match the one used in the MMU code. */
 1262:         if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
 1263:             /* 64 bit processor */
 1264: /* XXX: The physical address space is limited to 42 bits in exec.c. */
 1265:             *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
 1266:         } else {
 1267:             if (env->cpuid_features & CPUID_PSE36)
 1268:                 *eax = 0x00000024; /* 36 bits physical */
 1269:             else
 1270:                 *eax = 0x00000020; /* 32 bits physical */
 1271:         }
 1272:         *ebx = 0;
 1273:         *ecx = 0;
 1274:         *edx = 0;
 1275:         if (env->nr_cores * env->nr_threads > 1) {
 1276:             *ecx |= (env->nr_cores * env->nr_threads) - 1;
 1277:         }
 1278:         break;
 1279:     case 0x8000000A:
 1280: 	if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
 1281: 		*eax = 0x00000001; /* SVM Revision */
 1282: 		*ebx = 0x00000010; /* nr of ASIDs */
 1283: 		*ecx = 0;
 1284: 		*edx = env->cpuid_svm_features; /* optional features */
 1285: 	} else {
 1286: 		*eax = 0;
 1287: 		*ebx = 0;
 1288: 		*ecx = 0;
 1289: 		*edx = 0;
 1290: 	}
 1291:         break;
 1292:     case 0xC0000000:
 1293:         *eax = env->cpuid_xlevel2;
 1294:         *ebx = 0;
 1295:         *ecx = 0;
 1296:         *edx = 0;
 1297:         break;
 1298:     case 0xC0000001:
 1299:         /* Support for VIA CPU's CPUID instruction */
 1300:         *eax = env->cpuid_version;
 1301:         *ebx = 0;
 1302:         *ecx = 0;
 1303:         *edx = env->cpuid_ext4_features;
 1304:         break;
 1305:     case 0xC0000002:
 1306:     case 0xC0000003:
 1307:     case 0xC0000004:
 1308:         /* Reserved for the future, and now filled with zero */
 1309:         *eax = 0;
 1310:         *ebx = 0;
 1311:         *ecx = 0;
 1312:         *edx = 0;
 1313:         break;
 1314:     default:
 1315:         /* reserved values: zero */
 1316:         *eax = 0;
 1317:         *ebx = 0;
 1318:         *ecx = 0;
 1319:         *edx = 0;
 1320:         break;
 1321:     }
 1322: }

unix.superglobalmegacorp.com