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] [xen-unstable] x86 svm: Make 32bit legacy guests boot ag

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 svm: Make 32bit legacy guests boot again
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 29 Jun 2009 02:20:25 -0700
Delivery-date: Mon, 29 Jun 2009 02:22:05 -0700
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/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1246095213 -3600
# Node ID 49ae55a9c4429ea2ee34e7e723b99f7ad024a7b7
# Parent  43523102a8e9093acef4be9da8ec4ff4928ccea8
x86 svm: Make 32bit legacy guests boot again

Attached patch fixes a bug introduced in c/s 19648.

32bit legacy guests have the sysenter/sysexit instructions available.
Therefore, we have to disable intercepts for the sysenter MSRs or the
guest stucks in an infinite loop of #GPs, otherwise.

For guests in 64bit mode and 32bit compat mode, sysenter/sysexit
instructions aren't available. The sysenter MSRs have to be
intercepted to make the instruction emulation working.

Signed-off-by: Christoph Egger <Christoph.Egger@xxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c         |   11 +++++++++-
 xen/arch/x86/hvm/svm/vmcb.c        |   40 +++++++++++++++++++++----------------
 xen/include/asm-x86/hvm/svm/vmcb.h |    4 ++-
 3 files changed, 36 insertions(+), 19 deletions(-)

diff -r 43523102a8e9 -r 49ae55a9c442 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Sat Jun 27 10:02:52 2009 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Sat Jun 27 10:33:33 2009 +0100
@@ -452,10 +452,19 @@ static void svm_update_guest_efer(struct
 static void svm_update_guest_efer(struct vcpu *v)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    bool_t lma = v->arch.hvm_vcpu.guest_efer & EFER_LMA;
 
     vmcb->efer = (v->arch.hvm_vcpu.guest_efer | EFER_SVME) & ~EFER_LME;
-    if ( vmcb->efer & EFER_LMA )
+    if ( lma )
         vmcb->efer |= EFER_LME;
+
+    /*
+     * In legacy mode (EFER.LMA=0) we natively support SYSENTER/SYSEXIT with
+     * no need for MSR intercepts. Ehen EFER.LMA=1 we must trap and emulate.
+     */
+    svm_intercept_msr(v, MSR_IA32_SYSENTER_CS, lma);
+    svm_intercept_msr(v, MSR_IA32_SYSENTER_ESP, lma);
+    svm_intercept_msr(v, MSR_IA32_SYSENTER_EIP, lma);
 }
 
 static void svm_flush_guest_tlbs(void)
diff -r 43523102a8e9 -r 49ae55a9c442 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Sat Jun 27 10:02:52 2009 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Sat Jun 27 10:33:33 2009 +0100
@@ -78,29 +78,34 @@ struct host_save_area *alloc_host_save_a
     return hsa;
 }
 
-void svm_disable_intercept_for_msr(struct vcpu *v, u32 msr)
+void svm_intercept_msr(struct vcpu *v, uint32_t msr, int enable)
 {
     unsigned long *msr_bitmap = v->arch.hvm_svm.msrpm;
+    unsigned long *msr_bit = NULL;
 
     /*
      * See AMD64 Programmers Manual, Vol 2, Section 15.10 (MSR-Bitmap Address).
      */
     if ( msr <= 0x1fff )
-    {
-        __clear_bit(msr*2, msr_bitmap + 0x000/BYTES_PER_LONG); 
-        __clear_bit(msr*2+1, msr_bitmap + 0x000/BYTES_PER_LONG); 
-    }
+        msr_bit = msr_bitmap + 0x0000 / BYTES_PER_LONG;
     else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
-    {
-        msr &= 0x1fff;
-        __clear_bit(msr*2, msr_bitmap + 0x800/BYTES_PER_LONG);
-        __clear_bit(msr*2+1, msr_bitmap + 0x800/BYTES_PER_LONG);
-    } 
-    else if ( (msr >= 0xc001000) && (msr <= 0xc0011fff) )
-    {
-        msr &= 0x1fff;
-        __clear_bit(msr*2, msr_bitmap + 0x1000/BYTES_PER_LONG);
-        __clear_bit(msr*2+1, msr_bitmap + 0x1000/BYTES_PER_LONG);
+        msr_bit = msr_bitmap + 0x0800 / BYTES_PER_LONG;
+    else if ( (msr >= 0xc0010000) && (msr <= 0xc0011fff) )
+        msr_bit = msr_bitmap + 0x1000 / BYTES_PER_LONG;
+
+    BUG_ON(msr_bit == NULL);
+
+    msr &= 0x1fff;
+
+    if ( enable )
+    {
+        __set_bit(msr * 2, msr_bit);
+        __set_bit(msr * 2 + 1, msr_bit);
+    }
+    else
+    {
+        __clear_bit(msr * 2, msr_bit);
+        __clear_bit(msr * 2 + 1, msr_bit);
     }
 }
 
@@ -165,8 +170,9 @@ static int construct_vmcb(struct vcpu *v
     if ( opt_softtsc )
         vmcb->general1_intercepts |= GENERAL1_INTERCEPT_RDTSC;
 
-    /* Guest EFER: *must* contain SVME or VMRUN will fail. */
-    vmcb->efer = EFER_SVME;
+    /* Guest EFER. */
+    v->arch.hvm_vcpu.guest_efer = 0;
+    hvm_update_guest_efer(v);
 
     /* Guest segment limits. */
     vmcb->cs.limit = ~0u;
diff -r 43523102a8e9 -r 49ae55a9c442 xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h        Sat Jun 27 10:02:52 2009 +0100
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h        Sat Jun 27 10:33:33 2009 +0100
@@ -481,7 +481,9 @@ void svm_destroy_vmcb(struct vcpu *v);
 
 void setup_vmcb_dump(void);
 
-void svm_disable_intercept_for_msr(struct vcpu *v, u32 msr);
+void svm_intercept_msr(struct vcpu *v, uint32_t msr, int enable);
+#define svm_disable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), 0)
+#define svm_enable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), 1)
 
 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 svm: Make 32bit legacy guests boot again, Xen patchbot-unstable <=