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-devel

[Xen-devel] [PATCH 10/24] xen: mask XSAVE from cpuid

To: "H. Peter Anvin" <hpa@xxxxxxxxx>
Subject: [Xen-devel] [PATCH 10/24] xen: mask XSAVE from cpuid
From: Jeremy Fitzhardinge <jeremy@xxxxxxxx>
Date: Fri, 13 Mar 2009 01:11:46 -0700
Cc: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>, the arch/x86 maintainers <x86@xxxxxxxxxx>, Linux Kernel Mailing List <linux-kernel@xxxxxxxxxxxxxxx>, Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
Delivery-date: Fri, 13 Mar 2009 01:20:18 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1236931920-6861-1-git-send-email-jeremy@xxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1236931920-6861-1-git-send-email-jeremy@xxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>

Xen leaves XSAVE set in cpuid, but doesn't allow cr4.OSXSAVE
to be set.  This confuses the kernel and it ends up crashing on
an xsetbv instruction.

At boot time, try to set cr4.OSXSAVE, and mask XSAVE out of
cpuid it we can't.  This will produce a spurious error from Xen,
but allows us to support XSAVE if/when Xen does.

This also factors out the cpuid mask decisions to boot time.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
---
 arch/x86/xen/enlighten.c |   50 ++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 75b7a0f..da33e0c 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -168,21 +168,23 @@ static void __init xen_banner(void)
               xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " 
(preserve-AD)" : "");
 }
 
+static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0;
+static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
+
 static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                      unsigned int *cx, unsigned int *dx)
 {
+       unsigned maskecx = ~0;
        unsigned maskedx = ~0;
 
        /*
         * Mask out inconvenient features, to try and disable as many
         * unsupported kernel subsystems as possible.
         */
-       if (*ax == 1)
-               maskedx = ~((1 << X86_FEATURE_APIC) |  /* disable APIC */
-                           (1 << X86_FEATURE_ACPI) |  /* disable ACPI */
-                           (1 << X86_FEATURE_MCE)  |  /* disable MCE */
-                           (1 << X86_FEATURE_MCA)  |  /* disable MCA */
-                           (1 << X86_FEATURE_ACC));   /* thermal monitoring */
+       if (*ax == 1) {
+               maskecx = cpuid_leaf1_ecx_mask;
+               maskedx = cpuid_leaf1_edx_mask;
+       }
 
        asm(XEN_EMULATE_PREFIX "cpuid"
                : "=a" (*ax),
@@ -190,9 +192,43 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                  "=c" (*cx),
                  "=d" (*dx)
                : "0" (*ax), "2" (*cx));
+
+       *cx &= maskecx;
        *dx &= maskedx;
 }
 
+static __init void xen_init_cpuid_mask(void)
+{
+       unsigned int ax, bx, cx, dx;
+
+       cpuid_leaf1_edx_mask =
+               ~((1 << X86_FEATURE_MCE)  |  /* disable MCE */
+                 (1 << X86_FEATURE_MCA)  |  /* disable MCA */
+                 (1 << X86_FEATURE_ACC));   /* thermal monitoring */
+
+       if (!xen_initial_domain())
+               cpuid_leaf1_edx_mask &=
+                       ~((1 << X86_FEATURE_APIC) |  /* disable local APIC */
+                         (1 << X86_FEATURE_ACPI));  /* disable ACPI */
+
+       ax = 1;
+       xen_cpuid(&ax, &bx, &cx, &dx);
+
+       /* cpuid claims we support xsave; try enabling it to see what happens */
+       if (cx & (1 << (X86_FEATURE_XSAVE % 32))) {
+               unsigned long cr4;
+
+               set_in_cr4(X86_CR4_OSXSAVE);
+               
+               cr4 = read_cr4();
+
+               if ((cr4 & X86_CR4_OSXSAVE) == 0)
+                       cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 
32));
+
+               clear_in_cr4(X86_CR4_OSXSAVE);
+       }
+}
+
 static void xen_set_debugreg(int reg, unsigned long val)
 {
        HYPERVISOR_set_debugreg(reg, val);
@@ -901,6 +937,8 @@ asmlinkage void __init xen_start_kernel(void)
 
        xen_init_irq_ops();
 
+       xen_init_cpuid_mask();
+
 #ifdef CONFIG_X86_LOCAL_APIC
        /*
         * set up the basic apic ops.
-- 
1.6.0.6


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

<Prev in Thread] Current Thread [Next in Thread>