Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 3160499aacb81f6735941eb4c372d87a > files > 103

kvm-83-164.el5_5.30.src.rpm

From 650a1cb261a442ccd0b95bd11759582e18f7f429 Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Fri, 2 Oct 2009 14:15:29 -0300
Subject: [PATCH 02/10] Fetch sub-leaf cpuid values for functions 4, 0xb, 0xd.

RH-Author: Gleb Natapov <gleb@redhat.com>
Message-id: <1253608839-4319-3-git-send-email-gleb@redhat.com>
Patchwork-id: 3488
O-Subject: [PATCH 2/7] Fetch sub-leaf cpuid values for functions 4, 0xb, 0xd.
Bugzilla: 508040
RH-Acked-by: Mark McLoughlin <markmc@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>

CPUID functions 4, 0xb and 0xd have sub-leaf values which depend on the
input value of ECX. Fetch these cpuid values and pass them on to the kernel.

We also switch to the kvm_set_cpuid2() ioctl for this; kvm_set_cpuid() can't
handle the extra parameters we need to support sub-leaves.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
 qemu/qemu-kvm-x86.c |   37 ++++++++++++++++++++++++++++---------
 1 files changed, 28 insertions(+), 9 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/qemu-kvm-x86.c |   37 ++++++++++++++++++++++++++++---------
 1 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c
index 737ca87..8b3e89c 100644
--- a/qemu/qemu-kvm-x86.c
+++ b/qemu/qemu-kvm-x86.c
@@ -457,10 +457,11 @@ void kvm_arch_save_regs(CPUState *env)
     }
 }
 
-static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function,
-			 CPUState *env)
+static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function,
+                         uint32_t count, CPUState *env)
 {
     env->regs[R_EAX] = function;
+    env->regs[R_ECX] = count;
     qemu_kvm_cpuid_on_env(env);
     e->function = function;
     e->eax = env->regs[R_EAX];
@@ -502,14 +503,14 @@ static int get_para_features(kvm_context_t kvm_context)
 
 int kvm_arch_qemu_init_env(CPUState *cenv)
 {
-    struct kvm_cpuid_entry cpuid_ent[100];
+    struct kvm_cpuid_entry2 cpuid_ent[100];
 #ifdef KVM_CPUID_SIGNATURE
-    struct kvm_cpuid_entry *pv_ent;
+    struct kvm_cpuid_entry2 *pv_ent;
     uint32_t signature[3];
 #endif
     int cpuid_nent = 0;
     CPUState copy;
-    uint32_t i, limit;
+    uint32_t i, j, limit;
 
     qemu_kvm_load_lapic(cenv);
 
@@ -536,17 +537,35 @@ 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) {
+        if (i == 4 || i == 0xb || i == 0xd) {
+            for (j = 0; ; ++j) {
+                do_cpuid_ent(&cpuid_ent[cpuid_nent], i, j, &copy);
+
+                cpuid_ent[cpuid_nent].flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+                cpuid_ent[cpuid_nent].index = j;
+
+                cpuid_nent++;
+
+                if (i == 4 && copy.regs[R_EAX] == 0)
+                    break;
+                if (i == 0xb && !(copy.regs[R_ECX] & 0xff00))
+                    break;
+                if (i == 0xd && copy.regs[R_EAX] == 0)
+                    break;
+            }
+        } else
+            do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, &copy);
+    }
 
     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);
+    kvm_setup_cpuid2(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent);
     return 0;
 }
 
-- 
1.6.3.rc4.29.g8146