diff options
author | Keir Fraser <keir@xen.org> | 2010-11-15 09:27:53 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2010-11-15 09:27:53 +0000 |
commit | 9a36faf0c63bbb898d26f2114f0cb71b723f66c9 (patch) | |
tree | 4d3c71942585a6cdc183f350214cba75fa6cd8e1 /tools/libxc/xc_cpuid_x86.c | |
parent | d549bdb2a0bbd012263d0795f435fdd0bdae0da6 (diff) | |
download | xen-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.c | 30 |
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: |