aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/traps.c
diff options
context:
space:
mode:
authorShan Haitao <haitao.shan@intel.com>2011-09-18 00:01:58 +0100
committerShan Haitao <haitao.shan@intel.com>2011-09-18 00:01:58 +0100
commit60bb1d8cd45c041117a65374478e8da7d8e23f60 (patch)
treebd95e7181c881176d4ae570b866292db7cdf652f /xen/arch/x86/traps.c
parent022aa5fea4fcd347a1657baac68eae8d24fe3b9f (diff)
downloadxen-60bb1d8cd45c041117a65374478e8da7d8e23f60.tar.gz
xen-60bb1d8cd45c041117a65374478e8da7d8e23f60.tar.bz2
xen-60bb1d8cd45c041117a65374478e8da7d8e23f60.zip
Fix PV CPUID virtualization of XSave
The patch will fix XSave CPUID virtualization for PV guests. The XSave area size returned by CPUID leaf D is changed dynamically depending on the XCR0. Tools/libxc only assigns a static value. The fix will adjust xsave area size during runtime. Note: This fix is already in HVM cpuid virtualization. And Dom0 is not affected, either. Signed-off-by: Shan Haitao <haitao.shan@intel.com>
Diffstat (limited to 'xen/arch/x86/traps.c')
-rw-r--r--xen/arch/x86/traps.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 183ce91b74..0203613b53 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -770,6 +770,30 @@ static void pv_cpuid(struct cpu_user_regs *regs)
{
if ( !cpuid_hypervisor_leaves(a, c, &a, &b, &c, &d) )
domain_cpuid(current->domain, a, c, &a, &b, &c, &d);
+
+ switch ( a )
+ {
+ case 0xd:
+ {
+ unsigned int sub_leaf, _eax, _ebx, _ecx, _edx;
+ /* EBX value of main leaf 0 depends on enabled xsave features */
+ if ( c == 0 && current->arch.xcr0 )
+ {
+ /* reset EBX to default value first */
+ b = XSTATE_AREA_MIN_SIZE;
+ for ( sub_leaf = 2; sub_leaf < 63; sub_leaf++ )
+ {
+ if ( !(current->arch.xcr0 & (1ULL << sub_leaf)) )
+ continue;
+ domain_cpuid(current->domain, a, c, &_eax, &_ebx, &_ecx,
+ &_edx);
+ if ( (_eax + _ebx) > b )
+ b = _eax + _ebx;
+ }
+ }
+ break;
+ }
+ }
goto out;
}