Hi,

Currently CPUID function 4 is broken. This function's values rely on the
value of ECX.
To solve the issue cleanly, there is already a new API for cpuid
settings, which is not used yet.
Using the current interface, the function 4 can be easily passed
through, by giving multiple function 4 outputs and increasing the
index-identifier on the fly. This does not break compatibility.

This fix is really important for Mac OS X, as it requires cache
information. Please also see my previous patches for Mac OS X (or rather
core duo target) compatibility.

Regards,

Alex
diff --git a/kernel/x86.c b/kernel/x86.c
index b55c177..73312e9 100644
--- a/kernel/x86.c
+++ b/kernel/x86.c
@@ -783,7 +783,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 				    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;
@@ -803,8 +803,17 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 		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;
diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c
index d86fec3..8e5d754 100644
--- a/qemu/qemu-kvm-x86.c
+++ b/qemu/qemu-kvm-x86.c
@@ -461,10 +461,11 @@ static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx,
 }
 
 
-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];
@@ -515,7 +516,7 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
 #endif
     int cpuid_nent = 0;
     CPUState copy;
-    uint32_t i, limit;
+    uint32_t i, j, limit;
 
     copy = *cenv;
 
@@ -540,16 +541,27 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
     qemu_kvm_cpuid_on_env(&copy);
     limit = copy.regs[R_EAX];
 
-    for (i = 0; i <= limit; ++i)
-	do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, &copy);
+    for (i = 0; i <= limit; ++i) {
+        switch(i) {
+            case 4:
+                for(j = 0; ; j++) {
+	            do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, j, &copy);
+                    if(!copy.regs[R_EAX]) break;
+                }
+                break;
+            default:
+	        do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, &copy);
+                break;
+        }
+    }
 
     copy.regs[R_EAX] = 0x80000000;
     qemu_kvm_cpuid_on_env(&copy);
     limit = copy.regs[R_EAX];
 
     for (i = 0x80000000; i <= limit; ++i)
-	do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, &copy);
+	do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, &copy);
 
     kvm_setup_cpuid(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent);
     return 0;
 }
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to