cpuid function 2 can have multiple values to describe cache behaviour.
Loop till we have fetched all the values.

Signed-off-by: Amit Shah <amit.s...@redhat.com>
---
 qemu/qemu-kvm-x86.c |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c
index 5264015..9a175a8 100644
--- a/qemu/qemu-kvm-x86.c
+++ b/qemu/qemu-kvm-x86.c
@@ -538,7 +538,27 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
     limit = copy.regs[R_EAX];
 
     for (i = 0; i <= limit; ++i) {
-        if (i == 4 || i == 0xb || i == 0xd) {
+        switch (i) {
+        case 2: {
+            /* Keep reading function 2 till all the input is received */
+            int times;
+
+            do_cpuid_ent(&cpuid_ent[cpuid_nent], i, 0, &copy);
+            times = cpuid_ent[cpuid_nent].eax & 0xff;
+
+            cpuid_ent[cpuid_nent].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
+            cpuid_ent[cpuid_nent].flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
+
+            for (j = 1; j < times; ++j) {
+                do_cpuid_ent(&cpuid_ent[++cpuid_nent], i, 0, &copy);
+                cpuid_ent[cpuid_nent].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
+            }
+            cpuid_nent++;
+            break;
+        }
+        case 4:
+        case 0xb:
+        case 0xd:
             for (j = 0; ; ++j) {
                 do_cpuid_ent(&cpuid_ent[cpuid_nent], i, j, &copy);
 
@@ -554,8 +574,11 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
                 if (i == 0xd && copy.regs[R_EAX] == 0)
                     break;
             }
-        } else
+            break;
+
+        default:
             do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, &copy);
+        }
     }
 
     copy.regs[R_EAX] = 0x80000000;
-- 
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to