xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
	Ian Jackson <Ian.Jackson@eu.citrix.com>,
	Jan Beulich <jbeulich@suse.com>
Subject: [PATCH v6 21/21] tools/libxc: Calculate xstate cpuid leaf from guest information
Date: Fri, 8 Apr 2016 21:31:57 +0100	[thread overview]
Message-ID: <1460147517-11706-22-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1460147517-11706-1-git-send-email-andrew.cooper3@citrix.com>

The existing logic is broken for heterogeneous migration.  By always
advertising the host maximum xstate, a migration to a less capable host always
fails as Xen cannot accomodate the xcr0_accum in the migration stream.

By calculating xstate from the feature information (which a multi-host
toolstack will have levelled appropriately), the guest will have the current
hosts maximum xstate advertised, allowing for correct migration to less
capable hosts.

In addition, some further improvements and corrections:
 - don't discard the known flags in sub-leaves 2..63 ECX
 - zap sub-leaves beyond 62
 - zap all bits in leaf 1, EBX/ECX.  No XSS features are currently supported.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
---
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>

v3:
 * Reintroduce MPX adjustment (this series has been in development since
   before the introduction of MPX upstream, and it got lost in a rebase).
v4:
 * Fold further improvements from Jan.
v5:
 * Reintroduce PKRU, (again, lost due to rebasing).
 * Rewrite the commit message and comments to try and better explain why I am
   deliberatly removing host-specific information from the xstate calculation.
 * Reintroduce 0xFFFFFFFF masks for EAX, to avoid Coverity complaining about
   truncation on assignment.
---
 tools/libxc/xc_cpuid_x86.c | 89 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 14 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index fc7e20a..6d14904 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -398,54 +398,115 @@ static void intel_xc_cpuid_policy(xc_interface *xch,
     }
 }
 
+/* XSTATE bits in XCR0. */
+#define X86_XCR0_X87    (1ULL <<  0)
+#define X86_XCR0_SSE    (1ULL <<  1)
+#define X86_XCR0_AVX    (1ULL <<  2)
+#define X86_XCR0_BNDREG (1ULL <<  3)
+#define X86_XCR0_BNDCSR (1ULL <<  4)
+#define X86_XCR0_PKRU   (1ULL <<  9)
+#define X86_XCR0_LWP    (1ULL << 62)
+
+#define X86_XSS_MASK    (0) /* No XSS states supported yet. */
+
+/* Per-component subleaf flags. */
+#define XSTATE_XSS      (1ULL <<  0)
+#define XSTATE_ALIGN64  (1ULL <<  1)
+
 /* Configure extended state enumeration leaves (0x0000000D for xsave) */
 static void xc_cpuid_config_xsave(xc_interface *xch,
                                   const struct cpuid_domain_info *info,
                                   const unsigned int *input, unsigned int *regs)
 {
-    if ( info->xfeature_mask == 0 )
+    uint64_t guest_xfeature_mask;
+
+    if ( info->xfeature_mask == 0 ||
+         !test_bit(X86_FEATURE_XSAVE, info->featureset) )
     {
         regs[0] = regs[1] = regs[2] = regs[3] = 0;
         return;
     }
 
+    guest_xfeature_mask = X86_XCR0_SSE | X86_XCR0_X87;
+
+    if ( test_bit(X86_FEATURE_AVX, info->featureset) )
+        guest_xfeature_mask |= X86_XCR0_AVX;
+
+    if ( test_bit(X86_FEATURE_MPX, info->featureset) )
+        guest_xfeature_mask |= X86_XCR0_BNDREG | X86_XCR0_BNDCSR;
+
+    if ( test_bit(X86_FEATURE_PKU, info->featureset) )
+        guest_xfeature_mask |= X86_XCR0_PKRU;
+
+    if ( test_bit(X86_FEATURE_LWP, info->featureset) )
+        guest_xfeature_mask |= X86_XCR0_LWP;
+
+    /*
+     * In the common case, the toolstack will have queried Xen for the maximum
+     * available featureset, and guest_xfeature_mask should not able to be
+     * calculated as being greater than the host limit, info->xfeature_mask.
+     *
+     * Nothing currently prevents a toolstack (or an optimistic user) from
+     * purposefully trying to select a larger-than-available xstate set.
+     *
+     * To avoid the domain dying with an unexpected fault, clamp the
+     * calculated mask to the host limit.  Future development work will remove
+     * this possibility, when Xen fully audits the complete cpuid polcy set
+     * for a domain.
+     */
+    guest_xfeature_mask &= info->xfeature_mask;
+
     switch ( input[1] )
     {
-    case 0: 
+    case 0:
         /* EAX: low 32bits of xfeature_enabled_mask */
-        regs[0] = info->xfeature_mask & 0xFFFFFFFF;
+        regs[0] = guest_xfeature_mask & 0xFFFFFFFF;
         /* EDX: high 32bits of xfeature_enabled_mask */
-        regs[3] = (info->xfeature_mask >> 32) & 0xFFFFFFFF;
+        regs[3] = guest_xfeature_mask >> 32;
         /* 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]++ )
+            for ( _input[1] = 2; _input[1] <= 62; _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. */ 
+        /* 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] = info->featureset[featureword_of(X86_FEATURE_XSAVEOPT)];
-        regs[2] &= info->xfeature_mask;
-        regs[3] = 0;
+        regs[1] = 0;
+
+        if ( test_bit(X86_FEATURE_XSAVES, info->featureset) )
+        {
+            regs[2] = guest_xfeature_mask & X86_XSS_MASK & 0xFFFFFFFF;
+            regs[3] = (guest_xfeature_mask >> 32) & X86_XSS_MASK;
+        }
+        else
+            regs[2] = regs[3] = 0;
         break;
-    case 2 ... 63: /* sub-leaves */
-        if ( !(info->xfeature_mask & (1ULL << input[1])) )
+
+    case 2 ... 62: /* per-component sub-leaves */
+        if ( !(guest_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;
+        regs[2] &= XSTATE_XSS | XSTATE_ALIGN64;
+        regs[3] = 0;
+        break;
+
+    default:
+        regs[0] = regs[1] = regs[2] = regs[3] = 0;
         break;
     }
 }
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  parent reply	other threads:[~2016-04-08 20:31 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-08 20:31 [PATCH v6 00/21] x86: Improvements to cpuid handling for guests Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 01/21] xen/x86: Annotate VM applicability in featureset Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 02/21] xen/x86: Calculate maximum host and guest featuresets Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 03/21] xen/x86: Generate deep dependencies of features Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 04/21] xen/x86: Clear dependent features when clearing a cpu cap Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 05/21] xen/x86: Improve disabling of features which have dependencies Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 06/21] xen/x86: Improvements to in-hypervisor cpuid sanity checks Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 07/21] x86/cpu: Move set_cpumask() calls into c_early_init() Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 08/21] x86/cpu: Sysctl and common infrastructure for levelling context switching Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 09/21] x86/cpu: Rework AMD masking MSR setup Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 10/21] x86/cpu: Rework Intel masking/faulting setup Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 11/21] x86/cpu: Context switch cpuid masks and faulting state in context_switch() Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 12/21] x86/pv: Provide custom cpumasks for PV domains Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 13/21] x86/domctl: Update PV domain cpumasks when setting cpuid policy Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 14/21] xen+tools: Export maximum host and guest cpu featuresets via SYSCTL Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 15/21] tools/libxc: Modify bitmap operations to take void pointers Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 16/21] tools/libxc: Use public/featureset.h for cpuid policy generation Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 17/21] tools/libxc: Expose the automatically generated cpu featuremask information Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 18/21] tools: Utility for dealing with featuresets Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 19/21] tools/libxc: Wire a featureset through to cpuid policy logic Andrew Cooper
2016-04-08 20:31 ` [PATCH v6 20/21] tools/libxc: Use featuresets rather than guesswork Andrew Cooper
2016-04-08 20:31 ` Andrew Cooper [this message]
2016-04-09  0:04 ` [PATCH v6 00/21] x86: Improvements to cpuid handling for guests Konrad Rzeszutek Wilk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1460147517-11706-22-git-send-email-andrew.cooper3@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).