[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Clarify lazy FPU management in VMX domains.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 70024ebbdf55585230fa7656ea79ecb2960779c5
# Parent  39b392a220025993cfb9dfa6ae5554ac3c88a340
Clarify lazy FPU management in VMX domains.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 39b392a22002 -r 70024ebbdf55 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 14 18:43:45 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 14 19:17:26 2006
@@ -617,12 +617,17 @@
 
     clts();
     setup_fpu(current);
+
+    /* Disable TS in guest CR0 unless the guest wants the exception too. */
     __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
-    if (!(cr0 & X86_CR0_TS)) {
+    if ( !(cr0 & X86_CR0_TS) )
+    {
         __vmread_vcpu(v, GUEST_CR0, &cr0);
         cr0 &= ~X86_CR0_TS;
         __vmwrite(GUEST_CR0, cr0);
     }
+
+    /* Xen itself doesn't need another exception. */
     __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 }
 
@@ -1152,13 +1157,16 @@
      */
     __vmread_vcpu(v, CR0_READ_SHADOW, &old_cr0);
     paging_enabled = (old_cr0 & X86_CR0_PE) && (old_cr0 & X86_CR0_PG);
-    /* If OS don't use clts to clear TS bit...*/
-    if((old_cr0 & X86_CR0_TS) && !(value & X86_CR0_TS))
+
+    /*
+     * Disable TS? Then we do so at the same time, and initialise FPU.
+     * This avoids needing another vmexit.
+     */
+    if ( (old_cr0 & ~value & X86_CR0_TS) != 0 )
     {
-            clts();
-            setup_fpu(v);
-    }
-
+        clts();
+        setup_fpu(v);
+    }
 
     __vmwrite(GUEST_CR0, value | X86_CR0_PE | X86_CR0_PG | X86_CR0_NE);
     __vmwrite(CR0_READ_SHADOW, value);
@@ -1510,6 +1518,8 @@
         break;
     case TYPE_CLTS:
         TRACE_VMEXIT(1,TYPE_CLTS);
+
+        /* We initialise the FPU now, to avoid needing another vmexit. */
         clts();
         setup_fpu(current);
 
diff -r 39b392a22002 -r 70024ebbdf55 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Tue Feb 14 18:43:45 2006
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Tue Feb 14 19:17:26 2006
@@ -382,14 +382,22 @@
     unsigned long cr0;
     struct vcpu *v = current;
 
-    __vmread_vcpu(v, GUEST_CR0, &cr0);
-    if (!(cr0 & X86_CR0_TS)) {
+    /* FPU state already dirty? Then no need to setup_fpu() lazily. */
+    if ( test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
+        return;
+
+    /*
+     * If the guest does not have TS enabled then we must cause and handle an 
+     * exception on first use of the FPU. If the guest *does* have TS enabled 
+     * then this is not necessary: no FPU activity can occur until the guest 
+     * clears CR0.TS, and we will initialise the FPU when that happens.
+     */
+    __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
+    if ( !(cr0 & X86_CR0_TS) )
+    {
         __vmwrite(GUEST_CR0, cr0 | X86_CR0_TS);
-    }
-
-    __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
-    if (!(cr0 & X86_CR0_TS))
-       __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
+        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
+    }
 }
 
 /* Works only for vcpu == current */

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.