Revision 6d9fef1a

b/target-i386/helper.c
1638 1638
#endif
1639 1639
}
1640 1640

  
1641
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1642
                             uint32_t *ecx, uint32_t *edx)
1643
{
1644
    *ebx = env->cpuid_vendor1;
1645
    *edx = env->cpuid_vendor2;
1646
    *ecx = env->cpuid_vendor3;
1647

  
1648
    /* sysenter isn't supported on compatibility mode on AMD, syscall
1649
     * isn't supported in compatibility mode on Intel.
1650
     * Normally we advertise the actual cpu vendor, but you can override
1651
     * this if you want to use KVM's sysenter/syscall emulation
1652
     * in compatibility mode and when doing cross vendor migration
1653
     */
1654
    if (kvm_enabled() && env->cpuid_vendor_override) {
1655
        host_cpuid(0, 0, NULL, ebx, ecx, edx);
1656
    }
1657
}
1658

  
1641 1659
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1642 1660
                   uint32_t *eax, uint32_t *ebx,
1643 1661
                   uint32_t *ecx, uint32_t *edx)
......
1654 1672
    switch(index) {
1655 1673
    case 0:
1656 1674
        *eax = env->cpuid_level;
1657
        *ebx = env->cpuid_vendor1;
1658
        *edx = env->cpuid_vendor2;
1659
        *ecx = env->cpuid_vendor3;
1660

  
1661
        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
1662
         * isn't supported in compatibility mode on Intel.  so advertise the
1663
         * actuall cpu, and say goodbye to migration between different vendors
1664
         * is you use compatibility mode. */
1665
        if (kvm_enabled() && !env->cpuid_vendor_override)
1666
            host_cpuid(0, 0, NULL, ebx, ecx, edx);
1675
        get_cpuid_vendor(env, ebx, ecx, edx);
1667 1676
        break;
1668 1677
    case 1:
1669 1678
        *eax = env->cpuid_version;
......
1759 1768
        *ecx = env->cpuid_ext3_features;
1760 1769
        *edx = env->cpuid_ext2_features;
1761 1770

  
1762
        if (env->nr_cores * env->nr_threads > 1 &&
1763
            env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
1764
            env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
1765
            env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
1766
            *ecx |= 1 << 1;    /* CmpLegacy bit */
1771
        /* The Linux kernel checks for the CMPLegacy bit and
1772
         * discards multiple thread information if it is set.
1773
         * So dont set it here for Intel to make Linux guests happy.
1774
         */
1775
        if (env->nr_cores * env->nr_threads > 1) {
1776
            uint32_t tebx, tecx, tedx;
1777
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1778
            if (tebx != CPUID_VENDOR_INTEL_1 ||
1779
                tedx != CPUID_VENDOR_INTEL_2 ||
1780
                tecx != CPUID_VENDOR_INTEL_3) {
1781
                *ecx |= 1 << 1;    /* CmpLegacy bit */
1782
            }
1767 1783
        }
1768 1784

  
1769 1785
        if (kvm_enabled()) {

Also available in: Unified diff