Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 5803

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Michal Novotny <minovotn@redhat.com>
Date: Thu, 19 Aug 2010 12:28:36 -0400
Subject: [xen] vmx: fix handling of FS/GS base MSRs
Message-id: <1282220916-6537-1-git-send-email-minovotn@redhat.com>
Patchwork-id: 27717
O-Subject: [RHEL 5.6 Xen PATCH] vmx: Fix handling of FS/GS base MSRs
Bugzilla: 613187
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Andrew Jones <drjones@redhat.com>

Bugzilla: 613187

Upstream: xen-unstable.hg c/s 19953

Brew build: https://brewweb.devel.redhat.com/taskinfo?taskID=2589194

This is the patch for FS/GS base MSRs implementation in vmx.c for x86
CPUs to make Cygwin bash not crash on Intel CPUs.  It's the backport of
xen-unstable.hg c/s 19953.

Tested by me.

Michal
---
 arch/x86/hvm/vmx/vmx.c |   23 +++++++----------------
 1 files changed, 7 insertions(+), 16 deletions(-)

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/arch/x86/hvm/vmx/vmx.c b/arch/x86/hvm/vmx/vmx.c
index d5b6002..09d2ff9 100644
--- a/arch/x86/hvm/vmx/vmx.c
+++ b/arch/x86/hvm/vmx/vmx.c
@@ -190,20 +190,14 @@ static int long_mode_do_msr_read(struct cpu_user_regs *regs)
 
     case MSR_FS_BASE:
         msr_content = __vmread(GUEST_FS_BASE);
-        goto check_long_mode;
+        break;
 
     case MSR_GS_BASE:
         msr_content = __vmread(GUEST_GS_BASE);
-        goto check_long_mode;
+        break;
 
     case MSR_SHADOW_GS_BASE:
-        msr_content = v->arch.hvm_vmx.shadow_gs;
-    check_long_mode:
-        if ( !(vmx_long_mode_enabled(v)) )
-        {
-            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
-            return 0;
-        }
+        rdmsrl(MSR_SHADOW_GS_BASE, msr_content);
         break;
 
     case MSR_STAR:
@@ -288,9 +282,6 @@ static int long_mode_do_msr_write(struct cpu_user_regs *regs)
     case MSR_FS_BASE:
     case MSR_GS_BASE:
     case MSR_SHADOW_GS_BASE:
-        if ( !vmx_long_mode_enabled(v) )
-            goto gp_fault;
-
         if ( !is_canonical_address(msr_content) )
             goto uncanonical_address;
 
@@ -299,10 +290,7 @@ static int long_mode_do_msr_write(struct cpu_user_regs *regs)
         else if ( ecx == MSR_GS_BASE )
             __vmwrite(GUEST_GS_BASE, msr_content);
         else
-        {
-            v->arch.hvm_vmx.shadow_gs = msr_content;
             wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
-        }
 
         break;
 
@@ -360,7 +348,10 @@ static void vmx_restore_host_msrs(void)
 
 static void vmx_save_guest_msrs(struct vcpu *v)
 {
-    /* MSR_SHADOW_GS_BASE may have been changed by swapgs instruction. */
+    /*
+     * We cannot cache SHADOW_GS_BASE while the VCPU runs, as it can
+     * be updated at any time via SWAPGS, which we cannot trap.
+     */
     rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
 }