From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50086) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bnWQ8-0000ir-9G for qemu-devel@nongnu.org; Fri, 23 Sep 2016 15:46:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bnWQ7-0003rU-3z for qemu-devel@nongnu.org; Fri, 23 Sep 2016 15:46:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38790) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bnWQ6-0003rH-Tl for qemu-devel@nongnu.org; Fri, 23 Sep 2016 15:46:03 -0400 From: Eduardo Habkost Date: Fri, 23 Sep 2016 16:45:35 -0300 Message-Id: <1474659936-978-7-git-send-email-ehabkost@redhat.com> In-Reply-To: <1474659936-978-1-git-send-email-ehabkost@redhat.com> References: <1474659936-978-1-git-send-email-ehabkost@redhat.com> Subject: [Qemu-devel] [PATCH 6/7] target-i386: xsave: Calculate set of xsave components on realize List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Richard Henderson , Igor Mammedov Instead of doing complex calculations and calling kvm_arch_get_supported_cpuid() inside cpu_x86_cpuid(), calculate the set of required XSAVE components earlier, at realize time. Signed-off-by: Eduardo Habkost --- target-i386/cpu.c | 51 ++++++++++++++++++++++++++++----------------------- target-i386/cpu.h | 1 + 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 9034d8e..e6525e7 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2504,9 +2504,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ebx &= 0xffff; /* The count doesn't need to be reliable. */ break; case 0xD: { - uint64_t ena_mask; - int i; - /* Processor Extended State */ *eax = 0; *ebx = 0; @@ -2516,32 +2513,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; } - ena_mask = (XSTATE_FP_MASK | XSTATE_SSE_MASK); - for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { - const ExtSaveArea *esa = &x86_ext_save_areas[i]; - if (env->features[esa->feature] & esa->bits) { - ena_mask |= (1ULL << i); - } - } - - if (kvm_enabled()) { - KVMState *s = cs->kvm_state; - uint64_t kvm_mask = kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX); - kvm_mask <<= 32; - kvm_mask |= kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX); - ena_mask &= kvm_mask; - } - if (count == 0) { - *ecx = xsave_area_size(ena_mask);; - *eax = ena_mask; - *edx = ena_mask >> 32; + *ecx = xsave_area_size(env->xsave_components); + *eax = env->xsave_components; + *edx = env->xsave_components >> 32; *ebx = *ecx; } else if (count == 1) { *eax = env->features[FEAT_XSAVE]; } else if (count < ARRAY_SIZE(x86_ext_save_areas)) { const ExtSaveArea *esa = &x86_ext_save_areas[count]; - if ((ena_mask >> count) & 1) { + if ((env->xsave_components >> count) & 1) { *eax = esa->size; *ebx = esa->offset; } @@ -2971,6 +2952,29 @@ static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w) } } +/* Calculate XSAVE components based on the configured CPU feature flags */ +static void x86_cpu_enable_xsave_components(X86CPU *cpu) +{ + CPUX86State *env = &cpu->env; + int i; + + env->xsave_components = (XSTATE_FP_MASK | XSTATE_SSE_MASK); + for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { + const ExtSaveArea *esa = &x86_ext_save_areas[i]; + if (env->features[esa->feature] & esa->bits) { + env->xsave_components |= (1ULL << i); + } + } + + if (kvm_enabled()) { + KVMState *s = kvm_state; + uint64_t kvm_mask = kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX); + kvm_mask <<= 32; + kvm_mask |= kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX); + env->xsave_components &= kvm_mask; + } +} + #define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \ (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \ (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3) @@ -3016,6 +3020,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) cpu->env.features[w] &= ~minus_features[w]; } + x86_cpu_enable_xsave_components(cpu); /* CPUID[EAX=7,ECX=0].EBX always increased level automatically: */ x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX); diff --git a/target-i386/cpu.h b/target-i386/cpu.h index aaa45f0..6c457ed 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1122,6 +1122,7 @@ typedef struct CPUX86State { uint32_t cpuid_vendor3; uint32_t cpuid_version; FeatureWordArray features; + uint64_t xsave_components; uint32_t cpuid_model[12]; /* MTRRs */ -- 2.7.4