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] More fixes to HVM FPU management. Mostly for SVM, but al

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] More fixes to HVM FPU management. Mostly for SVM, but also
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 15 Feb 2006 13:14:11 +0000
Delivery-date: Wed, 15 Feb 2006 13:27:33 +0000
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 7d89f672aa49b0240bff86ad56992c888e4eca54
# Parent  ee6f025fb264214047b152e5583d4d5da03a1c22
More fixes to HVM FPU management. Mostly for SVM, but also
fix VMX mov_to_cr0: must setup_fpu() if the new cr0 value
has TS clear, regardless of previous cr0.TS value.

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

diff -r ee6f025fb264 -r 7d89f672aa49 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Feb 14 22:30:59 2006
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Feb 14 23:15:11 2006
@@ -701,12 +701,21 @@
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
-    ASSERT(vmcb);    
-
-    vmcb->cr0 |= X86_CR0_TS;
-
-    if (!(v->arch.hvm_svm.cpu_shadow_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.
+     */
+    if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
+    {
         v->arch.hvm_svm.vmcb->exception_intercepts |= EXCEPTION_BITMAP_NM;
+        vmcb->cr0 |= X86_CR0_TS;
+    }
 }
 
 static void arch_svm_do_launch(struct vcpu *v) 
@@ -884,14 +893,11 @@
 {
     struct vcpu *v = current;
 
-    clts();
-
     setup_fpu(v);    
-
-    if (!(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS))
+    vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
+
+    if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
         vmcb->cr0 &= ~X86_CR0_TS;
-    
-    vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
 }
 
 
@@ -1350,10 +1356,11 @@
     vmcb->cr0 = value | X86_CR0_PG;
     v->arch.hvm_svm.cpu_shadow_cr0 = value;
 
-    /* Check if FP Unit Trap need to be on */
-    if (value & X86_CR0_TS)
-    { 
-       vmcb->exception_intercepts |= EXCEPTION_BITMAP_NM;
+    /* TS cleared? Then initialise FPU now. */
+    if ( !(value & X86_CR0_TS) )
+    {
+        setup_fpu(v);
+        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
     }
 
     HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
@@ -1669,11 +1676,11 @@
         break;
 
     case INSTR_CLTS:
-        clts();
+        /* TS being cleared means that it's time to restore fpu state. */
         setup_fpu(current);
+        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
         vmcb->cr0 &= ~X86_CR0_TS; /* clear TS */
         v->arch.hvm_svm.cpu_shadow_cr0 &= ~X86_CR0_TS; /* clear TS */
-        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
         break;
 
     case INSTR_LMSW:
@@ -1803,11 +1810,8 @@
     struct vcpu *v = current;
     struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
     s_time_t  next_pit = -1, next_wakeup;
-    unsigned int inst_len;
-
-    svm_stts(v);
-    inst_len = __get_instruction_length(vmcb, INSTR_HLT, NULL);
-    __update_guest_eip(vmcb, inst_len);
+
+    __update_guest_eip(vmcb, 1);
 
     if ( !v->vcpu_id )
         next_pit = get_pit_scheduled(v, vpit);
@@ -1822,7 +1826,6 @@
 
 static inline void svm_vmexit_do_mwait(void)
 {
-    return;
 }
 
 
@@ -2494,7 +2497,6 @@
         break;
 
     case VMEXIT_INTR:
-        svm_stts(v);
         raise_softirq(SCHEDULE_SOFTIRQ);
         break;
 
diff -r ee6f025fb264 -r 7d89f672aa49 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Tue Feb 14 22:30:59 2006
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Tue Feb 14 23:15:11 2006
@@ -489,7 +489,9 @@
 {
     struct domain *d = v->domain;
     struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit;
-    
+
+    svm_stts(v);
+
     if ( test_bit(iopacket_port(d), &d->shared_info->evtchn_pending[0]) ||
          test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
         hvm_wait_io();
@@ -498,7 +500,7 @@
     if ( vpit->first_injected )
         pickup_deactive_ticks(vpit);
     svm_set_tsc_shift(v, vpit);
-    
+
     /* We can't resume the guest if we're waiting on I/O */
     ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
 }
diff -r ee6f025fb264 -r 7d89f672aa49 xen/arch/x86/hvm/svm/x86_32/exits.S
--- a/xen/arch/x86/hvm/svm/x86_32/exits.S       Tue Feb 14 22:30:59 2006
+++ b/xen/arch/x86/hvm/svm/x86_32/exits.S       Tue Feb 14 23:15:11 2006
@@ -89,7 +89,7 @@
 #define CLGI   .byte 0x0F,0x01,0xDD
 
 #define DO_TSC_OFFSET 0
-#define DO_FPUSAVE    1
+#define DO_FPUSAVE    0
         
 ENTRY(svm_asm_do_launch)
         sti
diff -r ee6f025fb264 -r 7d89f672aa49 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 14 22:30:59 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 14 23:15:11 2006
@@ -615,8 +615,8 @@
     unsigned long cr0;
     struct vcpu *v = current;
 
-    clts();
     setup_fpu(current);
+    __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 
     /* Disable TS in guest CR0 unless the guest wants the exception too. */
     __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
@@ -626,9 +626,6 @@
         cr0 &= ~X86_CR0_TS;
         __vmwrite(GUEST_CR0, cr0);
     }
-
-    /* Xen itself doesn't need another exception. */
-    __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 }
 
 /* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */
@@ -1158,14 +1155,11 @@
     __vmread_vcpu(v, CR0_READ_SHADOW, &old_cr0);
     paging_enabled = (old_cr0 & X86_CR0_PE) && (old_cr0 & X86_CR0_PG);
 
-    /*
-     * 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 )
+    /* TS cleared? Then initialise FPU now. */
+    if ( !(value & X86_CR0_TS) )
     {
-        clts();
         setup_fpu(v);
+        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
     }
 
     __vmwrite(GUEST_CR0, value | X86_CR0_PE | X86_CR0_PG | X86_CR0_NE);
@@ -1520,8 +1514,8 @@
         TRACE_VMEXIT(1,TYPE_CLTS);
 
         /* We initialise the FPU now, to avoid needing another vmexit. */
-        clts();
-        setup_fpu(current);
+        setup_fpu(v);
+        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 
         __vmread_vcpu(v, GUEST_CR0, &value);
         value &= ~X86_CR0_TS; /* clear TS */
diff -r ee6f025fb264 -r 7d89f672aa49 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Feb 14 22:30:59 2006
+++ b/xen/arch/x86/traps.c      Tue Feb 14 23:15:11 2006
@@ -1261,9 +1261,6 @@
     struct trap_bounce *tb;
     struct trap_info *ti;
 
-    /* Prevent recursion. */
-    clts();
-
     setup_fpu(current);
 
     if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS )
diff -r ee6f025fb264 -r 7d89f672aa49 xen/include/asm-x86/i387.h
--- a/xen/include/asm-x86/i387.h        Tue Feb 14 22:30:59 2006
+++ b/xen/include/asm-x86/i387.h        Tue Feb 14 23:15:11 2006
@@ -33,6 +33,7 @@
 {
     if ( !test_and_set_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
     {
+        clts();
         if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
             restore_fpu(v);
         else

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] More fixes to HVM FPU management. Mostly for SVM, but also, Xen patchbot -unstable <=