Commit 486bd5a2f26e58d7222a0cb83f25bb4136b7406d

Authored by aliguori
1 parent e00b6f80

KVM: Fetch sub-leaf cpuid values for functions 4, 0xb, 0xd. (Amit Shah)

CPUID functions 4, 0xb and 0xd have sub-leaf values which depend on the
input value of ECX. Store these values as well.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6566 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 39 additions and 14 deletions
target-i386/kvm.c
@@ -36,10 +36,10 @@ @@ -36,10 +36,10 @@
36 int kvm_arch_init_vcpu(CPUState *env) 36 int kvm_arch_init_vcpu(CPUState *env)
37 { 37 {
38 struct { 38 struct {
39 - struct kvm_cpuid cpuid;  
40 - struct kvm_cpuid_entry entries[100]; 39 + struct kvm_cpuid2 cpuid;
  40 + struct kvm_cpuid_entry2 entries[100];
41 } __attribute__((packed)) cpuid_data; 41 } __attribute__((packed)) cpuid_data;
42 - uint32_t limit, i, cpuid_i; 42 + uint32_t limit, i, j, cpuid_i;
43 uint32_t eax, ebx, ecx, edx; 43 uint32_t eax, ebx, ecx, edx;
44 44
45 cpuid_i = 0; 45 cpuid_i = 0;
@@ -48,21 +48,46 @@ int kvm_arch_init_vcpu(CPUState *env) @@ -48,21 +48,46 @@ int kvm_arch_init_vcpu(CPUState *env)
48 limit = eax; 48 limit = eax;
49 49
50 for (i = 0; i <= limit; i++) { 50 for (i = 0; i <= limit; i++) {
51 - struct kvm_cpuid_entry *c = &cpuid_data.entries[cpuid_i++];  
52 -  
53 - cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);  
54 - c->function = i;  
55 - c->eax = eax;  
56 - c->ebx = ebx;  
57 - c->ecx = ecx;  
58 - c->edx = edx; 51 + struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
  52 +
  53 + switch (i) {
  54 + case 4:
  55 + case 0xb:
  56 + case 0xd:
  57 + for (j = 0; ; j++) {
  58 + cpu_x86_cpuid(env, i, j, &eax, &ebx, &ecx, &edx);
  59 + c->function = i;
  60 + c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
  61 + c->index = j;
  62 + c->eax = eax;
  63 + c->ebx = ebx;
  64 + c->ecx = ecx;
  65 + c->edx = edx;
  66 + c = &cpuid_data.entries[++cpuid_i];
  67 +
  68 + if (i == 4 && eax == 0)
  69 + break;
  70 + if (i == 0xb && !(ecx & 0xff00))
  71 + break;
  72 + if (i == 0xd && eax == 0)
  73 + break;
  74 + }
  75 + break;
  76 + default:
  77 + cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
  78 + c->function = i;
  79 + c->eax = eax;
  80 + c->ebx = ebx;
  81 + c->ecx = ecx;
  82 + c->edx = edx;
  83 + break;
  84 + }
59 } 85 }
60 -  
61 cpu_x86_cpuid(env, 0x80000000, 0, &eax, &ebx, &ecx, &edx); 86 cpu_x86_cpuid(env, 0x80000000, 0, &eax, &ebx, &ecx, &edx);
62 limit = eax; 87 limit = eax;
63 88
64 for (i = 0x80000000; i <= limit; i++) { 89 for (i = 0x80000000; i <= limit; i++) {
65 - struct kvm_cpuid_entry *c = &cpuid_data.entries[cpuid_i++]; 90 + struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
66 91
67 cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx); 92 cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
68 c->function = i; 93 c->function = i;
@@ -74,7 +99,7 @@ int kvm_arch_init_vcpu(CPUState *env) @@ -74,7 +99,7 @@ int kvm_arch_init_vcpu(CPUState *env)
74 99
75 cpuid_data.cpuid.nent = cpuid_i; 100 cpuid_data.cpuid.nent = cpuid_i;
76 101
77 - return kvm_vcpu_ioctl(env, KVM_SET_CPUID, &cpuid_data); 102 + return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
78 } 103 }
79 104
80 static int kvm_has_msr_star(CPUState *env) 105 static int kvm_has_msr_star(CPUState *env)