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(©); 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) { + if (i == 4 || i == 0xb || i == 0xd) { + for (j = 0; ; ++j) { + do_cpuid_ent(&cpuid_ent[cpuid_nent], i, j, ©); + + 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.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); + kvm_setup_cpuid2(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent); return 0; } -- 1.6.3.rc4.29.g8146