aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_cpuid_x86.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-11-15 09:27:53 +0000
committerKeir Fraser <keir@xen.org>2010-11-15 09:27:53 +0000
commit9a36faf0c63bbb898d26f2114f0cb71b723f66c9 (patch)
tree4d3c71942585a6cdc183f350214cba75fa6cd8e1 /tools/libxc/xc_cpuid_x86.c
parentd549bdb2a0bbd012263d0795f435fdd0bdae0da6 (diff)
downloadxen-9a36faf0c63bbb898d26f2114f0cb71b723f66c9.tar.gz
xen-9a36faf0c63bbb898d26f2114f0cb71b723f66c9.tar.bz2
xen-9a36faf0c63bbb898d26f2114f0cb71b723f66c9.zip
x86 xsave: Adding back CPUID support for Xsave (version 2)
XSave support via CPUID virtualization for both PV and HVM guests. Signed-off-by: Shan Haitao <haitao.shan@intel.com>
Diffstat (limited to 'tools/libxc/xc_cpuid_x86.c')
-rw-r--r--tools/libxc/xc_cpuid_x86.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index e517eb7733..7d963a903e 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -168,13 +168,21 @@ static void xc_cpuid_hvm_policy(
xc_interface *xch, domid_t domid,
const unsigned int *input, unsigned int *regs)
{
+ DECLARE_DOMCTL;
char brand[13];
unsigned long pae;
- int is_pae;
+ int is_pae, xsave_supported;
xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &pae);
is_pae = !!pae;
+ /* Detecting Xen's atitude towards XSAVE */
+ memset(&domctl, 0, sizeof(domctl));
+ domctl.cmd = XEN_DOMCTL_getvcpuextstate;
+ domctl.domain = domid;
+ do_domctl(xch, &domctl);
+ xsave_supported = (domctl.u.vcpuextstate.xfeature_mask != 0);
+
switch ( input[0] )
{
case 0x00000000:
@@ -195,7 +203,10 @@ static void xc_cpuid_hvm_policy(
bitmaskof(X86_FEATURE_SSE4_1) |
bitmaskof(X86_FEATURE_SSE4_2) |
bitmaskof(X86_FEATURE_POPCNT) |
- bitmaskof(X86_FEATURE_AES));
+ bitmaskof(X86_FEATURE_AES) |
+ (xsave_supported)?
+ (bitmaskof(X86_FEATURE_AVX) |
+ bitmaskof(X86_FEATURE_XSAVE)) : 0);
regs[2] |= bitmaskof(X86_FEATURE_HYPERVISOR);
@@ -280,7 +291,7 @@ static void xc_cpuid_pv_policy(
const unsigned int *input, unsigned int *regs)
{
DECLARE_DOMCTL;
- int guest_64bit, xen_64bit = hypervisor_is_64bit(xch);
+ int guest_64bit, xsave_supported, xen_64bit = hypervisor_is_64bit(xch);
char brand[13];
xc_cpuid_brand_get(brand);
@@ -291,6 +302,13 @@ static void xc_cpuid_pv_policy(
do_domctl(xch, &domctl);
guest_64bit = (domctl.u.address_size.size == 64);
+ /* Detecting Xen's atitude towards XSAVE */
+ memset(&domctl, 0, sizeof(domctl));
+ domctl.cmd = XEN_DOMCTL_getvcpuextstate;
+ domctl.domain = domid;
+ do_domctl(xch, &domctl);
+ xsave_supported = (domctl.u.vcpuextstate.xfeature_mask != 0);
+
if ( (input[0] & 0x7fffffff) == 1 )
{
clear_bit(X86_FEATURE_VME, regs[3]);
@@ -320,10 +338,14 @@ static void xc_cpuid_pv_policy(
clear_bit(X86_FEATURE_TM2, regs[2]);
if ( !guest_64bit )
clear_bit(X86_FEATURE_CX16, regs[2]);
+ if ( !xsave_supported )
+ {
+ clear_bit(X86_FEATURE_XSAVE, regs[2]);
+ clear_bit(X86_FEATURE_AVX, regs[2]);
+ }
clear_bit(X86_FEATURE_XTPR, regs[2]);
clear_bit(X86_FEATURE_PDCM, regs[2]);
clear_bit(X86_FEATURE_DCA, regs[2]);
- clear_bit(X86_FEATURE_XSAVE, regs[2]);
set_bit(X86_FEATURE_HYPERVISOR, regs[2]);
break;
case 0x80000001: