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

[Xen-changelog] [xen-unstable] [SVM] Cleanup guest writes to EFER



# HG changeset patch
# User Travis Betak <travis.betak@xxxxxxx>
# Date 1173133271 21600
# Node ID 647fcc8f0c83a73ab10859b12839afa11b0b0273
# Parent  e4cffff8cfa7b6f3eadcce7dfd503e3c7f0e5e1d
[SVM] Cleanup guest writes to EFER
---
 xen/arch/x86/hvm/svm/svm.c |   52 +++++++++++++++++++++++++++++----------------
 1 files changed, 34 insertions(+), 18 deletions(-)

diff -r e4cffff8cfa7 -r 647fcc8f0c83 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Mar 05 16:18:10 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Mar 05 16:21:11 2007 -0600
@@ -258,15 +258,23 @@ static inline int long_mode_do_msr_write
             goto gp_fault;
         }
 
+        /* 
+         * update the VMCB's EFER with the intended value along with
+         * that crucial EFER.SVME bit =)
+         */
+        vmcb->efer = msr_content | EFER_SVME;
+
 #ifdef __x86_64__
-        /* LME: 0 -> 1 */
-        if ( (msr_content & EFER_LME) 
-             && !svm_lme_is_set(v) )
+
+        /*
+         * Check for EFER.LME transitions from 0->1 or 1->0.  Do the
+         * sanity checks and then make sure that both EFER.LME and
+         * EFER.LMA are cleared.
+         */
+        if ( (msr_content & EFER_LME) && !svm_lme_is_set(v) )
         {
-            /* 
-             * setting EFER.LME is illegal if the guest currently has
-             * enabled or CR4.PAE is not set
-             */
+            /* EFER.LME transition from 0 to 1 */
+            
             if ( svm_paging_enabled(v) ||
                  !svm_cr4_pae_is_set(v) )
             {
@@ -274,18 +282,26 @@ static inline int long_mode_do_msr_write
                          "in paging mode or PAE bit is not set\n");
                 goto gp_fault;
             }
+
+            vmcb->efer &= ~(EFER_LME | EFER_LMA);
+        }
+        else if ( !(msr_content & EFER_LME) && svm_lme_is_set(v) )
+        {
+            /* EFER.LME transistion from 1 to 0 */
             
-            v->arch.hvm_svm.cpu_shadow_efer |= EFER_LME;
-        }
-
-        /* We have already recorded that we want LME, so it will be set 
-         * next time CR0 gets updated. So we clear that bit and continue.
-         */
-        if ((msr_content ^ vmcb->efer) & EFER_LME)
-            msr_content &= ~EFER_LME;  
-        /* No update for LME/LMA since it have no effect */
-#endif
-        vmcb->efer = msr_content | EFER_SVME;
+            if ( svm_paging_enabled(v) )
+            {
+                gdprintk(XENLOG_WARNING, 
+                         "Trying to clear EFER.LME while paging enabled\n");
+                goto gp_fault;
+            }
+
+            vmcb->efer &= ~(EFER_LME | EFER_LMA);
+        }
+#endif /* __x86_64__ */
+
+        /* update the guest EFER's shadow with the intended value */
+        v->arch.hvm_svm.cpu_shadow_efer = msr_content;
         break;
 
 #ifdef __x86_64__

_______________________________________________
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®.