summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-17 21:05:41 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-17 21:05:41 +0000
commit3c398c0f8619acaea71a02b6fcc5f1f70459c3fb (patch)
treeecec947277974d3c1154e1fe90fffb5b0eb6eb16
parent4df8f71ee5276fb22a810bbb67db3a4288f5cad4 (diff)
downloadqemu-3c398c0f8619acaea71a02b6fcc5f1f70459c3fb.tar.gz
kvm: Fix cpuid initialization (Jan Kiszka)
Fix (more or less) spurious guest boot failures due to corrupted cpuid states. The reason was insufficient initialization of cpuid entries before passing them to the kernel. At this chance also fix improper entry pointer progression and simplify the code a bit. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7170 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-i386/kvm.c60
1 files changed, 20 insertions, 40 deletions
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 86745b1350..c46900eb51 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -40,12 +40,11 @@ int kvm_arch_init_vcpu(CPUState *env)
struct kvm_cpuid_entry2 entries[100];
} __attribute__((packed)) cpuid_data;
uint32_t limit, i, j, cpuid_i;
- uint32_t eax, ebx, ecx, edx;
+ uint32_t unused;
cpuid_i = 0;
- cpu_x86_cpuid(env, 0, 0, &eax, &ebx, &ecx, &edx);
- limit = eax;
+ cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
for (i = 0; i <= limit; i++) {
struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
@@ -55,26 +54,17 @@ int kvm_arch_init_vcpu(CPUState *env)
/* Keep reading function 2 till all the input is received */
int times;
- cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
- times = eax & 0xff;
-
c->function = i;
- c->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
- c->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
- c->eax = eax;
- c->ebx = ebx;
- c->ecx = ecx;
- c->edx = edx;
+ c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC |
+ KVM_CPUID_FLAG_STATE_READ_NEXT;
+ cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
+ times = c->eax & 0xff;
for (j = 1; j < times; ++j) {
- cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
+ c = &cpuid_data.entries[cpuid_i++];
c->function = i;
- c->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
- c->eax = eax;
- c->ebx = ebx;
- c->ecx = ecx;
- c->edx = edx;
- c = &cpuid_data.entries[++cpuid_i];
+ c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC;
+ cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
}
break;
}
@@ -82,46 +72,36 @@ int kvm_arch_init_vcpu(CPUState *env)
case 0xb:
case 0xd:
for (j = 0; ; j++) {
- cpu_x86_cpuid(env, i, j, &eax, &ebx, &ecx, &edx);
c->function = i;
c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
c->index = j;
- c->eax = eax;
- c->ebx = ebx;
- c->ecx = ecx;
- c->edx = edx;
- c = &cpuid_data.entries[++cpuid_i];
+ cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx);
- if (i == 4 && eax == 0)
+ if (i == 4 && c->eax == 0)
break;
- if (i == 0xb && !(ecx & 0xff00))
+ if (i == 0xb && !(c->ecx & 0xff00))
break;
- if (i == 0xd && eax == 0)
+ if (i == 0xd && c->eax == 0)
break;
+
+ c = &cpuid_data.entries[cpuid_i++];
}
break;
default:
- cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
c->function = i;
- c->eax = eax;
- c->ebx = ebx;
- c->ecx = ecx;
- c->edx = edx;
+ c->flags = 0;
+ cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
break;
}
}
- cpu_x86_cpuid(env, 0x80000000, 0, &eax, &ebx, &ecx, &edx);
- limit = eax;
+ cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
for (i = 0x80000000; i <= limit; i++) {
struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
- cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
c->function = i;
- c->eax = eax;
- c->ebx = ebx;
- c->ecx = ecx;
- c->edx = edx;
+ c->flags = 0;
+ cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
}
cpuid_data.cpuid.nent = cpuid_i;