VirtualBox

Ignore:
Timestamp:
Mar 4, 2011 4:21:09 PM (14 years ago)
Author:
vboxsync
Message:

rem: Synced up to v0.11.1 (35bfc7324e2e6946c4113ada5db30553a1a7c40b) from git://git.savannah.nongnu.org/qemu.git.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/target-i386/helper.c

    r36171 r36175  
    1515 *
    1616 * You should have received a copy of the GNU Lesser General Public
    17  * License along with this library; if not, write to the Free Software
    18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    1918 */
    2019
     
    3534#include <inttypes.h>
    3635#include <signal.h>
    37 #include <assert.h>
    3836#endif /* !VBOX */
    3937
     
    4644
    4745#ifndef VBOX
    48 static void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
     46/* feature flags taken from "Intel Processor Identification and the CPUID
     47 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
     48 * about feature names, the Linux name is used. */
     49static const char *feature_name[] = {
     50    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
     51    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
     52    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
     53    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
     54};
     55static const char *ext_feature_name[] = {
     56    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
     57    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
     58    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
     59    NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",
     60};
     61static const char *ext2_feature_name[] = {
     62    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
     63    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
     64    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
     65    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
     66};
     67static const char *ext3_feature_name[] = {
     68    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
     69    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
     70    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     71    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     72};
     73
     74static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
    4975                                    uint32_t *ext_features,
    5076                                    uint32_t *ext2_features,
     
    5278{
    5379    int i;
    54     /* feature flags taken from "Intel Processor Identification and the CPUID
    55      * Instruction" and AMD's "CPUID Specification". In cases of disagreement
    56      * about feature names, the Linux name is used. */
    57     static const char *feature_name[] = {
    58         "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
    59         "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
    60         "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
    61         "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
    62     };
    63     static const char *ext_feature_name[] = {
    64        "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
    65        "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
    66        NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
    67        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    68     };
    69     static const char *ext2_feature_name[] = {
    70        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
    71        "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
    72        "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
    73        "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
    74     };
    75     static const char *ext3_feature_name[] = {
    76        "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
    77        "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
    78        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    79        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    80     };
     80    int found = 0;
    8181
    8282    for ( i = 0 ; i < 32 ; i++ )
    8383        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
    8484            *features |= 1 << i;
    85             return;
     85            found = 1;
    8686        }
    8787    for ( i = 0 ; i < 32 ; i++ )
    8888        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
    8989            *ext_features |= 1 << i;
    90             return;
     90            found = 1;
    9191        }
    9292    for ( i = 0 ; i < 32 ; i++ )
    9393        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
    9494            *ext2_features |= 1 << i;
    95             return;
     95            found = 1;
    9696        }
    9797    for ( i = 0 ; i < 32 ; i++ )
    9898        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
    9999            *ext3_features |= 1 << i;
    100             return;
    101         }
    102     fprintf(stderr, "CPU feature %s not found\n", flagname);
     100            found = 1;
     101        }
     102    if (!found) {
     103        fprintf(stderr, "CPU feature %s not found\n", flagname);
     104    }
    103105}
    104106#endif /* !VBOX */
     
    114116    uint32_t xlevel;
    115117    char model_id[48];
     118    int vendor_override;
    116119} x86_def_t;
    117120
     
    146149        .ext_features = CPUID_EXT_SSE3,
    147150        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
    148             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
    149             CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
     151            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
    150152        .ext3_features = CPUID_EXT3_SVM,
    151153        .xlevel = 0x8000000A,
     
    271273        .name = "athlon",
    272274        .level = 2,
    273         .vendor1 = 0x68747541, /* "Auth" */
    274         .vendor2 = 0x69746e65, /* "enti" */
    275         .vendor3 = 0x444d4163, /* "cAMD" */
     275        .vendor1 = CPUID_VENDOR_AMD_1,
     276        .vendor2 = CPUID_VENDOR_AMD_2,
     277        .vendor3 = CPUID_VENDOR_AMD_3,
    276278        .family = 6,
    277279        .model = 2,
     
    306308};
    307309
     310static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
     311                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
     312
     313static int cpu_x86_fill_model_id(char *str)
     314{
     315    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
     316    int i;
     317
     318    for (i = 0; i < 3; i++) {
     319        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
     320        memcpy(str + i * 16 +  0, &eax, 4);
     321        memcpy(str + i * 16 +  4, &ebx, 4);
     322        memcpy(str + i * 16 +  8, &ecx, 4);
     323        memcpy(str + i * 16 + 12, &edx, 4);
     324    }
     325    return 0;
     326}
     327
     328static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
     329{
     330    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
     331
     332    x86_cpu_def->name = "host";
     333    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
     334    x86_cpu_def->level = eax;
     335    x86_cpu_def->vendor1 = ebx;
     336    x86_cpu_def->vendor2 = edx;
     337    x86_cpu_def->vendor3 = ecx;
     338
     339    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
     340    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
     341    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
     342    x86_cpu_def->stepping = eax & 0x0F;
     343    x86_cpu_def->ext_features = ecx;
     344    x86_cpu_def->features = edx;
     345
     346    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
     347    x86_cpu_def->xlevel = eax;
     348
     349    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
     350    x86_cpu_def->ext2_features = edx;
     351    x86_cpu_def->ext3_features = ecx;
     352    cpu_x86_fill_model_id(x86_cpu_def->model_id);
     353    x86_cpu_def->vendor_override = 0;
     354
     355    return 0;
     356}
     357
    308358static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
    309359{
     
    324374        }
    325375    }
    326     if (!def)
     376    if (kvm_enabled() && strcmp(name, "host") == 0) {
     377        cpu_x86_fill_host(x86_cpu_def);
     378    } else if (!def) {
    327379        goto error;
    328     memcpy(x86_cpu_def, def, sizeof(*def));
     380    } else {
     381        memcpy(x86_cpu_def, def, sizeof(*def));
     382    }
     383
     384    add_flagname_to_bitmaps("hypervisor", &plus_features,
     385        &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
    329386
    330387    featurestr = strtok(NULL, ",");
     
    375432                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
    376433                }
     434                x86_cpu_def->vendor_override = 1;
    377435            } else if (!strcmp(featurestr, "model_id")) {
    378436                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
     
    429487        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
    430488    }
     489    env->cpuid_vendor_override = def->vendor_override;
    431490    env->cpuid_level = def->level;
    432491    if (def->family > 0x0f)
     
    495554
    496555    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
    497                            DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK);
     556                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
     557                           DESC_R_MASK | DESC_A_MASK);
    498558    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
    499                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
     559                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
     560                           DESC_A_MASK);
    500561    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
    501                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
     562                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
     563                           DESC_A_MASK);
    502564    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
    503                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
     565                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
     566                           DESC_A_MASK);
    504567    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
    505                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
     568                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
     569                           DESC_A_MASK);
    506570    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
    507                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
     571                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
     572                           DESC_A_MASK);
    508573
    509574    env->eip = 0xfff0;
     
    595660    "SARQ",
    596661};
     662
     663static void
     664cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
     665                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
     666                       const char *name, struct SegmentCache *sc)
     667{
     668#ifdef TARGET_X86_64
     669    if (env->hflags & HF_CS64_MASK) {
     670        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
     671                    sc->selector, sc->base, sc->limit, sc->flags);
     672    } else
     673#endif
     674    {
     675        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
     676                    (uint32_t)sc->base, sc->limit, sc->flags);
     677    }
     678
     679    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
     680        goto done;
     681
     682    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
     683    if (sc->flags & DESC_S_MASK) {
     684        if (sc->flags & DESC_CS_MASK) {
     685            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
     686                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
     687            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
     688                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
     689        } else {
     690            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
     691            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
     692                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
     693        }
     694        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
     695    } else {
     696        static const char *sys_type_name[2][16] = {
     697            { /* 32 bit mode */
     698                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
     699                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
     700                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
     701                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
     702            },
     703            { /* 64 bit mode */
     704                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
     705                "Reserved", "Reserved", "Reserved", "Reserved",
     706                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
     707                "Reserved", "IntGate64", "TrapGate64"
     708            }
     709        };
     710        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
     711                                    [(sc->flags & DESC_TYPE_MASK)
     712                                     >> DESC_TYPE_SHIFT]);
     713    }
     714done:
     715    cpu_fprintf(f, "\n");
     716}
    597717
    598718void cpu_dump_state(CPUState *env, FILE *f,
     
    674794    }
    675795
     796    for(i = 0; i < 6; i++) {
     797        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
     798                               &env->segs[i]);
     799    }
     800    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
     801    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
     802
    676803#ifdef TARGET_X86_64
    677804    if (env->hflags & HF_LMA_MASK) {
    678         for(i = 0; i < 6; i++) {
    679             SegmentCache *sc = &env->segs[i];
    680             cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
    681                         seg_name[i],
    682                         sc->selector,
    683                         sc->base,
    684                         sc->limit,
    685                         sc->flags);
    686         }
    687         cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
    688                     env->ldt.selector,
    689                     env->ldt.base,
    690                     env->ldt.limit,
    691                     env->ldt.flags);
    692         cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
    693                     env->tr.selector,
    694                     env->tr.base,
    695                     env->tr.limit,
    696                     env->tr.flags);
    697805        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
    698806                    env->gdt.base, env->gdt.limit);
     
    711819#endif
    712820    {
    713         for(i = 0; i < 6; i++) {
    714             SegmentCache *sc = &env->segs[i];
    715             cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
    716                         seg_name[i],
    717                         sc->selector,
    718                         (uint32_t)sc->base,
    719                         sc->limit,
    720                         sc->flags);
    721         }
    722         cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
    723                     env->ldt.selector,
    724                     (uint32_t)env->ldt.base,
    725                     env->ldt.limit,
    726                     env->ldt.flags);
    727         cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
    728                     env->tr.selector,
    729                     (uint32_t)env->tr.base,
    730                     env->tr.limit,
    731                     env->tr.flags);
    732821        cpu_fprintf(f, "GDT=     %08x %08x\n",
    733822                    (uint32_t)env->gdt.base, env->gdt.limit);
     
    9391028/* XXX: This value should match the one returned by CPUID
    9401029 * and in exec.c */
    941 #if defined(USE_KQEMU)
     1030#if defined(CONFIG_KQEMU)
    9421031#define PHYS_ADDR_MASK 0xfffff000LL
    9431032#else
     
    14371526        prev_debug_excp_handler(env);
    14381527}
     1528
     1529
     1530#ifndef VBOX
     1531/* This should come from sysemu.h - if we could include it here... */
     1532void qemu_system_reset_request(void);
     1533
     1534void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
     1535                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
     1536{
     1537    uint64_t mcg_cap = cenv->mcg_cap;
     1538    unsigned bank_num = mcg_cap & 0xff;
     1539    uint64_t *banks = cenv->mce_banks;
     1540
     1541    if (bank >= bank_num || !(status & MCI_STATUS_VAL))
     1542        return;
     1543
     1544    /*
     1545     * if MSR_MCG_CTL is not all 1s, the uncorrected error
     1546     * reporting is disabled
     1547     */
     1548    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
     1549        cenv->mcg_ctl != ~(uint64_t)0)
     1550        return;
     1551    banks += 4 * bank;
     1552    /*
     1553     * if MSR_MCi_CTL is not all 1s, the uncorrected error
     1554     * reporting is disabled for the bank
     1555     */
     1556    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
     1557        return;
     1558    if (status & MCI_STATUS_UC) {
     1559        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
     1560            !(cenv->cr[4] & CR4_MCE_MASK)) {
     1561            fprintf(stderr, "injects mce exception while previous "
     1562                    "one is in progress!\n");
     1563            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
     1564            qemu_system_reset_request();
     1565            return;
     1566        }
     1567        if (banks[1] & MCI_STATUS_VAL)
     1568            status |= MCI_STATUS_OVER;
     1569        banks[2] = addr;
     1570        banks[3] = misc;
     1571        cenv->mcg_status = mcg_status;
     1572        banks[1] = status;
     1573        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
     1574    } else if (!(banks[1] & MCI_STATUS_VAL)
     1575               || !(banks[1] & MCI_STATUS_UC)) {
     1576        if (banks[1] & MCI_STATUS_VAL)
     1577            status |= MCI_STATUS_OVER;
     1578        banks[2] = addr;
     1579        banks[3] = misc;
     1580        banks[1] = status;
     1581    } else
     1582        banks[1] |= MCI_STATUS_OVER;
     1583}
     1584#endif /* !VBOX */
    14391585#endif /* !CONFIG_USER_ONLY */
    14401586
    14411587#ifndef VBOX
     1588
     1589static void mce_init(CPUX86State *cenv)
     1590{
     1591    unsigned int bank, bank_num;
     1592
     1593    if (((cenv->cpuid_version >> 8)&0xf) >= 6
     1594        && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
     1595        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
     1596        cenv->mcg_ctl = ~(uint64_t)0;
     1597        bank_num = cenv->mcg_cap & 0xff;
     1598        cenv->mce_banks = qemu_mallocz(bank_num * sizeof(uint64_t) * 4);
     1599        for (bank = 0; bank < bank_num; bank++)
     1600            cenv->mce_banks[bank*4] = ~(uint64_t)0;
     1601    }
     1602}
     1603
    14421604static void host_cpuid(uint32_t function, uint32_t count,
    14431605                       uint32_t *eax, uint32_t *ebx,
     
    14991661         * actuall cpu, and say goodbye to migration between different vendors
    15001662         * is you use compatibility mode. */
    1501         if (kvm_enabled())
     1663        if (kvm_enabled() && !env->cpuid_vendor_override)
    15021664            host_cpuid(0, 0, NULL, ebx, ecx, edx);
    15031665        break;
     
    15071669        *ecx = env->cpuid_ext_features;
    15081670        *edx = env->cpuid_features;
    1509 
    1510         /* "Hypervisor present" bit required for Microsoft SVVP */
    1511         if (kvm_enabled())
    1512             *ecx |= (1 << 31);
    15131671        break;
    15141672    case 2:
     
    15831741        break;
    15841742    case 0x80000001:
    1585         *eax = env->cpuid_features;
     1743        *eax = env->cpuid_version;
    15861744        *ebx = 0;
    15871745        *ecx = env->cpuid_ext3_features;
     
    15891747
    15901748        if (kvm_enabled()) {
    1591             uint32_t h_eax, h_edx;
    1592 
    1593             host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
    1594 
    1595             /* disable CPU features that the host does not support */
    1596 
    1597             /* long mode */
    1598             if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
    1599                 *edx &= ~0x20000000;
    1600             /* syscall */
    1601             if ((h_edx & 0x00000800) == 0)
    1602                 *edx &= ~0x00000800;
    1603             /* nx */
    1604             if ((h_edx & 0x00100000) == 0)
    1605                 *edx &= ~0x00100000;
    1606 
    1607             /* disable CPU features that KVM cannot support */
    1608 
    1609             /* svm */
    1610             *ecx &= ~4UL;
    1611             /* 3dnow */
    1612             *edx &= ~0xc0000000;
     1749            /* Nested SVM not yet supported in KVM */
     1750            *ecx &= ~CPUID_EXT3_SVM;
     1751        } else {
     1752            /* AMD 3DNow! is not supported in QEMU */
     1753            *edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT);
    16131754        }
    16141755        break;
     
    16401781        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
    16411782            /* 64 bit processor */
    1642 #if defined(USE_KQEMU)
     1783#if defined(CONFIG_KQEMU)
    16431784            *eax = 0x00003020;  /* 48 bits virtual, 32 bits physical */
    16441785#else
     
    16471788#endif
    16481789        } else {
    1649 #if defined(USE_KQEMU)
     1790#if defined(CONFIG_KQEMU)
    16501791            *eax = 0x00000020;  /* 32 bits physical */
    16511792#else
     
    16751816    }
    16761817}
     1818
     1819int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
     1820                            target_ulong *base, unsigned int *limit,
     1821                            unsigned int *flags)
     1822{
     1823    SegmentCache *dt;
     1824    target_ulong ptr;
     1825    uint32_t e1, e2;
     1826    int index;
     1827
     1828    if (selector & 0x4)
     1829        dt = &env->ldt;
     1830    else
     1831        dt = &env->gdt;
     1832    index = selector & ~7;
     1833    ptr = dt->base + index;
     1834    if ((index + 7) > dt->limit
     1835        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
     1836        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
     1837        return 0;
     1838
     1839    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
     1840    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
     1841    if (e2 & DESC_G_MASK)
     1842        *limit = (*limit << 12) | 0xfff;
     1843    *flags = e2;
     1844
     1845    return 1;
     1846}
     1847
    16771848#endif /* !VBOX */
    16781849
     
    17071878        return NULL;
    17081879    }
     1880#ifndef VBOX
     1881    mce_init(env);
     1882#endif
    17091883    cpu_reset(env);
    1710 #ifdef USE_KQEMU
     1884#ifdef CONFIG_KQEMU
    17111885    kqemu_init(env);
    17121886#endif
    1713     if (kvm_enabled())
    1714         kvm_init_vcpu(env);
     1887
     1888    qemu_init_vcpu(env);
     1889
    17151890    return env;
    17161891}
     1892
     1893#ifndef VBOX
     1894#if !defined(CONFIG_USER_ONLY)
     1895void do_cpu_init(CPUState *env)
     1896{
     1897    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
     1898    cpu_reset(env);
     1899    env->interrupt_request = sipi;
     1900    apic_init_reset(env);
     1901}
     1902
     1903void do_cpu_sipi(CPUState *env)
     1904{
     1905    apic_sipi(env);
     1906}
     1907#else
     1908void do_cpu_init(CPUState *env)
     1909{
     1910}
     1911void do_cpu_sipi(CPUState *env)
     1912{
     1913}
     1914#endif
     1915#endif /* !VBOX */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette