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: Fix PV guest CR4 handling. We should

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Fix PV guest CR4 handling. We should not leak hidden CR4 bits
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 09 Nov 2007 04:20:56 -0800
Delivery-date: Fri, 09 Nov 2007 05:30:11 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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 Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1194444944 0
# Node ID 00db9ec39831dc092cefc8bbf747ef90d19241a9
# Parent  c982fe8a9f91faffe2bf08b308bca8a6e8f6c0f0
x86: Fix PV guest CR4 handling. We should not leak hidden CR4 bits
into guest CR4 value.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/domain.c        |   23 ++++++++++++++---------
 xen/arch/x86/traps.c         |    3 ++-
 xen/include/asm-x86/domain.h |    7 +++++++
 3 files changed, 23 insertions(+), 10 deletions(-)

diff -r c982fe8a9f91 -r 00db9ec39831 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Nov 07 13:41:29 2007 +0000
+++ b/xen/arch/x86/domain.c     Wed Nov 07 14:15:44 2007 +0000
@@ -415,7 +415,8 @@ int vcpu_initialise(struct vcpu *v)
             v->arch.cr3           = __pa(idle_pg_table);
         }
 
-        v->arch.guest_context.ctrlreg[4] = mmu_cr4_features;
+        v->arch.guest_context.ctrlreg[4] =
+            real_cr4_to_pv_guest_cr4(mmu_cr4_features);
     }
 
     v->arch.perdomain_ptes =
@@ -573,17 +574,18 @@ void arch_domain_destroy(struct domain *
 
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4)
 {
-    unsigned long hv_cr4 = read_cr4(), hv_cr4_mask = ~X86_CR4_TSD;
+    unsigned long hv_cr4_mask, hv_cr4 = real_cr4_to_pv_guest_cr4(read_cr4());
+
+    hv_cr4_mask = ~X86_CR4_TSD;
     if ( cpu_has_de )
         hv_cr4_mask &= ~X86_CR4_DE;
 
-    if ( (guest_cr4 & hv_cr4_mask) !=
-         (hv_cr4 & hv_cr4_mask & ~(X86_CR4_PGE|X86_CR4_PSE)) )
+    if ( (guest_cr4 & hv_cr4_mask) != (hv_cr4 & hv_cr4_mask) )
         gdprintk(XENLOG_WARNING,
                  "Attempt to change CR4 flags %08lx -> %08lx\n",
                  hv_cr4 & ~(X86_CR4_PGE|X86_CR4_PSE), guest_cr4);
 
-    return  (hv_cr4 & hv_cr4_mask) | (guest_cr4 & ~hv_cr4_mask);
+    return (hv_cr4 & hv_cr4_mask) | (guest_cr4 & ~hv_cr4_mask);
 }
 
 /* This is called by arch_final_setup_guest and do_boot_vcpu */
@@ -684,8 +686,8 @@ int arch_set_info_guest(
     v->arch.guest_context.user_regs.eflags |= EF_IE;
 
     cr4 = v->arch.guest_context.ctrlreg[4];
-    v->arch.guest_context.ctrlreg[4] =
-        (cr4 == 0) ? mmu_cr4_features : pv_guest_cr4_fixup(cr4);
+    v->arch.guest_context.ctrlreg[4] = cr4 ? pv_guest_cr4_fixup(cr4) :
+        real_cr4_to_pv_guest_cr4(mmu_cr4_features);
 
     memset(v->arch.guest_context.debugreg, 0,
            sizeof(v->arch.guest_context.debugreg));
@@ -1223,11 +1225,14 @@ static void paravirt_ctxt_switch_from(st
 
 static void paravirt_ctxt_switch_to(struct vcpu *v)
 {
+    unsigned long cr4;
+
     set_int80_direct_trap(v);
     switch_kernel_stack(v);
 
-    if ( unlikely(read_cr4() != v->arch.guest_context.ctrlreg[4]) )
-        write_cr4(v->arch.guest_context.ctrlreg[4]);
+    cr4 = pv_guest_cr4_to_real_cr4(v->arch.guest_context.ctrlreg[4]);
+    if ( unlikely(cr4 != read_cr4()) )
+        write_cr4(cr4);
 
     if ( unlikely(v->arch.guest_context.debugreg[7]) )
     {
diff -r c982fe8a9f91 -r 00db9ec39831 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Nov 07 13:41:29 2007 +0000
+++ b/xen/arch/x86/traps.c      Wed Nov 07 14:15:44 2007 +0000
@@ -1797,7 +1797,8 @@ static int emulate_privileged_op(struct 
 
         case 4: /* Write CR4 */
             v->arch.guest_context.ctrlreg[4] = pv_guest_cr4_fixup(*reg);
-            write_cr4(v->arch.guest_context.ctrlreg[4]);
+            write_cr4(pv_guest_cr4_to_real_cr4(
+                v->arch.guest_context.ctrlreg[4]));
             break;
 
         default:
diff -r c982fe8a9f91 -r 00db9ec39831 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Nov 07 13:41:29 2007 +0000
+++ b/xen/include/asm-x86/domain.h      Wed Nov 07 14:15:44 2007 +0000
@@ -350,7 +350,14 @@ struct arch_vcpu
 /* Continue the current hypercall via func(data) on specified cpu. */
 int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data);
 
+/* Clean up CR4 bits that are not under guest control. */
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4);
+
+/* Convert between guest-visible and real CR4 values. */
+#define pv_guest_cr4_to_real_cr4(c) \
+    ((c) | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE)))
+#define real_cr4_to_pv_guest_cr4(c) \
+    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE))
 
 #endif /* __ASM_DOMAIN_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: Fix PV guest CR4 handling. We should not leak hidden CR4 bits, Xen patchbot-unstable <=