All of lore.kernel.org
 help / color / mirror / Atom feed
* [V6 0/4] add xsaves/xrstors support
@ 2015-10-12  6:07 Shuai Ruan
  2015-10-12  6:07 ` [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Shuai Ruan @ 2015-10-12  6:07 UTC (permalink / raw)
  To: xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	jun.nakajima, andrew.cooper3, ian.jackson, eddie.dong, jbeulich,
	keir

From: Shuai Ruan <shuai.ruan@intel.com>

Changes in v6:
* Address comments from Jan.
* Rebase the code based on Andrew'patch "xen/x86: Record xsave features in c->x86_capabilities".
* Re-split the patch to avoid building errors. Move some func definitions from patch1 to patch2.
* Change func name load/save_xsave_states to compress/expand_xsave_states in patch2.  
* Add macro to handle redundancy in xrstor.
* Fix some code errors and coding style errors.
* Add some descriptions in commit message.

Changes in v5:
*Address comments from Andrew/Jan,mainly:
*Add lazy writes of the xss_msr.
*Add xsave_area check when save/restore guest.
*Add xsavec support.
*Use word 2 in xen/include/asm-x86/cpufeature.h.
*Fix some code errors.

Changes in v4:
* Address comments from Andrew, mainly:
* No xsaves suporting for pv guest.
* Using xstate_sizes instead of domain_cpuid in hvm_cupid in patch 3.
* Add support for format translation when perform pv guest migration in patch 2. 
* Fix some code errors.

Changes in v3:
* Address comments from Jan/Konrad
* Change the bits of eax/ebx/ecx/edx passed to guest in patch 4.
* Add code to verify whether host supports xsaves or not in patch 1.

Changes in v2:
* Address comments from Andrew/chao/Jan, mainly:
* Add details information of xsaves/xrstors feature.
* Test migration between xsaves-support machine and none-xsaves-support machine 
* Remove XGETBV1/XSAVEC/XSAVEOPT out of 'else' in patch 3.
* Change macro name XGETBV to XGETBV1 in patch 4.

This patchset enable xsaves/xrstors feature which will be available on 
Intel Skylake and later platform. Like xsave/xrstor, xsaves/xrstors 
feature will save and load processor state from a region of memory called 
XSAVE area. While unlike xsave/xrstor, xsaves/xrstors:

a) use the compacted format only for the extended region 
   of the XSAVE area which saves memory for you;
b) can operate on supervisor state components so the feature
   is prerequisite to support new supervisor state components;
c) execute only if CPL=0. 

Detail hardware spec can be found in chapter 13 (section 13.11 13.12) of the 
Intel SDM [1].

patch1: add basic definition/function to support xsaves
patch2: add xsaves/xrstors support for xen
patch3-4: add xsaves/xrstors support for hvm guest


[1] Intel SDM (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf)


Shuai Ruan (4):
  x86/xsaves: add basic definitions/helpers to support xsaves
  x86/xsaves: enable xsaves/xrstors/xsavec in xen
  x86/xsaves: enable xsaves/xrstors for hvm guest
  libxc: expose xsaves/xgetbv1/xsavec to hvm guest

 tools/libxc/xc_cpuid_x86.c         |  16 ++-
 xen/arch/x86/domain.c              |   2 +
 xen/arch/x86/domctl.c              |  35 +++++-
 xen/arch/x86/hvm/hvm.c             |  46 ++++++-
 xen/arch/x86/hvm/vmx/vmcs.c        |   5 +-
 xen/arch/x86/hvm/vmx/vmx.c         |  20 ++++
 xen/arch/x86/i387.c                |   4 +
 xen/arch/x86/traps.c               |   6 +-
 xen/arch/x86/xstate.c              | 237 ++++++++++++++++++++++++++++++++-----
 xen/include/asm-x86/hvm/vcpu.h     |   1 +
 xen/include/asm-x86/hvm/vmx/vmcs.h |   4 +
 xen/include/asm-x86/hvm/vmx/vmx.h  |   2 +
 xen/include/asm-x86/msr-index.h    |   2 +
 xen/include/asm-x86/xstate.h       |  27 ++++-
 14 files changed, 356 insertions(+), 51 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves
  2015-10-12  6:07 [V6 0/4] add xsaves/xrstors support Shuai Ruan
@ 2015-10-12  6:07 ` Shuai Ruan
  2015-10-12  9:25   ` Andrew Cooper
  2015-10-13 13:33   ` Jan Beulich
  2015-10-12  6:07 ` [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen Shuai Ruan
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 13+ messages in thread
From: Shuai Ruan @ 2015-10-12  6:07 UTC (permalink / raw)
  To: xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	jun.nakajima, andrew.cooper3, ian.jackson, eddie.dong, jbeulich,
	keir

This patch add basic definitions/helpers which will be used in
later patches.

Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
---
 xen/arch/x86/xstate.c           | 16 ++++++++++++++++
 xen/include/asm-x86/hvm/vcpu.h  |  1 +
 xen/include/asm-x86/msr-index.h |  2 ++
 xen/include/asm-x86/xstate.h    | 25 ++++++++++++++++++++++++-
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c
index 9ddff90..730368a 100644
--- a/xen/arch/x86/xstate.c
+++ b/xen/arch/x86/xstate.c
@@ -23,6 +23,11 @@ static u32 __read_mostly xsave_cntxt_size;
 
 /* A 64-bit bitmask of the XSAVE/XRSTOR features supported by processor. */
 u64 __read_mostly xfeature_mask;
+unsigned int * __read_mostly xstate_offsets;
+unsigned int * __read_mostly xstate_sizes;
+
+/* Cached xss for fast read */
+static DEFINE_PER_CPU(uint64_t, xss);
 
 /* Cached xcr0 for fast read */
 static DEFINE_PER_CPU(uint64_t, xcr0);
@@ -60,6 +65,17 @@ uint64_t get_xcr0(void)
     return this_cpu(xcr0);
 }
 
+void set_msr_xss(u64 xss)
+{
+    wrmsrl(MSR_IA32_XSS, xss);
+    this_cpu(xss) = xss;
+}
+
+uint64_t get_msr_xss(void)
+{
+    return this_cpu(xss);
+}
+
 void xsave(struct vcpu *v, uint64_t mask)
 {
     struct xsave_struct *ptr = v->arch.xsave_area;
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index f553814..de81f8a 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -173,6 +173,7 @@ struct hvm_vcpu {
 
     u32                 msr_tsc_aux;
     u64                 msr_tsc_adjust;
+    u64                 msr_xss;
 
     union {
         struct arch_vmx_struct vmx;
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index e9c4723..4e5b31f 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -58,6 +58,8 @@
 
 #define MSR_IA32_BNDCFGS		0x00000D90
 
+#define MSR_IA32_XSS			0x00000da0
+
 #define MSR_MTRRfix64K_00000		0x00000250
 #define MSR_MTRRfix16K_80000		0x00000258
 #define MSR_MTRRfix16K_A0000		0x00000259
diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h
index f0d8f0b..f23435a 100644
--- a/xen/include/asm-x86/xstate.h
+++ b/xen/include/asm-x86/xstate.h
@@ -19,7 +19,11 @@
 
 #define XCR_XFEATURE_ENABLED_MASK 0x00000000  /* index of XCR0 */
 
+#define XSAVE_HDR_SIZE            64
+#define XSAVE_SSE_OFFSET          160
 #define XSTATE_YMM_SIZE           256
+#define FXSAVE_SIZE               512
+#define XSAVE_HDR_OFFSET          FXSAVE_SIZE
 #define XSTATE_AREA_MIN_SIZE      (512 + 64)  /* FP/SSE + XSAVE.HEADER */
 
 #define XSTATE_FP      (1ULL << 0)
@@ -38,8 +42,24 @@
 #define XSTATE_ALL     (~(1ULL << 63))
 #define XSTATE_NONLAZY (XSTATE_LWP | XSTATE_BNDREGS | XSTATE_BNDCSR)
 #define XSTATE_LAZY    (XSTATE_ALL & ~XSTATE_NONLAZY)
+#define XSTATE_COMPACTION_ENABLED  (1ULL << 63)
+
+#define XSTATE_FIXUP ".section .fixup,\"ax\"      \n"        \
+                     "2: mov %5,%%ecx             \n"        \
+                     "   xor %1,%1                \n"        \
+                     "   rep stosb                \n"        \
+                     "   lea %2,%0                \n"        \
+                     "   mov %3,%1                \n"        \
+                     "   jmp 1b                   \n"        \
+                     ".previous                   \n"        \
+                     _ASM_EXTABLE(1b, 2b)                    \
+                     : "+&D" (ptr), "+&a" (lmask)            \
+                     : "m" (*ptr), "g" (lmask), "d" (hmask), \
+                       "m" (xsave_cntxt_size)                \
+                     : "ecx"
 
 extern u64 xfeature_mask;
+extern unsigned int *xstate_offsets, *xstate_sizes;
 
 /* extended state save area */
 struct __packed __attribute__((aligned (64))) xsave_struct
@@ -68,7 +88,8 @@ struct __packed __attribute__((aligned (64))) xsave_struct
 
     struct {
         u64 xstate_bv;
-        u64 reserved[7];
+        u64 xcomp_bv;
+        u64 reserved[6];
     } xsave_hdr;                             /* The 64-byte header */
 
     struct { char x[XSTATE_YMM_SIZE]; } ymm; /* YMM */
@@ -78,6 +99,8 @@ struct __packed __attribute__((aligned (64))) xsave_struct
 /* extended state operations */
 bool_t __must_check set_xcr0(u64 xfeatures);
 uint64_t get_xcr0(void);
+void set_msr_xss(u64 xss);
+uint64_t get_msr_xss(void);
 void xsave(struct vcpu *v, uint64_t mask);
 void xrstor(struct vcpu *v, uint64_t mask);
 bool_t xsave_enabled(const struct vcpu *v);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
  2015-10-12  6:07 [V6 0/4] add xsaves/xrstors support Shuai Ruan
  2015-10-12  6:07 ` [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
@ 2015-10-12  6:07 ` Shuai Ruan
  2015-10-12 10:05   ` Andrew Cooper
  2015-10-13 13:49   ` Jan Beulich
  2015-10-12  6:07 ` [V6 3/4] x86/xsaves: enable xsaves/xrstors for hvm guest Shuai Ruan
  2015-10-12  6:07 ` [V6 4/4] libxc: expose xsaves/xgetbv1/xsavec to " Shuai Ruan
  3 siblings, 2 replies; 13+ messages in thread
From: Shuai Ruan @ 2015-10-12  6:07 UTC (permalink / raw)
  To: xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	jun.nakajima, andrew.cooper3, ian.jackson, eddie.dong, jbeulich,
	keir

This patch uses xsaves/xrstors/xsavec instead of xsaveopt/xrstor
to perform the xsave_area switching so that xen itself
can benefit from them when available.

For xsaves/xrstors/xsavec only use compact format. Add format conversion
support when perform guest os migration.

Also, pv guest will not support xsaves/xrstors.

Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
---
 xen/arch/x86/domain.c        |   2 +
 xen/arch/x86/domctl.c        |  35 ++++++-
 xen/arch/x86/hvm/hvm.c       |  19 +++-
 xen/arch/x86/i387.c          |   4 +
 xen/arch/x86/traps.c         |   6 +-
 xen/arch/x86/xstate.c        | 221 ++++++++++++++++++++++++++++++++++++-------
 xen/include/asm-x86/xstate.h |   2 +
 7 files changed, 244 insertions(+), 45 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 7ca9b93..7b3d9f4 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1569,6 +1569,8 @@ static void __context_switch(void)
             if ( xcr0 != get_xcr0() && !set_xcr0(xcr0) )
                 BUG();
         }
+        if ( cpu_has_xsaves && is_hvm_vcpu(n) )
+            set_msr_xss(n->arch.hvm_vcpu.msr_xss);
         vcpu_restore_fpu_eager(n);
         n->arch.ctxt_switch_to(n);
     }
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index f8a559c..9517741 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -897,9 +897,30 @@ long arch_do_domctl(
                 ret = -EFAULT;
 
             offset += sizeof(v->arch.xcr0_accum);
-            if ( !ret && copy_to_guest_offset(evc->buffer, offset,
-                                              (void *)v->arch.xsave_area,
-                                              size - 2 * sizeof(uint64_t)) )
+
+            if ( !ret && (cpu_has_xsaves || cpu_has_xsavec) )
+            {
+                void *xsave_area;
+
+                xsave_area = xmalloc_bytes(size);
+                if ( !xsave_area )
+                {
+                    ret = -ENOMEM;
+                    vcpu_unpause(v);
+                    goto vcpuextstate_out;
+                }
+
+                expand_xsave_states(v, xsave_area,
+                                    evc->size - 2 * sizeof(uint64_t));
+
+                if ( copy_to_guest_offset(evc->buffer, offset, xsave_area,
+                                          size - 2 * sizeof(uint64_t)) )
+                     ret = -EFAULT;
+                xfree(xsave_area);
+           }
+           else if ( !ret && copy_to_guest_offset(evc->buffer, offset,
+                                                  (void *)v->arch.xsave_area,
+                                                  size - 2 * sizeof(uint64_t)) )
                 ret = -EFAULT;
 
             vcpu_unpause(v);
@@ -955,8 +976,12 @@ long arch_do_domctl(
                 v->arch.xcr0_accum = _xcr0_accum;
                 if ( _xcr0_accum & XSTATE_NONLAZY )
                     v->arch.nonlazy_xstate_used = 1;
-                memcpy(v->arch.xsave_area, _xsave_area,
-                       evc->size - 2 * sizeof(uint64_t));
+                if ( (cpu_has_xsaves || cpu_has_xsavec) )
+                    compress_xsave_states(v, _xsave_area,
+                                          evc->size - 2 * sizeof(uint64_t));
+                else
+                    memcpy(v->arch.xsave_area, (void *)_xsave_area,
+                           evc->size - 2 * sizeof(uint64_t));
                 vcpu_unpause(v);
             }
             else
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 3fa2280..177cf5f 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -2157,8 +2157,12 @@ static int hvm_save_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
         ctxt->xfeature_mask = xfeature_mask;
         ctxt->xcr0 = v->arch.xcr0;
         ctxt->xcr0_accum = v->arch.xcr0_accum;
-        memcpy(&ctxt->save_area, v->arch.xsave_area,
-               size - offsetof(struct hvm_hw_cpu_xsave, save_area));
+        if ( (cpu_has_xsaves || cpu_has_xsavec) )
+            expand_xsave_states(v, &ctxt->save_area,
+                                size - offsetof(typeof(*ctxt), save_area));
+        else
+            memcpy(&ctxt->save_area, v->arch.xsave_area,
+                   size - offsetof(struct hvm_hw_cpu_xsave, save_area));
     }
 
     return 0;
@@ -2257,9 +2261,14 @@ static int hvm_load_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
     v->arch.xcr0_accum = ctxt->xcr0_accum;
     if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
         v->arch.nonlazy_xstate_used = 1;
-    memcpy(v->arch.xsave_area, &ctxt->save_area,
-           min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
-           save_area));
+    if ( (cpu_has_xsaves || cpu_has_xsavec) )
+        compress_xsave_states(v, &ctxt->save_area,
+                              min(desc->length, size) -
+                              offsetof(struct hvm_hw_cpu_xsave,save_area));
+    else
+        memcpy(v->arch.xsave_area, &ctxt->save_area,
+               min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
+               save_area));
 
     return 0;
 }
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
index 14f2a79..736197f 100644
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -309,7 +309,11 @@ int vcpu_init_fpu(struct vcpu *v)
         return rc;
 
     if ( v->arch.xsave_area )
+    {
         v->arch.fpu_ctxt = &v->arch.xsave_area->fpu_sse;
+        if ( cpu_has_xsaves || cpu_has_xsavec )
+            v->arch.xsave_area->xsave_hdr.xcomp_bv |= XSTATE_COMPACTION_ENABLED;
+    }
     else
     {
         v->arch.fpu_ctxt = _xzalloc(sizeof(v->arch.xsave_area->fpu_sse), 16);
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 07feb6d..316fc7f 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -935,9 +935,9 @@ void pv_cpuid(struct cpu_user_regs *regs)
             goto unsupported;
         if ( regs->_ecx == 1 )
         {
-            a &= boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32];
-            if ( !cpu_has_xsaves )
-                b = c = d = 0;
+            a &= (boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32] &
+                 ~cpufeat_mask(X86_FEATURE_XSAVES));
+            b = c = d = 0;
         }
         break;
 
diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c
index 730368a..323c6f2 100644
--- a/xen/arch/x86/xstate.c
+++ b/xen/arch/x86/xstate.c
@@ -25,6 +25,8 @@ static u32 __read_mostly xsave_cntxt_size;
 u64 __read_mostly xfeature_mask;
 unsigned int * __read_mostly xstate_offsets;
 unsigned int * __read_mostly xstate_sizes;
+static unsigned int __read_mostly xstate_features;
+static unsigned int __read_mostly xstate_comp_offsets[sizeof(xfeature_mask)*8];
 
 /* Cached xss for fast read */
 static DEFINE_PER_CPU(uint64_t, xss);
@@ -76,6 +78,154 @@ uint64_t get_msr_xss(void)
     return this_cpu(xss);
 }
 
+static bool_t xsave_area_compressed(const struct xsave_struct *xsave_area)
+{
+     return xsave_area && (xsave_area->xsave_hdr.xcomp_bv
+                           & XSTATE_COMPACTION_ENABLED);
+}
+
+static int setup_xstate_features(bool_t bsp)
+{
+    unsigned int leaf, tmp, eax, ebx;
+
+    if ( bsp )
+    {
+        xstate_features = fls(xfeature_mask);
+        xstate_offsets = xzalloc_array(unsigned int, xstate_features);
+        if ( !xstate_offsets )
+            return -ENOMEM;
+
+        xstate_sizes = xzalloc_array(unsigned int, xstate_features);
+        if ( !xstate_sizes )
+            return -ENOMEM;
+    }
+
+    for ( leaf = 2; leaf < xstate_features; leaf++ )
+    {
+        if ( bsp )
+            cpuid_count(XSTATE_CPUID, leaf, &xstate_sizes[leaf],
+                        &xstate_offsets[leaf], &tmp, &tmp);
+        else
+        {
+            cpuid_count(XSTATE_CPUID, leaf, &eax,
+                        &ebx, &tmp, &tmp);
+            BUG_ON(eax != xstate_sizes[leaf]);
+            BUG_ON(ebx != xstate_offsets[leaf]);
+        }
+    }
+
+    return 0;
+}
+
+static void __init setup_xstate_comp(void)
+{
+    unsigned int i;
+
+    /*
+     * The FP xstates and SSE xstates are legacy states. They are always
+     * in the fixed offsets in the xsave area in either compacted form
+     * or standard form.
+     */
+    xstate_comp_offsets[0] = 0;
+    xstate_comp_offsets[1] = XSAVE_SSE_OFFSET;
+
+    xstate_comp_offsets[2] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+
+    for ( i = 3; i < xstate_features; i++ )
+    {
+        xstate_comp_offsets[i] = xstate_comp_offsets[i-1] +
+                                 (((1ul << i) & xfeature_mask)
+                                 ? xstate_sizes[i-1] : 0);
+        ASSERT(xstate_comp_offsets[i] + xstate_sizes[i] <= xsave_cntxt_size);
+    }
+}
+
+static void *get_xsave_addr(const struct xsave_struct *xsave, unsigned int xfeature_idx)
+{
+    if ( !((1ul << xfeature_idx) & xfeature_mask) )
+        return NULL;
+
+    return (void *)xsave + xstate_comp_offsets[xfeature_idx];
+}
+
+void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size)
+{
+    const struct xsave_struct *xsave = v->arch.xsave_area;
+    struct xsave_struct *dest_xsave = (struct xsave_struct *)dest;
+    u64 xstate_bv = xsave->xsave_hdr.xstate_bv;
+    u64 valid;
+
+    ASSERT(xsave_area_compressed(xsave));
+    /*
+     * Copy legacy XSAVE area, to avoid complications with CPUID
+     * leaves 0 and 1 in the loop below.
+     */
+    memcpy(dest, xsave, FXSAVE_SIZE);
+
+    dest_xsave->xsave_hdr.xstate_bv = xstate_bv;
+    dest_xsave->xsave_hdr.xcomp_bv =  0;
+
+    /*
+     * Copy each region from the possibly compacted offset to the
+     * non-compacted offset.
+     */
+    valid = xstate_bv & ~XSTATE_FP_SSE;
+    while ( valid )
+    {
+        u64 feature = valid & -valid;
+        unsigned int index = fls(feature) - 1;
+        void *src = get_xsave_addr(xsave, index);
+
+        if ( src )
+        {
+            ASSERT((xstate_offsets[index] + xstate_sizes[index]) <= size);
+            memcpy(dest + xstate_offsets[index], src, xstate_sizes[index]);
+        }
+
+        valid &= ~feature;
+    }
+
+}
+
+void compress_xsave_states(struct vcpu *v, const void *src, unsigned int size)
+{
+    struct xsave_struct *xsave = v->arch.xsave_area;
+    struct xsave_struct *src_xsave = (struct xsave_struct *)src;
+    u64 xstate_bv = src_xsave->xsave_hdr.xstate_bv;
+    u64 valid;
+
+    ASSERT(!xsave_area_compressed((struct xsave_struct *)src));
+    /*
+     * Copy legacy XSAVE area, to avoid complications with CPUID
+     * leaves 0 and 1 in the loop below.
+     */
+    memcpy(xsave, src, FXSAVE_SIZE);
+
+    /* Set XSTATE_BV and XCOMP_BV.  */
+    xsave->xsave_hdr.xstate_bv = xstate_bv;
+    xsave->xsave_hdr.xcomp_bv = v->arch.xcr0_accum | XSTATE_COMPACTION_ENABLED;
+
+    /*
+     * Copy each region from the non-compacted offset to the
+     * possibly compacted offset.
+     */
+    valid = xstate_bv & ~XSTATE_FP_SSE;
+    while ( valid )
+    {
+        u64 feature = valid & -valid;
+        unsigned int index = fls(feature) - 1;
+        void *dest = get_xsave_addr(xsave, index);
+
+        if ( dest )
+        {
+            ASSERT((xstate_offsets[index] + xstate_sizes[index]) <= size);
+            memcpy(dest, src + xstate_offsets[index], xstate_sizes[index]);
+        }
+
+        valid &= ~feature;
+    }
+}
+
 void xsave(struct vcpu *v, uint64_t mask)
 {
     struct xsave_struct *ptr = v->arch.xsave_area;
@@ -88,7 +238,15 @@ void xsave(struct vcpu *v, uint64_t mask)
         typeof(ptr->fpu_sse.fip.sel) fcs = ptr->fpu_sse.fip.sel;
         typeof(ptr->fpu_sse.fdp.sel) fds = ptr->fpu_sse.fdp.sel;
 
-        if ( cpu_has_xsaveopt )
+        if ( cpu_has_xsaves )
+            asm volatile ( ".byte 0x48,0x0f,0xc7,0x2f"
+                           : "=m" (*ptr)
+                           : "a" (lmask), "d" (hmask), "D" (ptr) );
+        else if ( cpu_has_xsavec )
+            asm volatile ( ".byte 0x48,0x0f,0xc7,0x27"
+                           : "=m" (*ptr)
+                           : "a" (lmask), "d" (hmask), "D" (ptr) );
+        else if ( cpu_has_xsaveopt )
         {
             /*
              * xsaveopt may not write the FPU portion even when the respective
@@ -141,7 +299,15 @@ void xsave(struct vcpu *v, uint64_t mask)
     }
     else
     {
-        if ( cpu_has_xsaveopt )
+        if ( cpu_has_xsaves )
+            asm volatile ( ".byte 0x48,0x0f,0xc7,0x2f"
+                           : "=m" (*ptr)
+                           : "a" (lmask), "d" (hmask), "D" (ptr) );
+        else if ( cpu_has_xsavec )
+            asm volatile ( ".byte 0x48,0x0f,0xc7,0x27"
+                           : "=m" (*ptr)
+                           : "a" (lmask), "d" (hmask), "D" (ptr) );
+        else if ( cpu_has_xsaveopt )
             asm volatile ( ".byte 0x0f,0xae,0x37"
                            : "=m" (*ptr)
                            : "a" (lmask), "d" (hmask), "D" (ptr) );
@@ -184,36 +350,20 @@ void xrstor(struct vcpu *v, uint64_t mask)
     switch ( __builtin_expect(ptr->fpu_sse.x[FPU_WORD_SIZE_OFFSET], 8) )
     {
     default:
-        asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n"
-                       ".section .fixup,\"ax\"      \n"
-                       "2: mov %5,%%ecx             \n"
-                       "   xor %1,%1                \n"
-                       "   rep stosb                \n"
-                       "   lea %2,%0                \n"
-                       "   mov %3,%1                \n"
-                       "   jmp 1b                   \n"
-                       ".previous                   \n"
-                       _ASM_EXTABLE(1b, 2b)
-                       : "+&D" (ptr), "+&a" (lmask)
-                       : "m" (*ptr), "g" (lmask), "d" (hmask),
-                         "m" (xsave_cntxt_size)
-                       : "ecx" );
-        break;
+        if ( cpu_has_xsaves )
+            asm volatile ( "1: .byte 0x48,0x0f,0xc7,0x1f\n"
+                           XSTATE_FIXUP );
+        else
+            asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n"
+                           XSTATE_FIXUP );
+            break;
     case 4: case 2:
-        asm volatile ( "1: .byte 0x0f,0xae,0x2f\n"
-                       ".section .fixup,\"ax\" \n"
-                       "2: mov %5,%%ecx        \n"
-                       "   xor %1,%1           \n"
-                       "   rep stosb           \n"
-                       "   lea %2,%0           \n"
-                       "   mov %3,%1           \n"
-                       "   jmp 1b              \n"
-                       ".previous              \n"
-                       _ASM_EXTABLE(1b, 2b)
-                       : "+&D" (ptr), "+&a" (lmask)
-                       : "m" (*ptr), "g" (lmask), "d" (hmask),
-                         "m" (xsave_cntxt_size)
-                       : "ecx" );
+        if ( cpu_has_xsaves )
+            asm volatile ( "1: .byte 0x48,0x0f,0xc7,0x1f\n"
+                           XSTATE_FIXUP );
+        else
+            asm volatile ( "1: .byte 0x0f,0xae,0x2f\n"
+                           XSTATE_FIXUP );
         break;
     }
 }
@@ -340,11 +490,18 @@ void xstate_init(struct cpuinfo_x86 *c)
 
     /* Mask out features not currently understood by Xen. */
     eax &= (cpufeat_mask(X86_FEATURE_XSAVEOPT) |
-            cpufeat_mask(X86_FEATURE_XSAVEC));
+            cpufeat_mask(X86_FEATURE_XSAVEC) |
+            cpufeat_mask(X86_FEATURE_XGETBV1) |
+            cpufeat_mask(X86_FEATURE_XSAVES));
 
     c->x86_capability[X86_FEATURE_XSAVEOPT / 32] = eax;
 
     BUG_ON(eax != boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32]);
+
+    if ( setup_xstate_features(bsp) )
+        BUG();
+    if ( bsp && (cpu_has_xsaves || cpu_has_xsavec) )
+        setup_xstate_comp();
 }
 
 static bool_t valid_xcr0(u64 xcr0)
diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h
index f23435a..1c4c5fd 100644
--- a/xen/include/asm-x86/xstate.h
+++ b/xen/include/asm-x86/xstate.h
@@ -106,6 +106,8 @@ void xrstor(struct vcpu *v, uint64_t mask);
 bool_t xsave_enabled(const struct vcpu *v);
 int __must_check validate_xstate(u64 xcr0, u64 xcr0_accum, u64 xstate_bv);
 int __must_check handle_xsetbv(u32 index, u64 new_bv);
+void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size);
+void compress_xsave_states(struct vcpu *v, const void *src, unsigned int size);
 
 /* extended state init and cleanup functions */
 void xstate_free_save_area(struct vcpu *v);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [V6 3/4] x86/xsaves: enable xsaves/xrstors for hvm guest
  2015-10-12  6:07 [V6 0/4] add xsaves/xrstors support Shuai Ruan
  2015-10-12  6:07 ` [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
  2015-10-12  6:07 ` [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen Shuai Ruan
@ 2015-10-12  6:07 ` Shuai Ruan
  2015-10-12  6:07 ` [V6 4/4] libxc: expose xsaves/xgetbv1/xsavec to " Shuai Ruan
  3 siblings, 0 replies; 13+ messages in thread
From: Shuai Ruan @ 2015-10-12  6:07 UTC (permalink / raw)
  To: xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	jun.nakajima, andrew.cooper3, ian.jackson, eddie.dong, jbeulich,
	keir

This patch enables xsaves for hvm guest, includes:
1.handle xsaves vmcs init and vmexit.
2.add logic to write/read the XSS msr.

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
---
 xen/arch/x86/hvm/hvm.c             | 27 +++++++++++++++++++++++++++
 xen/arch/x86/hvm/vmx/vmcs.c        |  5 ++++-
 xen/arch/x86/hvm/vmx/vmx.c         | 20 ++++++++++++++++++++
 xen/include/asm-x86/hvm/vmx/vmcs.h |  4 ++++
 xen/include/asm-x86/hvm/vmx/vmx.h  |  2 ++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 177cf5f..a7c45be 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4561,6 +4561,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
                     *ebx = _eax + _ebx;
             }
         }
+        if ( count == 1 )
+        {
+            if ( cpu_has_xsaves && cpu_has_vmx_xsaves )
+            {
+                *ebx = XSTATE_AREA_MIN_SIZE;
+                if ( v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss )
+                    for ( sub_leaf = 2; sub_leaf < 63; sub_leaf++ )
+                        if ( (v->arch.xcr0 | v->arch.hvm_vcpu.msr_xss)
+                             & (1ULL << sub_leaf) )
+                            *ebx += xstate_sizes[sub_leaf];
+            }
+            else
+                *ebx = *ecx = *edx = 0;
+        }
         break;
 
     case 0x80000001:
@@ -4660,6 +4674,12 @@ int hvm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
         *msr_content = v->arch.hvm_vcpu.guest_efer;
         break;
 
+    case MSR_IA32_XSS:
+        if ( !cpu_has_xsaves )
+            goto gp_fault;
+        *msr_content = v->arch.hvm_vcpu.msr_xss;
+        break;
+
     case MSR_IA32_TSC:
         *msr_content = _hvm_rdtsc_intercept();
         break;
@@ -4792,6 +4812,13 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content,
            return X86EMUL_EXCEPTION;
         break;
 
+    case MSR_IA32_XSS:
+        /* No XSS features currently supported for guests. */
+        if ( !cpu_has_xsaves || msr_content != 0 )
+            goto gp_fault;
+        v->arch.hvm_vcpu.msr_xss = msr_content;
+        break;
+
     case MSR_IA32_TSC:
         hvm_set_guest_tsc(v, msr_content);
         break;
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 3592a88..7185d55 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -240,7 +240,8 @@ static int vmx_init_vmcs_config(void)
                SECONDARY_EXEC_PAUSE_LOOP_EXITING |
                SECONDARY_EXEC_ENABLE_INVPCID |
                SECONDARY_EXEC_ENABLE_VM_FUNCTIONS |
-               SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS);
+               SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS |
+               SECONDARY_EXEC_XSAVES);
         rdmsrl(MSR_IA32_VMX_MISC, _vmx_misc_cap);
         if ( _vmx_misc_cap & VMX_MISC_VMWRITE_ALL )
             opt |= SECONDARY_EXEC_ENABLE_VMCS_SHADOWING;
@@ -1249,6 +1250,8 @@ static int construct_vmcs(struct vcpu *v)
         __vmwrite(HOST_PAT, host_pat);
         __vmwrite(GUEST_PAT, guest_pat);
     }
+    if ( cpu_has_vmx_xsaves )
+        __vmwrite(XSS_EXIT_BITMAP, 0);
 
     vmx_vmcs_exit(v);
 
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index bbec0e8..5d723e8 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2852,6 +2852,18 @@ static void vmx_idtv_reinject(unsigned long idtv_info)
     }
 }
 
+static void vmx_handle_xsaves(void)
+{
+    gdprintk(XENLOG_ERR, "xsaves should not cause vmexit\n");
+    domain_crash(current->domain);
+}
+
+static void vmx_handle_xrstors(void)
+{
+    gdprintk(XENLOG_ERR, "xrstors should not cause vmexit\n");
+    domain_crash(current->domain);
+}
+
 static int vmx_handle_apic_write(void)
 {
     unsigned long exit_qualification;
@@ -3423,6 +3435,14 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         vmx_vcpu_flush_pml_buffer(v);
         break;
 
+    case EXIT_REASON_XSAVES:
+        vmx_handle_xsaves();
+        break;
+
+    case EXIT_REASON_XRSTORS:
+        vmx_handle_xrstors();
+        break;
+
     case EXIT_REASON_ACCESS_GDTR_OR_IDTR:
     case EXIT_REASON_ACCESS_LDTR_OR_TR:
     case EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED:
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index f1126d4..79c2c58 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -225,6 +225,7 @@ extern u32 vmx_vmentry_control;
 #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING    0x00004000
 #define SECONDARY_EXEC_ENABLE_PML               0x00020000
 #define SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS   0x00040000
+#define SECONDARY_EXEC_XSAVES                   0x00100000
 extern u32 vmx_secondary_exec_control;
 
 #define VMX_EPT_EXEC_ONLY_SUPPORTED             0x00000001
@@ -291,6 +292,8 @@ extern u32 vmx_secondary_exec_control;
     (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS)
 #define cpu_has_vmx_pml \
     (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_PML)
+#define cpu_has_vmx_xsaves \
+    (vmx_secondary_exec_control & SECONDARY_EXEC_XSAVES)
 
 #define VMCS_RID_TYPE_MASK              0x80000000
 
@@ -365,6 +368,7 @@ enum vmcs_field {
     VMREAD_BITMAP                   = 0x00002026,
     VMWRITE_BITMAP                  = 0x00002028,
     VIRT_EXCEPTION_INFO             = 0x0000202a,
+    XSS_EXIT_BITMAP                 = 0x0000202c,
     GUEST_PHYSICAL_ADDRESS          = 0x00002400,
     VMCS_LINK_POINTER               = 0x00002800,
     GUEST_IA32_DEBUGCTL             = 0x00002802,
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 2ed62f9..cb66925 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -188,6 +188,8 @@ static inline unsigned long pi_get_pir(struct pi_desc *pi_desc, int group)
 #define EXIT_REASON_INVPCID             58
 #define EXIT_REASON_VMFUNC              59
 #define EXIT_REASON_PML_FULL            62
+#define EXIT_REASON_XSAVES              63
+#define EXIT_REASON_XRSTORS             64
 
 /*
  * Interruption-information format
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [V6 4/4] libxc: expose xsaves/xgetbv1/xsavec to hvm guest
  2015-10-12  6:07 [V6 0/4] add xsaves/xrstors support Shuai Ruan
                   ` (2 preceding siblings ...)
  2015-10-12  6:07 ` [V6 3/4] x86/xsaves: enable xsaves/xrstors for hvm guest Shuai Ruan
@ 2015-10-12  6:07 ` Shuai Ruan
  2015-10-12 10:11   ` Andrew Cooper
  3 siblings, 1 reply; 13+ messages in thread
From: Shuai Ruan @ 2015-10-12  6:07 UTC (permalink / raw)
  To: xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	jun.nakajima, andrew.cooper3, ian.jackson, eddie.dong, jbeulich,
	keir

This patch exposes xsaves/xgetbv1/xsavec to hvm guest.
The reserved bits of eax/ebx/ecx/edx must be cleaned up
when call cpuid(0dh) with leaf 1 or 2..63.

According to the spec the following bits must be reserved:
For leaf 1, bits 03-04/08-31 of ecx is reserved. Edx is reserved.
For leaf 2...63, bits 01-31 of ecx is reserved. Edx is reserved.

Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
---
 tools/libxc/xc_cpuid_x86.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index e146a3e..b0d6ecc 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -210,6 +210,10 @@ static void intel_xc_cpuid_policy(
 }
 
 #define XSAVEOPT        (1 << 0)
+#define XSAVEC          (1 << 1)
+#define XGETBV1         (1 << 2)
+#define XSAVES          (1 << 3)
+#define XSS_SUPPORT     (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,
@@ -246,8 +250,9 @@ static void xc_cpuid_config_xsave(
         regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
         break;
     case 1: /* leaf 1 */
-        regs[0] &= XSAVEOPT;
-        regs[1] = regs[2] = regs[3] = 0;
+        regs[0] &= (XSAVEOPT | XSAVEC | XGETBV1 | XSAVES);
+        regs[2] &= xfeature_mask;
+        regs[3] = 0;
         break;
     case 2 ... 63: /* sub-leaves */
         if ( !(xfeature_mask & (1ULL << input[1])) )
@@ -255,8 +260,11 @@ static void xc_cpuid_config_xsave(
             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;
+        /* Don't touch EAX, EBX and cleanup EDX.
+         * Bit 0 of ECX represent whether sub-leave is supported in IA32_XSS
+         * msr or supported in XCR0.*/
+        regs[2] &= XSS_SUPPORT;
+        regs[3] = 0;
         break;
     }
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves
  2015-10-12  6:07 ` [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
@ 2015-10-12  9:25   ` Andrew Cooper
  2015-10-13 13:33   ` Jan Beulich
  1 sibling, 0 replies; 13+ messages in thread
From: Andrew Cooper @ 2015-10-12  9:25 UTC (permalink / raw)
  To: Shuai Ruan, xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	eddie.dong, ian.jackson, jbeulich, jun.nakajima, keir

On 12/10/15 07:07, Shuai Ruan wrote:
> This patch add basic definitions/helpers which will be used in
> later patches.
>
> Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
> ---
>  xen/arch/x86/xstate.c           | 16 ++++++++++++++++
>  xen/include/asm-x86/hvm/vcpu.h  |  1 +
>  xen/include/asm-x86/msr-index.h |  2 ++
>  xen/include/asm-x86/xstate.h    | 25 ++++++++++++++++++++++++-
>  4 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c
> index 9ddff90..730368a 100644
> --- a/xen/arch/x86/xstate.c
> +++ b/xen/arch/x86/xstate.c
> @@ -23,6 +23,11 @@ static u32 __read_mostly xsave_cntxt_size;
>  
>  /* A 64-bit bitmask of the XSAVE/XRSTOR features supported by processor. */
>  u64 __read_mostly xfeature_mask;
> +unsigned int * __read_mostly xstate_offsets;
> +unsigned int * __read_mostly xstate_sizes;
> +
> +/* Cached xss for fast read */
> +static DEFINE_PER_CPU(uint64_t, xss);
>  
>  /* Cached xcr0 for fast read */
>  static DEFINE_PER_CPU(uint64_t, xcr0);
> @@ -60,6 +65,17 @@ uint64_t get_xcr0(void)
>      return this_cpu(xcr0);
>  }
>  
> +void set_msr_xss(u64 xss)
> +{
> +    wrmsrl(MSR_IA32_XSS, xss);
> +    this_cpu(xss) = xss;

This can become faster by doing a lazy write.

u64 * this_xss = &this_cpu(xss);

if ( *this_xss != xss )
{
    wrmsrl(MSR_IA32_XSS, xss);
    *this_xss = xss;
}

Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
  2015-10-12  6:07 ` [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen Shuai Ruan
@ 2015-10-12 10:05   ` Andrew Cooper
  2015-10-13  7:28     ` Shuai Ruan
  2015-10-13 13:49   ` Jan Beulich
  1 sibling, 1 reply; 13+ messages in thread
From: Andrew Cooper @ 2015-10-12 10:05 UTC (permalink / raw)
  To: Shuai Ruan, xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	eddie.dong, ian.jackson, jbeulich, jun.nakajima, keir

On 12/10/15 07:07, Shuai Ruan wrote:
> This patch uses xsaves/xrstors/xsavec instead of xsaveopt/xrstor
> to perform the xsave_area switching so that xen itself
> can benefit from them when available.
>
> For xsaves/xrstors/xsavec only use compact format. Add format conversion
> support when perform guest os migration.
>
> Also, pv guest will not support xsaves/xrstors.
>
> Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
> ---
>  xen/arch/x86/domain.c        |   2 +
>  xen/arch/x86/domctl.c        |  35 ++++++-
>  xen/arch/x86/hvm/hvm.c       |  19 +++-
>  xen/arch/x86/i387.c          |   4 +
>  xen/arch/x86/traps.c         |   6 +-
>  xen/arch/x86/xstate.c        | 221 ++++++++++++++++++++++++++++++++++++-------
>  xen/include/asm-x86/xstate.h |   2 +
>  7 files changed, 244 insertions(+), 45 deletions(-)
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index 7ca9b93..7b3d9f4 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1569,6 +1569,8 @@ static void __context_switch(void)
>              if ( xcr0 != get_xcr0() && !set_xcr0(xcr0) )
>                  BUG();
>          }
> +        if ( cpu_has_xsaves && is_hvm_vcpu(n) )

Because of the current implementation of PVH mode, the correct predicate
here is has_hvm_container(n)

> +            set_msr_xss(n->arch.hvm_vcpu.msr_xss);
>          vcpu_restore_fpu_eager(n);
>          n->arch.ctxt_switch_to(n);
>      }
> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
> index f8a559c..9517741 100644
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -897,9 +897,30 @@ long arch_do_domctl(
>                  ret = -EFAULT;
>  
>              offset += sizeof(v->arch.xcr0_accum);
> -            if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> -                                              (void *)v->arch.xsave_area,
> -                                              size - 2 * sizeof(uint64_t)) )
> +
> +            if ( !ret && (cpu_has_xsaves || cpu_has_xsavec) )
> +            {
> +                void *xsave_area;
> +
> +                xsave_area = xmalloc_bytes(size);
> +                if ( !xsave_area )
> +                {
> +                    ret = -ENOMEM;
> +                    vcpu_unpause(v);
> +                    goto vcpuextstate_out;
> +                }
> +
> +                expand_xsave_states(v, xsave_area,
> +                                    evc->size - 2 * sizeof(uint64_t));
> +
> +                if ( copy_to_guest_offset(evc->buffer, offset, xsave_area,
> +                                          size - 2 * sizeof(uint64_t)) )
> +                     ret = -EFAULT;
> +                xfree(xsave_area);
> +           }
> +           else if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> +                                                  (void *)v->arch.xsave_area,
> +                                                  size - 2 * sizeof(uint64_t)) )
>                  ret = -EFAULT;
>  
>              vcpu_unpause(v);
> @@ -955,8 +976,12 @@ long arch_do_domctl(
>                  v->arch.xcr0_accum = _xcr0_accum;
>                  if ( _xcr0_accum & XSTATE_NONLAZY )
>                      v->arch.nonlazy_xstate_used = 1;
> -                memcpy(v->arch.xsave_area, _xsave_area,
> -                       evc->size - 2 * sizeof(uint64_t));
> +                if ( (cpu_has_xsaves || cpu_has_xsavec) )

You can drop the inner set of brackets.

> +                    compress_xsave_states(v, _xsave_area,
> +                                          evc->size - 2 * sizeof(uint64_t));
> +                else
> +                    memcpy(v->arch.xsave_area, (void *)_xsave_area,
> +                           evc->size - 2 * sizeof(uint64_t));
>                  vcpu_unpause(v);
>              }
>              else
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 3fa2280..177cf5f 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -2157,8 +2157,12 @@ static int hvm_save_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
>          ctxt->xfeature_mask = xfeature_mask;
>          ctxt->xcr0 = v->arch.xcr0;
>          ctxt->xcr0_accum = v->arch.xcr0_accum;
> -        memcpy(&ctxt->save_area, v->arch.xsave_area,
> -               size - offsetof(struct hvm_hw_cpu_xsave, save_area));
> +        if ( (cpu_has_xsaves || cpu_has_xsavec) )

And here

> +            expand_xsave_states(v, &ctxt->save_area,
> +                                size - offsetof(typeof(*ctxt), save_area));
> +        else
> +            memcpy(&ctxt->save_area, v->arch.xsave_area,
> +                   size - offsetof(struct hvm_hw_cpu_xsave, save_area));
>      }
>  
>      return 0;
> @@ -2257,9 +2261,14 @@ static int hvm_load_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
>      v->arch.xcr0_accum = ctxt->xcr0_accum;
>      if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
>          v->arch.nonlazy_xstate_used = 1;
> -    memcpy(v->arch.xsave_area, &ctxt->save_area,
> -           min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
> -           save_area));
> +    if ( (cpu_has_xsaves || cpu_has_xsavec) )

And here.

With these 4 things fixed, Reviewed-by: Andrew Cooper
<andrew.cooper3@citrix.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 4/4] libxc: expose xsaves/xgetbv1/xsavec to hvm guest
  2015-10-12  6:07 ` [V6 4/4] libxc: expose xsaves/xgetbv1/xsavec to " Shuai Ruan
@ 2015-10-12 10:11   ` Andrew Cooper
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Cooper @ 2015-10-12 10:11 UTC (permalink / raw)
  To: Shuai Ruan, xen-devel
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	eddie.dong, ian.jackson, jbeulich, jun.nakajima, keir

On 12/10/15 07:07, Shuai Ruan wrote:
> This patch exposes xsaves/xgetbv1/xsavec to hvm guest.
> The reserved bits of eax/ebx/ecx/edx must be cleaned up
> when call cpuid(0dh) with leaf 1 or 2..63.
>
> According to the spec the following bits must be reserved:
> For leaf 1, bits 03-04/08-31 of ecx is reserved. Edx is reserved.
> For leaf 2...63, bits 01-31 of ecx is reserved. Edx is reserved.
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>

This patch needs rebasing over c/s bf87f3a "tools/libxc: Improve
efficiency of xc_cpuid_apply_policy()"

> ---
>  tools/libxc/xc_cpuid_x86.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
> index e146a3e..b0d6ecc 100644
> --- a/tools/libxc/xc_cpuid_x86.c
> +++ b/tools/libxc/xc_cpuid_x86.c
> @@ -210,6 +210,10 @@ static void intel_xc_cpuid_policy(
>  }
>  
>  #define XSAVEOPT        (1 << 0)
> +#define XSAVEC          (1 << 1)
> +#define XGETBV1         (1 << 2)
> +#define XSAVES          (1 << 3)
> +#define XSS_SUPPORT     (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,
> @@ -246,8 +250,9 @@ static void xc_cpuid_config_xsave(
>          regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
>          break;
>      case 1: /* leaf 1 */
> -        regs[0] &= XSAVEOPT;
> -        regs[1] = regs[2] = regs[3] = 0;
> +        regs[0] &= (XSAVEOPT | XSAVEC | XGETBV1 | XSAVES);

The correct mask here depends on !info->hvm, to hide XSAVES from PV guests.

> +        regs[2] &= xfeature_mask;
> +        regs[3] = 0;
>          break;
>      case 2 ... 63: /* sub-leaves */
>          if ( !(xfeature_mask & (1ULL << input[1])) )
> @@ -255,8 +260,11 @@ static void xc_cpuid_config_xsave(
>              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;
> +        /* Don't touch EAX, EBX and cleanup EDX.
> +         * Bit 0 of ECX represent whether sub-leave is supported in IA32_XSS
> +         * msr or supported in XCR0.*/
> +        regs[2] &= XSS_SUPPORT;

No XSS features are currently supported, even in HVM guests.  This
should be unilaterally zero at the moment.

~Andrew

> +        regs[3] = 0;
>          break;
>      }
>  }

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
  2015-10-12 10:05   ` Andrew Cooper
@ 2015-10-13  7:28     ` Shuai Ruan
  0 siblings, 0 replies; 13+ messages in thread
From: Shuai Ruan @ 2015-10-13  7:28 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	jun.nakajima, ian.jackson, eddie.dong, xen-devel, jbeulich, keir

On Mon, Oct 12, 2015 at 11:05:33AM +0100, Andrew Cooper wrote:
> On 12/10/15 07:07, Shuai Ruan wrote:
> > This patch uses xsaves/xrstors/xsavec instead of xsaveopt/xrstor
> > to perform the xsave_area switching so that xen itself
> > can benefit from them when available.
> >
> > For xsaves/xrstors/xsavec only use compact format. Add format conversion
> > support when perform guest os migration.
> >
> > Also, pv guest will not support xsaves/xrstors.
> >
> > Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
> > ---
> 
> With these 4 things fixed, Reviewed-by: Andrew Cooper
> <andrew.cooper3@citrix.com>
> 
Ok.
Thanks.
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves
  2015-10-12  6:07 ` [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
  2015-10-12  9:25   ` Andrew Cooper
@ 2015-10-13 13:33   ` Jan Beulich
  1 sibling, 0 replies; 13+ messages in thread
From: Jan Beulich @ 2015-10-13 13:33 UTC (permalink / raw)
  To: Shuai Ruan
  Cc: kevin.tian, wei.liu2, eddie.dong, stefano.stabellini,
	andrew.cooper3, ian.jackson, xen-devel, jun.nakajima, keir,
	Ian.Campbell

>>> On 12.10.15 at 08:07, <shuai.ruan@linux.intel.com> wrote:
> --- a/xen/arch/x86/xstate.c
> +++ b/xen/arch/x86/xstate.c
> @@ -23,6 +23,11 @@ static u32 __read_mostly xsave_cntxt_size;
>  
>  /* A 64-bit bitmask of the XSAVE/XRSTOR features supported by processor. */
>  u64 __read_mostly xfeature_mask;
> +unsigned int * __read_mostly xstate_offsets;
> +unsigned int * __read_mostly xstate_sizes;

You appear to need the latter outside of this file in patch 3, but the
former could (and hence should) be static afaict.

> --- a/xen/include/asm-x86/xstate.h
> +++ b/xen/include/asm-x86/xstate.h
> @@ -19,7 +19,11 @@
>  
>  #define XCR_XFEATURE_ENABLED_MASK 0x00000000  /* index of XCR0 */
>  
> +#define XSAVE_HDR_SIZE            64
> +#define XSAVE_SSE_OFFSET          160
>  #define XSTATE_YMM_SIZE           256
> +#define FXSAVE_SIZE               512
> +#define XSAVE_HDR_OFFSET          FXSAVE_SIZE
>  #define XSTATE_AREA_MIN_SIZE      (512 + 64)  /* FP/SSE + XSAVE.HEADER */

This 512 should now get replaced too.

> @@ -38,8 +42,24 @@
>  #define XSTATE_ALL     (~(1ULL << 63))
>  #define XSTATE_NONLAZY (XSTATE_LWP | XSTATE_BNDREGS | XSTATE_BNDCSR)
>  #define XSTATE_LAZY    (XSTATE_ALL & ~XSTATE_NONLAZY)
> +#define XSTATE_COMPACTION_ENABLED  (1ULL << 63)
> +
> +#define XSTATE_FIXUP ".section .fixup,\"ax\"      \n"        \
> +                     "2: mov %5,%%ecx             \n"        \
> +                     "   xor %1,%1                \n"        \
> +                     "   rep stosb                \n"        \
> +                     "   lea %2,%0                \n"        \
> +                     "   mov %3,%1                \n"        \
> +                     "   jmp 1b                   \n"        \
> +                     ".previous                   \n"        \
> +                     _ASM_EXTABLE(1b, 2b)                    \
> +                     : "+&D" (ptr), "+&a" (lmask)            \
> +                     : "m" (*ptr), "g" (lmask), "d" (hmask), \
> +                       "m" (xsave_cntxt_size)                \
> +                     : "ecx"

First of all I don't think this belongs here - neither in this patch, nor
in this header. It's not being used by this patch, and the connection
between variable names used here and in patch 2 is completely lost.
If you put this into xrstor() as a local #define, then this may be
okay. In any other case the user of the macro has to have a way
to control the variable names used.

Jan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
  2015-10-12  6:07 ` [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen Shuai Ruan
  2015-10-12 10:05   ` Andrew Cooper
@ 2015-10-13 13:49   ` Jan Beulich
  2015-10-15  1:58     ` Shuai Ruan
       [not found]     ` <20151015015832.GA11071@shuai.ruan@linux.intel.com>
  1 sibling, 2 replies; 13+ messages in thread
From: Jan Beulich @ 2015-10-13 13:49 UTC (permalink / raw)
  To: Shuai Ruan
  Cc: kevin.tian, wei.liu2, eddie.dong, stefano.stabellini,
	andrew.cooper3, ian.jackson, xen-devel, jun.nakajima, keir,
	Ian.Campbell

>>> On 12.10.15 at 08:07, <shuai.ruan@linux.intel.com> wrote:
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -897,9 +897,30 @@ long arch_do_domctl(
>                  ret = -EFAULT;
>  
>              offset += sizeof(v->arch.xcr0_accum);
> -            if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> -                                              (void *)v->arch.xsave_area,
> -                                              size - 2 * sizeof(uint64_t)) )
> +
> +            if ( !ret && (cpu_has_xsaves || cpu_has_xsavec) )
> +            {
> +                void *xsave_area;
> +
> +                xsave_area = xmalloc_bytes(size);
> +                if ( !xsave_area )
> +                {
> +                    ret = -ENOMEM;
> +                    vcpu_unpause(v);
> +                    goto vcpuextstate_out;
> +                }
> +
> +                expand_xsave_states(v, xsave_area,
> +                                    evc->size - 2 * sizeof(uint64_t));
> +
> +                if ( copy_to_guest_offset(evc->buffer, offset, xsave_area,
> +                                          size - 2 * sizeof(uint64_t)) )

Here you use size, which is fine, but why do you use evc->size
three lines up from here?

> +                     ret = -EFAULT;
> +                xfree(xsave_area);
> +           }
> +           else if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> +                                                  (void *)v->arch.xsave_area,
> +                                                  size - 2 * sizeof(uint64_t)) )

I also think code readability would benefit from folding the two
copy_to_guest_offset()s, which differ in only the pointer used.

> @@ -955,8 +976,12 @@ long arch_do_domctl(
>                  v->arch.xcr0_accum = _xcr0_accum;
>                  if ( _xcr0_accum & XSTATE_NONLAZY )
>                      v->arch.nonlazy_xstate_used = 1;
> -                memcpy(v->arch.xsave_area, _xsave_area,
> -                       evc->size - 2 * sizeof(uint64_t));
> +                if ( (cpu_has_xsaves || cpu_has_xsavec) )
> +                    compress_xsave_states(v, _xsave_area,
> +                                          evc->size - 2 * sizeof(uint64_t));
> +                else
> +                    memcpy(v->arch.xsave_area, (void *)_xsave_area,

Stray cast got added here.

> @@ -2257,9 +2261,14 @@ static int hvm_load_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
>      v->arch.xcr0_accum = ctxt->xcr0_accum;
>      if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
>          v->arch.nonlazy_xstate_used = 1;
> -    memcpy(v->arch.xsave_area, &ctxt->save_area,
> -           min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
> -           save_area));
> +    if ( (cpu_has_xsaves || cpu_has_xsavec) )
> +        compress_xsave_states(v, &ctxt->save_area,
> +                              min(desc->length, size) -
> +                              offsetof(struct hvm_hw_cpu_xsave,save_area));
> +    else
> +        memcpy(v->arch.xsave_area, &ctxt->save_area,
> +               min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
> +               save_area));

Each time I look at these two hunks I wonder whether the condition
and memcpy() wouldn't better move into the new called functions.

> +void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size)
> +{
> +    const struct xsave_struct *xsave = v->arch.xsave_area;
> +    struct xsave_struct *dest_xsave = (struct xsave_struct *)dest;

Pointless cast.

> +void compress_xsave_states(struct vcpu *v, const void *src, unsigned int size)
> +{
> +    struct xsave_struct *xsave = v->arch.xsave_area;
> +    struct xsave_struct *src_xsave = (struct xsave_struct *)src;

Here the cast is even bogus, as it removes const-ness.

> +    u64 xstate_bv = src_xsave->xsave_hdr.xstate_bv;
> +    u64 valid;
> +
> +    ASSERT(!xsave_area_compressed((struct xsave_struct *)src));

Pointless cast (to same type).

Jan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
  2015-10-13 13:49   ` Jan Beulich
@ 2015-10-15  1:58     ` Shuai Ruan
       [not found]     ` <20151015015832.GA11071@shuai.ruan@linux.intel.com>
  1 sibling, 0 replies; 13+ messages in thread
From: Shuai Ruan @ 2015-10-15  1:58 UTC (permalink / raw)
  To: Jan Beulich
  Cc: kevin.tian, wei.liu2, Ian.Campbell, stefano.stabellini,
	andrew.cooper3, eddie.dong, xen-devel, jun.nakajima, keir,
	ian.jackson

On Tue, Oct 13, 2015 at 07:49:12AM -0600, Jan Beulich wrote:
> >>> On 12.10.15 at 08:07, <shuai.ruan@linux.intel.com> wrote:
> 
> > @@ -2257,9 +2261,14 @@ static int hvm_load_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
> >      v->arch.xcr0_accum = ctxt->xcr0_accum;
> >      if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
> >          v->arch.nonlazy_xstate_used = 1;
> > -    memcpy(v->arch.xsave_area, &ctxt->save_area,
> > -           min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
> > -           save_area));
> > +    if ( (cpu_has_xsaves || cpu_has_xsavec) )
> > +        compress_xsave_states(v, &ctxt->save_area,
> > +                              min(desc->length, size) -
> > +                              offsetof(struct hvm_hw_cpu_xsave,save_area));
> > +    else
> > +        memcpy(v->arch.xsave_area, &ctxt->save_area,
> > +               min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
> > +               save_area));
> 
> Each time I look at these two hunks I wonder whether the condition
> and memcpy() wouldn't better move into the new called functions.
> 
Will func name 
void load_xsave_area(struct vcpu *v, struct hvm_hw_cpu_xsave *ctxt)
void save_xsave_area(struct vcpu *v, struct hvm_hw_cpu_xsave *ctxt)
Ok ?
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
       [not found]     ` <20151015015832.GA11071@shuai.ruan@linux.intel.com>
@ 2015-10-15  6:48       ` Jan Beulich
  0 siblings, 0 replies; 13+ messages in thread
From: Jan Beulich @ 2015-10-15  6:48 UTC (permalink / raw)
  To: Shuai Ruan
  Cc: kevin.tian, wei.liu2, eddie.dong, stefano.stabellini,
	andrew.cooper3, ian.jackson, xen-devel, jun.nakajima, keir,
	Ian.Campbell

>>> On 15.10.15 at 03:58, <shuai.ruan@linux.intel.com> wrote:
> On Tue, Oct 13, 2015 at 07:49:12AM -0600, Jan Beulich wrote:
>> >>> On 12.10.15 at 08:07, <shuai.ruan@linux.intel.com> wrote:
>> 
>> > @@ -2257,9 +2261,14 @@ static int hvm_load_cpu_xsave_states(struct domain 
> *d, hvm_domain_context_t *h)
>> >      v->arch.xcr0_accum = ctxt->xcr0_accum;
>> >      if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
>> >          v->arch.nonlazy_xstate_used = 1;
>> > -    memcpy(v->arch.xsave_area, &ctxt->save_area,
>> > -           min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
>> > -           save_area));
>> > +    if ( (cpu_has_xsaves || cpu_has_xsavec) )
>> > +        compress_xsave_states(v, &ctxt->save_area,
>> > +                              min(desc->length, size) -
>> > +                              offsetof(struct 
> hvm_hw_cpu_xsave,save_area));
>> > +    else
>> > +        memcpy(v->arch.xsave_area, &ctxt->save_area,
>> > +               min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
>> > +               save_area));
>> 
>> Each time I look at these two hunks I wonder whether the condition
>> and memcpy() wouldn't better move into the new called functions.
>> 
> Will func name 
> void load_xsave_area(struct vcpu *v, struct hvm_hw_cpu_xsave *ctxt)
> void save_xsave_area(struct vcpu *v, struct hvm_hw_cpu_xsave *ctxt)
> Ok ?

Yes, or just keep the current names. (As a side note - one of the
two clearly wants its second argument constified.)

Jan

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-10-15  6:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-12  6:07 [V6 0/4] add xsaves/xrstors support Shuai Ruan
2015-10-12  6:07 ` [V6 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
2015-10-12  9:25   ` Andrew Cooper
2015-10-13 13:33   ` Jan Beulich
2015-10-12  6:07 ` [V6 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen Shuai Ruan
2015-10-12 10:05   ` Andrew Cooper
2015-10-13  7:28     ` Shuai Ruan
2015-10-13 13:49   ` Jan Beulich
2015-10-15  1:58     ` Shuai Ruan
     [not found]     ` <20151015015832.GA11071@shuai.ruan@linux.intel.com>
2015-10-15  6:48       ` Jan Beulich
2015-10-12  6:07 ` [V6 3/4] x86/xsaves: enable xsaves/xrstors for hvm guest Shuai Ruan
2015-10-12  6:07 ` [V6 4/4] libxc: expose xsaves/xgetbv1/xsavec to " Shuai Ruan
2015-10-12 10:11   ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.