x86/xsaves: ebx may return wrong value using CPUID eax=0xd,ecx =1

Refer to SDM Volume 1 Extended Region of an XSAVE Area. The value returned
by ecx[1] with cpuid function 0xd and sub-function 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 guest using CPUID eax=0xd, 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@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Shuai Ruan authored and Jan Beulich committed 2016-04-08 00:04:39 +02:00
1 parent 6b5e0bc7e4
commit 9d313bdebb
3 files changed
+10 -5

No files matched your search

+8 -4
View File
@@ -3432,14 +3432,18 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
}
if ( count == 1 )
{
if ( cpu_has_xsaves && cpu_has_vmx_xsaves )
uint64_t xfeatures = v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss;
if ( cpu_has_xsaves && cpu_has_vmx_xsaves && xfeatures )
{
*ebx = XSTATE_AREA_MIN_SIZE;
if ( v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss )
if ( xfeatures & ~XSTATE_FP_SSE )
for ( sub_leaf = 2; sub_leaf < 63; sub_leaf++ )
if ( (v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss) &
(1ULL << sub_leaf) )
if ( xfeatures & (1ULL << sub_leaf) )
{
if ( test_bit(sub_leaf, &xstate_align) )
*ebx = ROUNDUP(*ebx, 64);
*ebx += xstate_sizes[sub_leaf];
}
}
else
*ebx = *ecx = *edx = 0;
+1 -1
View File
@@ -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;
+1
View File
@@ -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 */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.