File kvm-cpuid.patch of Package kvm
# Quick patch until proper version is upstream, but is safe.
# Signed-off-by: Alex Graf - agraf@suse
Index: kvm-61/kernel/x86.c
===================================================================
--- kvm-61.orig/kernel/x86.c
+++ kvm-61/kernel/x86.c
@@ -911,7 +911,7 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
struct kvm_cpuid *cpuid,
struct kvm_cpuid_entry __user *entries)
{
- int r, i;
+ int r, i, n = 0;
struct kvm_cpuid_entry *cpuid_entries;
r = -E2BIG;
@@ -931,8 +931,17 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
- vcpu->arch.cpuid_entries[i].index = 0;
- vcpu->arch.cpuid_entries[i].flags = 0;
+ switch(vcpu->arch.cpuid_entries[i].function) {
+ case 4:
+ vcpu->arch.cpuid_entries[i].index = n;
+ vcpu->arch.cpuid_entries[i].flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+ n++;
+ break;
+ default:
+ vcpu->arch.cpuid_entries[i].index = 0;
+ vcpu->arch.cpuid_entries[i].flags = 0;
+ break;
+ }
vcpu->arch.cpuid_entries[i].padding[0] = 0;
vcpu->arch.cpuid_entries[i].padding[1] = 0;
vcpu->arch.cpuid_entries[i].padding[2] = 0;
Index: kvm-61/qemu/qemu-kvm-x86.c
===================================================================
--- kvm-61.orig/qemu/qemu-kvm-x86.c
+++ kvm-61/qemu/qemu-kvm-x86.c
@@ -468,10 +468,11 @@ static void host_cpuid(uint32_t function
}
-static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function,
+static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function, uint32_t index,
CPUState *env)
{
env->regs[R_EAX] = function;
+ env->regs[R_ECX] = index;
qemu_kvm_cpuid_on_env(env);
e->function = function;
e->eax = env->regs[R_EAX];
@@ -522,7 +523,7 @@ int kvm_arch_qemu_init_env(CPUState *cen
#endif
int cpuid_nent = 0;
CPUState copy;
- uint32_t i, limit;
+ uint32_t i, j, limit;
int has_clocksource = 0;
#ifdef KVM_CAP_CLOCKSOURCE
has_clocksource = kvm_check_extension(kvm_context, KVM_CAP_CLOCKSOURCE);
@@ -551,15 +552,26 @@ int kvm_arch_qemu_init_env(CPUState *cen
qemu_kvm_cpuid_on_env(©);
limit = copy.regs[R_EAX];
- for (i = 0; i <= limit; ++i)
- do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, ©);
+ for (i = 0; i <= limit; ++i) {
+ switch(i) {
+ case 4:
+ for(j = 0; ; j++) {
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, j, ©);
+ if(!copy.regs[R_EAX]) break;
+ }
+ break;
+ default:
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, ©);
+ break;
+ }
+ }
copy.regs[R_EAX] = 0x80000000;
qemu_kvm_cpuid_on_env(©);
limit = copy.regs[R_EAX];
for (i = 0x80000000; i <= limit; ++i)
- do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, ©);
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, ©);
kvm_setup_cpuid(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent);
return 0;