From patchwork Fri Apr 8 20:31:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 8786261 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9C5C59FBEA for ; Fri, 8 Apr 2016 21:01:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 97AE8201CD for ; Fri, 8 Apr 2016 21:01:14 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 67678202EC for ; Fri, 8 Apr 2016 21:01:13 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aodUT-0002OM-LM; Fri, 08 Apr 2016 20:58:53 +0000 Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aodUS-0002NB-Py for xen-devel@lists.xen.org; Fri, 08 Apr 2016 20:58:52 +0000 Received: from [85.158.143.35] by server-3.bemta-6.messagelabs.com id D0/4E-07120-A8B18075; Fri, 08 Apr 2016 20:58:50 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuphkeJIrShJLcpLzFFi42JxWrohUrdLmiP c4NkyfoslHxezODB6HN39mymAMYo1My8pvyKBNaN17iKmgl0GFe8WlzYwrtHoYuTkkBDwl7i4 YxEriM0moC+x+8UnJhBbREBd4nTHRaA4BwezgK7Eqp8aIKawQIrEl35VkAoWARWJ3gunwTp5B bwkfk34zg4xUU7i/PGfzCA2J1D8zLYzYDVCAp4Sl2fOZ4Gw1SSu9V9ih+gVlDg58wlYnFlAQu LgixfMIKskBLgl/nbbT2Dkm4WkahaSqgWMTKsY1YtTi8pSi3SN9ZKKMtMzSnITM3N0DQ3M9HJ Ti4sT01NzEpOK9ZLzczcxAkOJAQh2MHb8czrEKMnBpCTKu+0he7gQX1J+SmVGYnFGfFFpTmrx IUYZDg4lCd6pUhzhQoJFqempFWmZOcCghklLcPAoifCWg6R5iwsSc4sz0yFSpxgVpcR5q0ESA iCJjNI8uDZYJF1ilJUS5mUEOkSIpyC1KDezBFX+FaM4B6OSMG8hyBSezLwSuOmvgBYzAS2+wM 8GsrgkESEl1cAYYvyFdfX5eW+31wjvTvpq3T1hSqoej9zJ7o4XLw0zGf/vOTKtSOWiRzDvSQc BvYMt0U//dYtOnx92cnVMYR/r70nHzAqmnHng3x25ltv0z8Rli9bP0V8jdlbMpbTBk6FJYqN+ ynou6e78F3qRwfOKdy179Xz5e76XN2pe2rfJ3+PZc9104aQ8JZbijERDLeai4kQANmrv3p8CA AA= X-Env-Sender: prvs=8997c7931=Andrew.Cooper3@citrix.com X-Msg-Ref: server-5.tower-21.messagelabs.com!1460149123!8343370!2 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.28; banners=-,-,- X-VirusChecked: Checked Received: (qmail 61310 invoked from network); 8 Apr 2016 20:58:49 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-5.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 8 Apr 2016 20:58:49 -0000 X-IronPort-AV: E=Sophos;i="5.24,454,1454976000"; d="scan'208";a="345898940" From: Andrew Cooper To: Xen-devel Date: Fri, 8 Apr 2016 21:31:47 +0100 Message-ID: <1460147517-11706-12-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1460147517-11706-1-git-send-email-andrew.cooper3@citrix.com> References: <1460147517-11706-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-DLP: MIA1 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH v6 11/21] x86/cpu: Context switch cpuid masks and faulting state in context_switch() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A single ctxt_switch_levelling() function pointer is provided (defaulting to an empty nop), which is overridden in the appropriate $VENDOR_init_levelling(). set_cpuid_faulting() is made private and included within intel_ctxt_switch_levelling(). One (attempted) functional change is that the faulting configuration should not be special cased for dom0. It turns out that the toolstack relies on the special case (and indeed, on being a PV domain in the first place) to correctly build HVM domains. For now, the control domain is left as a special case, until futher work can be completed to remove the restriction. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Reviewed-by: Konrad Rzeszutek Wilk --- v3: * Don't leave cpuid masking/faulting active for the kexec kernel. v2: * Style fixes. * ASSERT() that faulting is available in set_cpuid_faulting(). v5: * Fix the building of HVM domains from hardware with faulting available. --- xen/arch/x86/cpu/amd.c | 3 +++ xen/arch/x86/cpu/common.c | 7 +++++++ xen/arch/x86/cpu/intel.c | 37 ++++++++++++++++++++++++++++++++----- xen/arch/x86/crash.c | 3 +++ xen/arch/x86/domain.c | 4 +--- xen/include/asm-x86/processor.h | 2 +- 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 93a8a5e..3e2f4a8 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -331,6 +331,9 @@ static void __init noinline amd_init_levelling(void) (uint32_t)cpuidmask_defaults._7ab0, (uint32_t)cpuidmask_defaults._6c); } + + if (levelling_caps) + ctxt_switch_levelling = amd_ctxt_switch_levelling; } /* diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 7ef75b0..fe6eab4 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -88,6 +88,13 @@ static const struct cpu_dev default_cpu = { }; static const struct cpu_dev *this_cpu = &default_cpu; +static void default_ctxt_switch_levelling(const struct domain *nextd) +{ + /* Nop */ +} +void (* __read_mostly ctxt_switch_levelling)(const struct domain *nextd) = + default_ctxt_switch_levelling; + bool_t opt_cpu_info; boolean_param("cpuinfo", opt_cpu_info); diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c index 6e1fbbb..e21c32d 100644 --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -32,13 +32,15 @@ static bool_t __init probe_intel_cpuid_faulting(void) return 1; } -static DEFINE_PER_CPU(bool_t, cpuid_faulting_enabled); -void set_cpuid_faulting(bool_t enable) +static void set_cpuid_faulting(bool_t enable) { + static DEFINE_PER_CPU(bool_t, cpuid_faulting_enabled); + bool_t *this_enabled = &this_cpu(cpuid_faulting_enabled); uint32_t hi, lo; - if (!cpu_has_cpuid_faulting || - this_cpu(cpuid_faulting_enabled) == enable ) + ASSERT(cpu_has_cpuid_faulting); + + if (*this_enabled == enable) return; rdmsr(MSR_INTEL_MISC_FEATURES_ENABLES, lo, hi); @@ -47,7 +49,7 @@ void set_cpuid_faulting(bool_t enable) lo |= MSR_MISC_FEATURES_CPUID_FAULTING; wrmsr(MSR_INTEL_MISC_FEATURES_ENABLES, lo, hi); - this_cpu(cpuid_faulting_enabled) = enable; + *this_enabled = enable; } /* @@ -154,6 +156,28 @@ static void intel_ctxt_switch_levelling(const struct domain *nextd) struct cpuidmasks *these_masks = &this_cpu(cpuidmasks); const struct cpuidmasks *masks = &cpuidmask_defaults; + if (cpu_has_cpuid_faulting) { + /* + * We *should* be enabling faulting for the control domain. + * + * Unfortunately, the domain builder (having only ever been a + * PV guest) expects to be able to see host cpuid state in a + * native CPUID instruction, to correctly build a CPUID policy + * for HVM guests (notably the xstate leaves). + * + * This logic is fundimentally broken for HVM toolstack + * domains, and faulting causes PV guests to behave like HVM + * guests from their point of view. + * + * Future development plans will move responsibility for + * generating the maximum full cpuid policy into Xen, at which + * this problem will disappear. + */ + set_cpuid_faulting(nextd && is_pv_domain(nextd) && + !is_control_domain(nextd)); + return; + } + #define LAZY(msr, field) \ ({ \ if (unlikely(these_masks->field != masks->field) && \ @@ -227,6 +251,9 @@ static void __init noinline intel_init_levelling(void) (uint32_t)cpuidmask_defaults.e1cd, (uint32_t)cpuidmask_defaults.Da1); } + + if (levelling_caps) + ctxt_switch_levelling = intel_ctxt_switch_levelling; } static void early_init_intel(struct cpuinfo_x86 *c) diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c index 888a214..f28f527 100644 --- a/xen/arch/x86/crash.c +++ b/xen/arch/x86/crash.c @@ -189,6 +189,9 @@ void machine_crash_shutdown(void) nmi_shootdown_cpus(); + /* Reset CPUID masking and faulting to the host's default. */ + ctxt_switch_levelling(NULL); + info = kexec_crash_save_info(); info->xen_phys_start = xen_phys_start; info->dom0_pfn_to_mfn_frame_list_list = diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index a4f6db2..cba77a2 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -2082,9 +2082,7 @@ void context_switch(struct vcpu *prev, struct vcpu *next) load_segments(next); } - set_cpuid_faulting(is_pv_domain(nextd) && - !is_control_domain(nextd) && - !is_hardware_domain(nextd)); + ctxt_switch_levelling(nextd); } context_saved(prev); diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index a950554..f29d370 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -209,7 +209,7 @@ extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 cpu_data[]; #define current_cpu_data cpu_data[smp_processor_id()] -extern void set_cpuid_faulting(bool_t enable); +extern void (*ctxt_switch_levelling)(const struct domain *nextd); extern u64 host_pat; extern bool_t opt_cpu_info;