Revision e00b6f80
b/target-i386/cpu.h | ||
---|---|---|
772 | 772 |
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, |
773 | 773 |
int is_write, int mmu_idx, int is_softmmu); |
774 | 774 |
void cpu_x86_set_a20(CPUX86State *env, int a20_state); |
775 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, |
|
775 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
776 | 776 |
uint32_t *eax, uint32_t *ebx, |
777 | 777 |
uint32_t *ecx, uint32_t *edx); |
778 | 778 |
|
b/target-i386/helper.c | ||
---|---|---|
1403 | 1403 |
} |
1404 | 1404 |
#endif /* !CONFIG_USER_ONLY */ |
1405 | 1405 |
|
1406 |
static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx, |
|
1406 |
static void host_cpuid(uint32_t function, uint32_t count, |
|
1407 |
uint32_t *eax, uint32_t *ebx, |
|
1407 | 1408 |
uint32_t *ecx, uint32_t *edx) |
1408 | 1409 |
{ |
1409 | 1410 |
#if defined(CONFIG_KVM) |
... | ... | |
1411 | 1412 |
|
1412 | 1413 |
#ifdef __x86_64__ |
1413 | 1414 |
asm volatile("cpuid" |
1414 |
: "=a"(vec[0]), "=b"(vec[1]),
|
|
1415 |
"=c"(vec[2]), "=d"(vec[3])
|
|
1416 |
: "0"(function) : "cc");
|
|
1415 |
: "=a"(vec[0]), "=b"(vec[1]),
|
|
1416 |
"=c"(vec[2]), "=d"(vec[3])
|
|
1417 |
: "0"(function), "c"(count) : "cc");
|
|
1417 | 1418 |
#else |
1418 | 1419 |
asm volatile("pusha \n\t" |
1419 |
"cpuid \n\t"
|
|
1420 |
"mov %%eax, 0(%1) \n\t"
|
|
1421 |
"mov %%ebx, 4(%1) \n\t"
|
|
1422 |
"mov %%ecx, 8(%1) \n\t"
|
|
1423 |
"mov %%edx, 12(%1) \n\t"
|
|
1424 |
"popa"
|
|
1425 |
: : "a"(function), "S"(vec)
|
|
1426 |
: "memory", "cc");
|
|
1420 |
"cpuid \n\t"
|
|
1421 |
"mov %%eax, 0(%1) \n\t"
|
|
1422 |
"mov %%ebx, 4(%1) \n\t"
|
|
1423 |
"mov %%ecx, 8(%1) \n\t"
|
|
1424 |
"mov %%edx, 12(%1) \n\t"
|
|
1425 |
"popa"
|
|
1426 |
: : "a"(function), "c"(count), "S"(vec)
|
|
1427 |
: "memory", "cc");
|
|
1427 | 1428 |
#endif |
1428 | 1429 |
|
1429 | 1430 |
if (eax) |
... | ... | |
1437 | 1438 |
#endif |
1438 | 1439 |
} |
1439 | 1440 |
|
1440 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, |
|
1441 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
1441 | 1442 |
uint32_t *eax, uint32_t *ebx, |
1442 | 1443 |
uint32_t *ecx, uint32_t *edx) |
1443 | 1444 |
{ |
... | ... | |
1462 | 1463 |
* actuall cpu, and say goodbye to migration between different vendors |
1463 | 1464 |
* is you use compatibility mode. */ |
1464 | 1465 |
if (kvm_enabled()) |
1465 |
host_cpuid(0, NULL, ebx, ecx, edx); |
|
1466 |
host_cpuid(0, 0, NULL, ebx, ecx, edx);
|
|
1466 | 1467 |
break; |
1467 | 1468 |
case 1: |
1468 | 1469 |
*eax = env->cpuid_version; |
... | ... | |
1483 | 1484 |
break; |
1484 | 1485 |
case 4: |
1485 | 1486 |
/* cache info: needed for Core compatibility */ |
1486 |
switch (*ecx) {
|
|
1487 |
switch (count) {
|
|
1487 | 1488 |
case 0: /* L1 dcache info */ |
1488 | 1489 |
*eax = 0x0000121; |
1489 | 1490 |
*ebx = 0x1c0003f; |
... | ... | |
1509 | 1510 |
*edx = 0; |
1510 | 1511 |
break; |
1511 | 1512 |
} |
1512 |
|
|
1513 | 1513 |
break; |
1514 | 1514 |
case 5: |
1515 | 1515 |
/* mwait info: needed for Core compatibility */ |
... | ... | |
1554 | 1554 |
if (kvm_enabled()) { |
1555 | 1555 |
uint32_t h_eax, h_edx; |
1556 | 1556 |
|
1557 |
host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);
|
|
1557 |
host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
|
|
1558 | 1558 |
|
1559 | 1559 |
/* disable CPU features that the host does not support */ |
1560 | 1560 |
|
b/target-i386/kvm.c | ||
---|---|---|
44 | 44 |
|
45 | 45 |
cpuid_i = 0; |
46 | 46 |
|
47 |
cpu_x86_cpuid(env, 0, &eax, &ebx, &ecx, &edx); |
|
47 |
cpu_x86_cpuid(env, 0, 0, &eax, &ebx, &ecx, &edx);
|
|
48 | 48 |
limit = eax; |
49 | 49 |
|
50 | 50 |
for (i = 0; i <= limit; i++) { |
51 | 51 |
struct kvm_cpuid_entry *c = &cpuid_data.entries[cpuid_i++]; |
52 | 52 |
|
53 |
cpu_x86_cpuid(env, i, &eax, &ebx, &ecx, &edx); |
|
53 |
cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
|
|
54 | 54 |
c->function = i; |
55 | 55 |
c->eax = eax; |
56 | 56 |
c->ebx = ebx; |
... | ... | |
58 | 58 |
c->edx = edx; |
59 | 59 |
} |
60 | 60 |
|
61 |
cpu_x86_cpuid(env, 0x80000000, &eax, &ebx, &ecx, &edx); |
|
61 |
cpu_x86_cpuid(env, 0x80000000, 0, &eax, &ebx, &ecx, &edx);
|
|
62 | 62 |
limit = eax; |
63 | 63 |
|
64 | 64 |
for (i = 0x80000000; i <= limit; i++) { |
65 | 65 |
struct kvm_cpuid_entry *c = &cpuid_data.entries[cpuid_i++]; |
66 | 66 |
|
67 |
cpu_x86_cpuid(env, i, &eax, &ebx, &ecx, &edx); |
|
67 |
cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
|
|
68 | 68 |
c->function = i; |
69 | 69 |
c->eax = eax; |
70 | 70 |
c->ebx = ebx; |
b/target-i386/op_helper.c | ||
---|---|---|
1913 | 1913 |
|
1914 | 1914 |
helper_svm_check_intercept_param(SVM_EXIT_CPUID, 0); |
1915 | 1915 |
|
1916 |
cpu_x86_cpuid(env, (uint32_t)EAX, &eax, &ebx, &ecx, &edx); |
|
1916 |
cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
|
|
1917 | 1917 |
EAX = eax; |
1918 | 1918 |
EBX = ebx; |
1919 | 1919 |
ECX = ecx; |
Also available in: Unified diff