From patchwork Fri Jun 15 09:54:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Bader X-Patchwork-Id: 165076 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 3DF4CB706F for ; Fri, 15 Jun 2012 19:55:18 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SfTF9-0005b3-64; Fri, 15 Jun 2012 09:55:03 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SfTF6-0005an-MO for kernel-team@lists.ubuntu.com; Fri, 15 Jun 2012 09:55:00 +0000 Received: from p5b2e29a5.dip.t-dialin.net ([91.46.41.165] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1SfTF6-0006CA-DD for kernel-team@lists.ubuntu.com; Fri, 15 Jun 2012 09:55:00 +0000 From: Stefan Bader To: kernel-team@lists.ubuntu.com Subject: [RFC Quantal] Replace pv-ops fix for legacy Xen [v2] Date: Fri, 15 Jun 2012 11:54:59 +0200 Message-Id: <1339754099-12023-1-git-send-email-stefan.bader@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <4FDA3634.1030007@canonical.com> References: <4FDA3634.1030007@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com > Just a nit, how about making the version check a documented macro > instead of open coding '(version >> 16) < 4)' twice ? You know, I was already wondering about that just after sending out the initial version. So how about that? Just using an inline function instead of a macro. Not sure why, but I find inline a bit more attractive. Should not make much difference... -Stefan From 590ef72644debfb8c910eda68f5264610d128f74 Mon Sep 17 00:00:00 2001 From: Stefan Bader Date: Mon, 4 Jun 2012 19:12:51 +0200 Subject: [PATCH] UBUNTU: SAUCE: Mask CR4 writes on older Xen hypervisors Older Xen hypervisors (like RHEL5 versions found to be used on Amazon's EC2) did have a bug which would crash the domain when trying to write unsupported CR4 values. Newer versions do handle this correctly. But some probes (in particular one that tries to pass the OSXSAVE bit set) were causing pv-ops kernels to crash early on boot when running on EC2. We were using a patch that did always filter the OSXSAVE off the values written to CR4 when running as Xen PV guest. While not completely wrong this creates an inconsistency between the cpuid bits a guest sees and the CR4 settings. And this did recently cause problems because user-space was not testing all bits when deciding to use certain features. This patch will actually mask off the cpuid bits for XSAVE and OSXSAVE, so generic code will not even try to set CR4. It is limited to PV guests and (since we do not actually know the exact version) Xen hypervisors before version 4. [v2: make the version check an inline function] Signed-off-by: Stefan Bader --- arch/x86/xen/enlighten.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e74df95..d465026 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -196,6 +196,18 @@ void xen_vcpu_restore(void) } } +/* + * Older (with no clear statement about what old means) Xen hypervisors + * will crash a PV guest that tries to store OSXSAVE into CR4. + * To prevent this, we force the feature bits related to this off in the + * xen cpuid call. This inline function serves as a centralized test + * on whether the quirk should be done. + */ +static inline needs_xsave_quirk(unsigned version) +{ + return (xen_pv_domain() && ((version >> 16) < 4)) ? 1 : 0; +} + static void __init xen_banner(void) { unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL); @@ -207,6 +219,8 @@ static void __init xen_banner(void) printk(KERN_INFO "Xen version: %d.%d%s%s\n", version >> 16, version & 0xffff, extra.extraversion, xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); + if (needs_xsave_quirk(version)) + printk(KERN_INFO "Forcing xsave off due to Xen version.\n"); } static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; @@ -329,6 +343,7 @@ static bool __init xen_check_mwait(void) } static void __init xen_init_cpuid_mask(void) { + unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL); unsigned int ax, bx, cx, dx; unsigned int xsave_mask; @@ -351,7 +366,7 @@ static void __init xen_init_cpuid_mask(void) (1 << (X86_FEATURE_OSXSAVE % 32)); /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ - if ((cx & xsave_mask) != xsave_mask) + if (((cx & xsave_mask) != xsave_mask) || needs_xsave_quirk(version)) cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ if (xen_check_mwait()) cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32));