From 673639c308efbf0b19346b977ad79194506c6355 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 17 Apr 2009 20:50:54 +0000 Subject: [PATCH] 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 Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7167 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/kvm.c | 60 +++++++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 4f437c2..2de8b81 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -41,12 +41,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++]; @@ -56,26 +55,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; } @@ -83,46 +73,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; -- 2.7.4