Revision 2d5f20b5

b/target-i386/cpu.h
438 438
#define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
439 439

  
440 440
#define CPUID_VENDOR_AMD_1   0x68747541 /* "Auth" */
441
#define CPUID_VENDOR_AMD_2   0x69746e65 /* "enti" */ 
441
#define CPUID_VENDOR_AMD_2   0x69746e65 /* "enti" */
442 442
#define CPUID_VENDOR_AMD_3   0x444d4163 /* "cAMD" */
443 443

  
444
#define CPUID_VENDOR_VIA_1   0x746e6543 /* "Cent" */
445
#define CPUID_VENDOR_VIA_2   0x48727561 /* "aurH" */
446
#define CPUID_VENDOR_VIA_3   0x736c7561 /* "auls" */
447

  
444 448
#define CPUID_MWAIT_IBE     (1 << 1) /* Interrupts can exit capability */
445 449
#define CPUID_MWAIT_EMX     (1 << 0) /* enumeration supported */
446 450

  
......
730 734
    uint32_t cpuid_ext3_features;
731 735
    uint32_t cpuid_apic_id;
732 736
    int cpuid_vendor_override;
737
    /* Store the results of Centaur's CPUID instructions */
738
    uint32_t cpuid_xlevel2;
739
    uint32_t cpuid_ext4_features;
733 740

  
734 741
    /* MTRRs */
735 742
    uint64_t mtrr_fixed[11];
b/target-i386/cpuid.c
230 230
    char model_id[48];
231 231
    int vendor_override;
232 232
    uint32_t flags;
233
    /* Store the results of Centaur's CPUID instructions */
234
    uint32_t ext4_features;
235
    uint32_t xlevel2;
233 236
} x86_def_t;
234 237

  
235 238
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
......
522 525
    cpu_x86_fill_model_id(x86_cpu_def->model_id);
523 526
    x86_cpu_def->vendor_override = 0;
524 527

  
528
    /* Call Centaur's CPUID instruction. */
529
    if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
530
        x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
531
        x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
532
        host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
533
        if (eax >= 0xC0000001) {
534
            /* Support VIA max extended level */
535
            x86_cpu_def->xlevel2 = eax;
536
            host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
537
            x86_cpu_def->ext4_features = edx;
538
        }
539
    }
525 540

  
526 541
    /*
527 542
     * Every SVM feature requires emulation support in KVM - so we can't just
......
855 870
    env->cpuid_xlevel = def->xlevel;
856 871
    env->cpuid_kvm_features = def->kvm_features;
857 872
    env->cpuid_svm_features = def->svm_features;
873
    env->cpuid_ext4_features = def->ext4_features;
874
    env->cpuid_xlevel2 = def->xlevel2;
858 875
    if (!kvm_enabled()) {
859 876
        env->cpuid_features &= TCG_FEATURES;
860 877
        env->cpuid_ext_features &= TCG_EXT_FEATURES;
......
1035 1052
{
1036 1053
    /* test if maximum index reached */
1037 1054
    if (index & 0x80000000) {
1038
        if (index > env->cpuid_xlevel)
1039
            index = env->cpuid_level;
1055
        if (index > env->cpuid_xlevel) {
1056
            if (env->cpuid_xlevel2 > 0) {
1057
                /* Handle the Centaur's CPUID instruction. */
1058
                if (index > env->cpuid_xlevel2) {
1059
                    index = env->cpuid_xlevel2;
1060
                } else if (index < 0xC0000000) {
1061
                    index = env->cpuid_xlevel;
1062
                }
1063
            } else {
1064
                index =  env->cpuid_xlevel;
1065
            }
1066
        }
1040 1067
    } else {
1041 1068
        if (index > env->cpuid_level)
1042 1069
            index = env->cpuid_level;
......
1231 1258
		*edx = 0;
1232 1259
	}
1233 1260
        break;
1261
    case 0xC0000000:
1262
        *eax = env->cpuid_xlevel2;
1263
        *ebx = 0;
1264
        *ecx = 0;
1265
        *edx = 0;
1266
        break;
1267
    case 0xC0000001:
1268
        /* Support for VIA CPU's CPUID instruction */
1269
        *eax = env->cpuid_version;
1270
        *ebx = 0;
1271
        *ecx = 0;
1272
        *edx = env->cpuid_ext4_features;
1273
        break;
1274
    case 0xC0000002:
1275
    case 0xC0000003:
1276
    case 0xC0000004:
1277
        /* Reserved for the future, and now filled with zero */
1278
        *eax = 0;
1279
        *ebx = 0;
1280
        *ecx = 0;
1281
        *edx = 0;
1282
        break;
1234 1283
    default:
1235 1284
        /* reserved values: zero */
1236 1285
        *eax = 0;
b/target-i386/kvm.c
482 482
        cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
483 483
    }
484 484

  
485
    /* Call Centaur's CPUID instructions they are supported. */
486
    if (env->cpuid_xlevel2 > 0) {
487
        env->cpuid_ext4_features &=
488
            kvm_arch_get_supported_cpuid(env, 0xC0000001, 0, R_EDX);
489
        cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused);
490

  
491
        for (i = 0xC0000000; i <= limit; i++) {
492
            c = &cpuid_data.entries[cpuid_i++];
493

  
494
            c->function = i;
495
            c->flags = 0;
496
            cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
497
        }
498
    }
499

  
485 500
    cpuid_data.cpuid.nent = cpuid_i;
486 501

  
487 502
#ifdef KVM_CAP_MCE

Also available in: Unified diff