[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V7 3/3] x86/xsaves: ebx may return wrong value using CPUID eax=0xdh, ecx =1
From: Shuai Ruan <shuai.ruan@xxxxxxxxx> Refer to SDM 13.4.3 Extended Region of an XSAVE Area. The value return by ecx[1] with cpuid function 0xdh and sub-fucntion i (i>1) indicates the alignment of the state component i when the compacted format of the extended region of an xsave area is used. So when hvm/pv guest using CPUID eax=0xdh,ecx=1 to get the size of area used for compacted format, we need to take alignment into consideration. tools side is fixed by "tools/libxc: Calculate xstate cpuid leaf from guest information" by Andrew Cooper Signed-off-by: Shuai Ruan <shuai.ruan@xxxxxxxxx> --- v2: Address comments by Jan: 1. take alignment into consideration in pv_cpuid. 2. fix coding style issues xen/arch/x86/hvm/hvm.c | 6 +++++- xen/arch/x86/traps.c | 12 ++++++++++++ xen/arch/x86/xstate.c | 2 +- xen/include/asm-x86/xstate.h | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 5aef3cb..c6cd4fb 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4743,14 +4743,18 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx, } if ( count == 1 ) { - if ( cpu_has_xsaves && cpu_has_vmx_xsaves ) + if ( (cpu_has_xsaves && cpu_has_vmx_xsaves) || cpu_has_xsavec ) { *ebx = XSTATE_AREA_MIN_SIZE; if ( v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss ) for ( sub_leaf = 2; sub_leaf < 63; sub_leaf++ ) if ( (v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss) & (1ULL << sub_leaf) ) + { + if ( test_bit(sub_leaf, &xstate_align) ) + *ebx = ROUNDUP(*ebx, 64); *ebx += xstate_sizes[sub_leaf]; + } } else *ebx = *ecx = *edx = 0; diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 6fbb1cf..8694da6 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1020,6 +1020,18 @@ void pv_cpuid(struct cpu_user_regs *regs) a &= (boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_XSAVEOPT)] & ~cpufeat_mask(X86_FEATURE_XSAVES)); b = c = d = 0; + if ( cpu_has_xsavec ) + { + b = XSTATE_AREA_MIN_SIZE; + if ( curr->arch.xcr0 ) + for( subleaf = 2; subleaf < 63; subleaf++ ) + if ( (1ULL << subleaf) & curr->arch.xcr0 ) + { + if ( test_bit(subleaf, &xstate_align) ) + b = ROUNDUP(b, 64); + b += xstate_sizes[subleaf]; + } + } break; } break; diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index f4ea54d..850b778 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -26,7 +26,7 @@ u64 __read_mostly xfeature_mask; static unsigned int *__read_mostly xstate_offsets; unsigned int *__read_mostly xstate_sizes; -static u64 __read_mostly xstate_align; +u64 __read_mostly xstate_align; static unsigned int __read_mostly xstate_features; static uint32_t __read_mostly mxcsr_mask = 0x0000ffbf; diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h index 91d1c39..535443a 100644 --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -50,6 +50,7 @@ #define XSTATE_ALIGN64 (1U << 1) extern u64 xfeature_mask; +extern u64 xstate_align; extern unsigned int *xstate_sizes; /* extended state save area */ -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |