WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86 xsave: supports xsave (CPUID:0xD) enu

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 xsave: supports xsave (CPUID:0xD) enumeration for all sub-leaves.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 24 Dec 2010 15:47:33 -0800
Delivery-date: Fri, 24 Dec 2010 15:54:04 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1293179982 0
# Node ID 920826e80bee78d725fc3758bc7e378734d85bb8
# Parent  26e7e6c6ff7f9775fb77f58ddc0454ef08a1a908
x86 xsave: supports xsave (CPUID:0xD) enumeration for all sub-leaves.

In specific, it fixes the following issues:

1. The sub-leaves of CPUID:0x0000000D aren't contiguous. Hypervisor
shouldn't use register values to stop the enumeration. This patch
moves checking on XSAVE sub-leaves out of if-else statement. It also
bumps up sub-leaves to 63.
2. It creates a common function for xsave.
3. The main leaf 0 of CPUID:0x0000000D in current Xen is broken,
especially ECX and EBX registers. This patch cleans it up.
4. It adds support to detects EBX value of CPUID:0x0000000D main leaf
0 on-the-fly.

Signed-off-by: Wei Huang2 <wei.huang2@xxxxxxx>
---
 tools/libxc/xc_cpuid_x86.c |  114 +++++++++++++++++++++++++--------------------
 xen/arch/x86/hvm/hvm.c     |   18 +++++++
 2 files changed, 83 insertions(+), 49 deletions(-)

diff -r 26e7e6c6ff7f -r 920826e80bee tools/libxc/xc_cpuid_x86.c
--- a/tools/libxc/xc_cpuid_x86.c        Fri Dec 24 08:38:22 2010 +0000
+++ b/tools/libxc/xc_cpuid_x86.c        Fri Dec 24 08:39:42 2010 +0000
@@ -160,6 +160,58 @@ static void intel_xc_cpuid_policy(
     case 0x80000008:
         /* Mask AMD Number of Cores information. */
         regs[2] = 0;
+        break;
+    }
+}
+
+#define XSAVEOPT        (1 << 0)
+/* Configure extended state enumeration leaves (0x0000000D for xsave) */
+static void xc_cpuid_config_xsave(
+    xc_interface *xch, domid_t domid, uint64_t xfeature_mask,
+    const unsigned int *input, unsigned int *regs)
+{
+    if ( xfeature_mask == 0 )
+    {
+        regs[0] = regs[1] = regs[2] = regs[3] = 0;
+        return;
+    }
+
+    switch ( input[1] )
+    {
+    case 0: 
+        /* EAX: low 32bits of xfeature_enabled_mask */
+        regs[0] = xfeature_mask & 0xFFFFFFFF;
+        /* EDX: high 32bits of xfeature_enabled_mask */
+        regs[3] = (xfeature_mask >> 32) & 0xFFFFFFFF;
+        /* ECX: max size required by all HW features */
+        {
+            unsigned int _input[2] = {0xd, 0x0}, _regs[4];
+            regs[2] = 0;
+            for ( _input[1] = 2; _input[1] < 64; _input[1]++ )
+            {
+                cpuid(_input, _regs);
+                if ( (_regs[0] + _regs[1]) > regs[2] )
+                    regs[2] = _regs[0] + _regs[1];
+            }
+        }
+        /* EBX: max size required by enabled features. 
+         * This register contains a dynamic value, which varies when a guest 
+         * enables or disables XSTATE features (via xsetbv). The default size 
+         * after reset is 576. */ 
+        regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
+        break;
+    case 1: /* leaf 1 */
+        regs[0] &= XSAVEOPT;
+        regs[1] = regs[2] = regs[3] = 0;
+        break;
+    case 2 ... 63: /* sub-leaves */
+        if ( !(xfeature_mask & (1ULL << input[1])) )
+        {
+            regs[0] = regs[1] = regs[2] = regs[3] = 0;
+            break;
+        }
+        /* Don't touch EAX, EBX. Also cleanup ECX and EDX */
+        regs[2] = regs[3] = 0;
         break;
     }
 }
@@ -244,43 +296,7 @@ static void xc_cpuid_hvm_policy(
         break;
 
     case 0x0000000d:
-#define XSTATE_FP       (1 << 0)
-#define XSTATE_SSE      (1 << 1)
-#define XSTATE_YMM      (1 << 2)
-#define XSAVEOPT        (1 << 0)
-#define XSTATE_YMM_SIZE 256
-        if ( xfeature_mask == 0 )
-        {
-            regs[0] = regs[1] = regs[2] = regs[3] = 0;
-            break;
-        }
-        switch ( input[1] )
-        {
-        case 0:
-            /* We only enable the features we know. */
-            regs[0] = xfeature_mask;
-            /* FP/SSE + XSAVE.HEADER + YMM. */
-            regs[2] = 512 + 64;
-            if ( regs[0] & XSTATE_YMM )
-                regs[2] += XSTATE_YMM_SIZE;
-            regs[1] = regs[2];
-            regs[3] = 0;
-            break;
-        case 1:
-            regs[0] &= XSAVEOPT;
-            regs[1] = regs[2] = regs[3] = 0;
-            break;
-        case 2:
-            if ( !(xfeature_mask & XSTATE_YMM) )
-                break;
-            regs[0] = XSTATE_YMM_SIZE;
-            regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
-            regs[2] = regs[3] = 0;
-            break;
-        default:
-            regs[0] = regs[1] = regs[2] = regs[3] = 0;
-            break;
-        }
+        xc_cpuid_config_xsave(xch, domid, xfeature_mask, input, regs);
         break;
 
     case 0x80000000:
@@ -501,20 +517,20 @@ int xc_cpuid_apply_policy(xc_interface *
             rc = xc_cpuid_do_domctl(xch, domid, input, regs);
             if ( rc )
                 return rc;
-
-            /* Intel cache descriptor leaves. */
-            if ( input[0] == 4 )
-            {
-                input[1]++;
-                /* More to do? Then loop keeping %%eax==0x00000004. */
-                if ( (regs[0] & 0x1f) != 0 )
-                    continue;
-            }
-
-            /* XSAVE information, subleaves 0-2. */
-            if ( (input[0] == 0xd) && (input[1]++ < 2) )
+        }
+
+        /* Intel cache descriptor leaves. */
+        if ( input[0] == 4 )
+        {
+            input[1]++;
+            /* More to do? Then loop keeping %%eax==0x00000004. */
+            if ( (regs[0] & 0x1f) != 0 )
                 continue;
         }
+
+        /* XSAVE information, subleaves 0-63. */
+        if ( (input[0] == 0xd) && (input[1]++ < 63) )
+            continue;
 
         input[0]++;
         if ( !(input[0] & 0x80000000u) && (input[0] > base_max ) )
diff -r 26e7e6c6ff7f -r 920826e80bee xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Dec 24 08:38:22 2010 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Fri Dec 24 08:39:42 2010 +0000
@@ -2144,6 +2144,24 @@ void hvm_cpuid(unsigned int input, unsig
         /* Fix the x2APIC identifier. */
         *edx = v->vcpu_id * 2;
         break;
+    case 0xd:
+    {
+        unsigned int sub_leaf, _eax, _ebx, _ecx, _edx;
+        /* EBX value of main leaf 0 depends on enabled xsave features */
+        if ( count == 0 && v->arch.xcr0 ) 
+        {
+            for ( sub_leaf = 2; 
+                  (sub_leaf < 64) && (v->arch.xcr0 & (1ULL << sub_leaf));
+                  sub_leaf++ ) 
+            {
+                domain_cpuid(v->domain, input, sub_leaf, &_eax, &_ebx, &_ecx, 
+                             &_edx);
+                if ( (_eax + _ebx) > *ebx )
+                    *ebx = _eax + _ebx;
+            }
+        }
+        break;
+    }
     case 0x80000001:
         /* We expose RDTSCP feature to guest only when
            tsc_mode == TSC_MODE_DEFAULT and host_tsc_is_safe() returns 1 */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 xsave: supports xsave (CPUID:0xD) enumeration for all sub-leaves., Xen patchbot-unstable <=