From 0d3b2772fef3fc200204c150304887ab699da68b Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 12 Sep 2013 11:32:21 +0200 Subject: x86/xsave: initialization improvements - properly validate available feature set on APs - also validate xsaveopt availability on APs - properly indicate whether the initialization is on the BSP (we shouldn't be using "cpu == 0" checks for this) Signed-off-by: Jan Beulich Acked-by: Keir Fraser master commit: c6066e78f4a66005b0d5d86c6ade32e2ab78923a master date: 2013-08-30 10:56:07 +0200 --- xen/arch/x86/cpu/common.c | 2 +- xen/arch/x86/xstate.c | 28 +++++++++++++++------------- xen/include/asm-x86/xstate.h | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index b8cd59c2c9..44542f4d49 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -369,7 +369,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) clear_bit(X86_FEATURE_XSAVE, boot_cpu_data.x86_capability); if ( cpu_has_xsave ) - xstate_init(); + xstate_init(c == &boot_cpu_data); /* * The vendor-specific functions might have changed features. Now diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index e1412e257c..27a0eded4c 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -253,11 +253,10 @@ void xstate_free_save_area(struct vcpu *v) } /* Collect the information of processor's extended state */ -void xstate_init(void) +void xstate_init(bool_t bsp) { - u32 eax, ebx, ecx, edx; - int cpu = smp_processor_id(); - u32 min_size; + u32 eax, ebx, ecx, edx, min_size; + u64 feature_mask; if ( boot_cpu_data.cpuid_level < XSTATE_CPUID ) return; @@ -266,6 +265,7 @@ void xstate_init(void) BUG_ON((eax & XSTATE_FP_SSE) != XSTATE_FP_SSE); BUG_ON((eax & XSTATE_YMM) && !(eax & XSTATE_SSE)); + feature_mask = (((u64)edx << 32) | eax) & XCNTXT_MASK; /* FP/SSE, XSAVE.HEADER, YMM */ min_size = XSTATE_AREA_MIN_SIZE; @@ -277,31 +277,33 @@ void xstate_init(void) * Set CR4_OSXSAVE and run "cpuid" to get xsave_cntxt_size. */ set_in_cr4(X86_CR4_OSXSAVE); - if ( !set_xcr0((((u64)edx << 32) | eax) & XCNTXT_MASK) ) + if ( !set_xcr0(feature_mask) ) BUG(); cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx); - if ( cpu == 0 ) + if ( bsp ) { + xfeature_mask = feature_mask; /* * xsave_cntxt_size is the max size required by enabled features. * We know FP/SSE and YMM about eax, and nothing about edx at present. */ xsave_cntxt_size = ebx; - xfeature_mask = eax + ((u64)edx << 32); - xfeature_mask &= XCNTXT_MASK; printk("%s: using cntxt_size: 0x%x and states: 0x%"PRIx64"\n", __func__, xsave_cntxt_size, xfeature_mask); - - /* Check XSAVEOPT feature. */ - cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx); - cpu_has_xsaveopt = !!(eax & XSTATE_FEATURE_XSAVEOPT); } else { + BUG_ON(xfeature_mask != feature_mask); BUG_ON(xsave_cntxt_size != ebx); - BUG_ON(xfeature_mask != (xfeature_mask & XCNTXT_MASK)); } + + /* Check XSAVEOPT feature. */ + cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx); + if ( bsp ) + cpu_has_xsaveopt = !!(eax & XSTATE_FEATURE_XSAVEOPT); + else + BUG_ON(!cpu_has_xsaveopt != !(eax & XSTATE_FEATURE_XSAVEOPT)); } int handle_xsetbv(u32 index, u64 new_bv) diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h index 3c6f91d908..b0b9a1c5cb 100644 --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -83,6 +83,6 @@ int __must_check handle_xsetbv(u32 index, u64 new_bv); /* extended state init and cleanup functions */ void xstate_free_save_area(struct vcpu *v); int xstate_alloc_save_area(struct vcpu *v); -void xstate_init(void); +void xstate_init(bool_t bsp); #endif /* __ASM_XSTATE_H */ -- cgit v1.2.3