|
[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 |