x86:xsaveopt: Enable xsaveopt feature in Xen and guest
authorKeir Fraser <keir@xen.org>
Fri, 17 Dec 2010 09:25:00 +0000 (09:25 +0000)
committerKeir Fraser <keir@xen.org>
Fri, 17 Dec 2010 09:25:00 +0000 (09:25 +0000)
This patch uses "xsaveopt" instead of "xsave" if the feature is
supported in hardware to optimize task switch performance in Xen. It
also exposes the feature to guest VMs.

Signed-off-by: Zhang Fengzhe <fengzhe.zhang@intel.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/i387.c
xen/include/asm-x86/i387.h

index 9f5784216c0d451e3544a4d0121654cc963ca2bc..19c8ba0794a84104c07e34a75328ea9f91c2beb0 100644 (file)
@@ -2171,6 +2171,9 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
                 *ebx = XSTATE_YMM_OFFSET;
                 break;
             case 1:
+                if ( cpu_has_xsaveopt )
+                    *eax = XSAVEOPT;
+                break;
             default:
                 break;
             }
index 82dd88e92009554228e3889ecf69e74a1182bc63..1ddb2c7495872437892e5cde2365c1cfe8d11fb8 100644 (file)
@@ -39,7 +39,10 @@ void save_init_fpu(struct vcpu *v)
          * we set all accumulated feature mask before doing save/restore.
          */
         set_xcr0(v->arch.xcr0_accum);
-        xsave(v);
+        if ( cpu_has_xsaveopt )
+            xsaveopt(v);
+        else
+            xsave(v);
         set_xcr0(v->arch.xcr0);
     }
     else if ( cpu_has_fxsr )
@@ -152,6 +155,8 @@ u64 xfeature_mask;
 /* Cached xcr0 for fast read */
 DEFINE_PER_CPU(uint64_t, xcr0);
 
+bool_t __read_mostly cpu_has_xsaveopt;
+
 void xsave_init(void)
 {
     u32 eax, ebx, ecx, edx;
@@ -196,6 +201,10 @@ void xsave_init(void)
         xfeature_mask &= XCNTXT_MASK;
         printk("%s: using cntxt_size: 0x%x and states: 0x%"PRIx64"\n",
             __func__, xsave_cntxt_size, xfeature_mask);
+
+        /* Check XSAVEOPT feature. */
+        cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
+        cpu_has_xsaveopt = !!(eax & XSAVEOPT);
     }
     else
     {
index 0e01d1604d49d3a793a35adb32762334059e85f7..471747c7c478cdd8865abff041f71187084044b7 100644 (file)
@@ -16,6 +16,7 @@
 
 extern unsigned int xsave_cntxt_size;
 extern u64 xfeature_mask;
+extern bool_t cpu_has_xsaveopt;
 
 void xsave_init(void);
 int xsave_alloc_save_area(struct vcpu *v);
@@ -28,6 +29,7 @@ void xsave_free_save_area(struct vcpu *v);
 #define XCNTXT_MASK     (XSTATE_FP | XSTATE_SSE | XSTATE_YMM)
 #define XSTATE_YMM_OFFSET  (512 + 64)
 #define XSTATE_YMM_SIZE    256
+#define XSAVEOPT        (1 << 0)
 
 struct xsave_struct
 {
@@ -84,6 +86,18 @@ static inline void xsave(struct vcpu *v)
         : "memory");
 }
 
+static inline void xsaveopt(struct vcpu *v)
+{
+    struct xsave_struct *ptr;
+
+    ptr =(struct xsave_struct *)v->arch.xsave_area;
+
+    asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x37"
+        :
+        : "a" (-1), "d" (-1), "D"(ptr)
+        : "memory");
+}
+
 static inline void xrstor(struct vcpu *v)
 {
     struct xsave_struct *ptr;