From patchwork Wed Jan 4 12:39:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 9496683 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D4D2C606DD for ; Wed, 4 Jan 2017 12:48:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C6CB427F85 for ; Wed, 4 Jan 2017 12:48:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBA2A27F8C; Wed, 4 Jan 2017 12:48:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 1066027F88 for ; Wed, 4 Jan 2017 12:48:32 +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 1cOkxf-0005pO-DW; Wed, 04 Jan 2017 12:46:35 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cOkxe-0005kr-7k for xen-devel@lists.xen.org; Wed, 04 Jan 2017 12:46:34 +0000 Received: from [85.158.137.68] by server-2.bemta-3.messagelabs.com id 05/F1-09690-9AEEC685; Wed, 04 Jan 2017 12:46:33 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmkeJIrShJLcpLzFFi42JxWrohUnfFu5w IgwNt+hZLPi5mcWD0OLr7N1MAYxRrZl5SfkUCa8bdWSdYCk5ZVCw9+JOpgbFPo4uRk0NCwF/i 59MDrCA2m4C+xO4Xn5hAbBEBdYnTHReB4hwczAJ+Eoce+IKEhQV8JSa9fsQIYrMIqEgs/HqWG cTmFfCUuPBiKjPESDmJ88d/gtmcQPFnG9eB1QsJeEhMubiMHcJWk7jWf4kdoldQ4uTMJywgNr OAhMTBFy+YJzDyzkKSmoUktYCRaRWjenFqUVlqka6JXlJRZnpGSW5iZo6uoYGxXm5qcXFiemp OYlKxXnJ+7iZGYOAwAMEOxsYvTocYJTmYlER5+9pzIoT4kvJTKjMSizPii0pzUosPMcpwcChJ 8Aq9BcoJFqWmp1akZeYAQxgmLcHBoyTCmw6S5i0uSMwtzkyHSJ1iVJQS5zUGSQiAJDJK8+DaY HFziVFWSpiXEegQIZ6C1KLczBJU+VeM4hyMSsK8NiBTeDLzSuCmvwJazAS0eHtANsjikkSElF QDozNDu0Zyu83+s747GhTjP7nozW26XCXAupfX32/Gr1OW+grNzIv+rah/I3J425K4dPG3dYH m4s1zdzGbvWeT3PJgXZ/wD4EfG944FH51vel7vnb5ko+uW/e+Y6hrl7Z/qL9UrddErkI4bbJz QYSrnJ6/7zWzHfsPpx/fmvZjmpmq2E6pIENvJZbijERDLeai4kQAsrIBtpYCAAA= X-Env-Sender: prvs=1701003ad=Andrew.Cooper3@citrix.com X-Msg-Ref: server-6.tower-31.messagelabs.com!1483533980!52605894!9 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: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 47051 invoked from network); 4 Jan 2017 12:46:32 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-6.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 4 Jan 2017 12:46:32 -0000 X-IronPort-AV: E=Sophos;i="5.33,459,1477958400"; d="scan'208";a="397866986" From: Andrew Cooper To: Xen-devel Date: Wed, 4 Jan 2017 12:39:29 +0000 Message-ID: <1483533584-8015-13-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1483533584-8015-1-git-send-email-andrew.cooper3@citrix.com> References: <1483533584-8015-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 Cc: Andrew Cooper , Jan Beulich Subject: [Xen-devel] [PATCH 12/27] x86/hvm: Improve CR4 verification using named features 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-Virus-Scanned: ClamAV using ClamSMTP Alter the function to return the valid CR4 bits, rather than the invalid CR4 bits. This will allow reuse in other areas of code. Pick the appropriate cpuid_policy object rather than using hvm_cpuid() or boot_cpu_data. This breaks the dependency on current. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich --- xen/arch/x86/domain.c | 2 +- xen/arch/x86/hvm/hvm.c | 92 +++++++++++++++---------------------------- xen/include/asm-x86/hvm/hvm.h | 2 +- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index b554a9c..319cc8a 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1512,7 +1512,7 @@ int arch_set_info_hvm_guest(struct vcpu *v, const vcpu_hvm_context_t *ctx) if ( v->arch.hvm_vcpu.guest_efer & EFER_LME ) v->arch.hvm_vcpu.guest_efer |= EFER_LMA; - if ( v->arch.hvm_vcpu.guest_cr[4] & hvm_cr4_guest_reserved_bits(v, 0) ) + if ( v->arch.hvm_vcpu.guest_cr[4] & ~hvm_cr4_guest_valid_bits(v, 0) ) { gprintk(XENLOG_ERR, "Bad CR4 value: %#016lx\n", v->arch.hvm_vcpu.guest_cr[4]); diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index d651d0b..e2060d2 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -956,67 +956,39 @@ const char *hvm_efer_valid(const struct vcpu *v, uint64_t value, int cr0_pg) X86_CR0_WP | X86_CR0_AM | X86_CR0_NW | \ X86_CR0_CD | X86_CR0_PG))) -/* These bits in CR4 cannot be set by the guest. */ -unsigned long hvm_cr4_guest_reserved_bits(const struct vcpu *v,bool_t restore) +/* These bits in CR4 can be set by the guest. */ +unsigned long hvm_cr4_guest_valid_bits(const struct vcpu *v, bool restore) { - unsigned int leaf1_ecx = 0, leaf1_edx = 0; - unsigned int leaf7_0_ebx = 0, leaf7_0_ecx = 0; - - if ( !restore && !is_hardware_domain(v->domain) ) - { - unsigned int level; + const struct domain *d = v->domain; + const struct cpuid_policy *p; + bool mce, vmxe; - ASSERT(v->domain == current->domain); - hvm_cpuid(0, &level, NULL, NULL, NULL); - if ( level >= 1 ) - hvm_cpuid(1, NULL, NULL, &leaf1_ecx, &leaf1_edx); - if ( level >= 7 ) - hvm_cpuid(7, NULL, &leaf7_0_ebx, &leaf7_0_ecx, NULL); - } + if ( !restore && !is_hardware_domain(d) ) + p = d->arch.cpuid; else - { - leaf1_edx = boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_VME)]; - leaf1_ecx = boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_PCID)]; - leaf7_0_ebx = boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_FSGSBASE)]; - leaf7_0_ecx = boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_PKU)]; - } - - return ~(unsigned long) - ((leaf1_edx & cpufeat_mask(X86_FEATURE_VME) ? - X86_CR4_VME | X86_CR4_PVI : 0) | - (leaf1_edx & cpufeat_mask(X86_FEATURE_TSC) ? - X86_CR4_TSD : 0) | - (leaf1_edx & cpufeat_mask(X86_FEATURE_DE) ? - X86_CR4_DE : 0) | - (leaf1_edx & cpufeat_mask(X86_FEATURE_PSE) ? - X86_CR4_PSE : 0) | - (leaf1_edx & cpufeat_mask(X86_FEATURE_PAE) ? - X86_CR4_PAE : 0) | - (leaf1_edx & (cpufeat_mask(X86_FEATURE_MCE) | - cpufeat_mask(X86_FEATURE_MCA)) ? - X86_CR4_MCE : 0) | - (leaf1_edx & cpufeat_mask(X86_FEATURE_PGE) ? - X86_CR4_PGE : 0) | - X86_CR4_PCE | - (leaf1_edx & cpufeat_mask(X86_FEATURE_FXSR) ? - X86_CR4_OSFXSR : 0) | - (leaf1_edx & cpufeat_mask(X86_FEATURE_SSE) ? - X86_CR4_OSXMMEXCPT : 0) | - ((restore || nestedhvm_enabled(v->domain)) && - (leaf1_ecx & cpufeat_mask(X86_FEATURE_VMX)) ? - X86_CR4_VMXE : 0) | - (leaf7_0_ebx & cpufeat_mask(X86_FEATURE_FSGSBASE) ? - X86_CR4_FSGSBASE : 0) | - (leaf1_ecx & cpufeat_mask(X86_FEATURE_PCID) ? - X86_CR4_PCIDE : 0) | - (leaf1_ecx & cpufeat_mask(X86_FEATURE_XSAVE) ? - X86_CR4_OSXSAVE : 0) | - (leaf7_0_ebx & cpufeat_mask(X86_FEATURE_SMEP) ? - X86_CR4_SMEP : 0) | - (leaf7_0_ebx & cpufeat_mask(X86_FEATURE_SMAP) ? - X86_CR4_SMAP : 0) | - (leaf7_0_ecx & cpufeat_mask(X86_FEATURE_PKU) ? - X86_CR4_PKE : 0)); + p = &host_policy; + + /* Logic broken out simply to aid readability below. */ + mce = p->basic.mce || p->basic.mca; + vmxe = p->basic.vmx && (restore || nestedhvm_enabled(d)); + + return ((p->basic.vme ? X86_CR4_VME | X86_CR4_PVI : 0) | + (p->basic.tsc ? X86_CR4_TSD : 0) | + (p->basic.de ? X86_CR4_DE : 0) | + (p->basic.pse ? X86_CR4_PSE : 0) | + (p->basic.pae ? X86_CR4_PAE : 0) | + (mce ? X86_CR4_MCE : 0) | + (p->basic.pge ? X86_CR4_PGE : 0) | + X86_CR4_PCE | + (p->basic.fxsr ? X86_CR4_OSFXSR : 0) | + (p->basic.sse ? X86_CR4_OSXMMEXCPT : 0) | + (vmxe ? X86_CR4_VMXE : 0) | + (p->feat.fsgsbase ? X86_CR4_FSGSBASE : 0) | + (p->basic.pcid ? X86_CR4_PCIDE : 0) | + (p->basic.xsave ? X86_CR4_OSXSAVE : 0) | + (p->feat.smep ? X86_CR4_SMEP : 0) | + (p->feat.smap ? X86_CR4_SMAP : 0) | + (p->feat.pku ? X86_CR4_PKE : 0)); } static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) @@ -1053,7 +1025,7 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) return -EINVAL; } - if ( ctxt.cr4 & hvm_cr4_guest_reserved_bits(v, 1) ) + if ( ctxt.cr4 & ~hvm_cr4_guest_valid_bits(v, 1) ) { printk(XENLOG_G_ERR "HVM%d restore: bad CR4 %#" PRIx64 "\n", d->domain_id, ctxt.cr4); @@ -2389,7 +2361,7 @@ int hvm_set_cr4(unsigned long value, bool_t may_defer) struct vcpu *v = current; unsigned long old_cr; - if ( value & hvm_cr4_guest_reserved_bits(v, 0) ) + if ( value & ~hvm_cr4_guest_valid_bits(v, 0) ) { HVM_DBG_LOG(DBG_LEVEL_1, "Guest attempts to set reserved bit in CR4: %lx", diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 4248546..c1b07b7 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -614,7 +614,7 @@ static inline bool altp2m_vcpu_emulate_ve(struct vcpu *v) /* Check CR4/EFER values */ const char *hvm_efer_valid(const struct vcpu *v, uint64_t value, int cr0_pg); -unsigned long hvm_cr4_guest_reserved_bits(const struct vcpu *v, bool_t restore); +unsigned long hvm_cr4_guest_valid_bits(const struct vcpu *v, bool restore); /* * This must be defined as a macro instead of an inline function,