Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp405945ybt; Wed, 1 Jul 2020 01:08:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzaLHdLF9f4VcmtwLFo0L5vlVrzr+dTefEbjACNTOty9ALx+JJlLgeVJFI7RgYjSlpjNSoR X-Received: by 2002:a17:906:b24d:: with SMTP id ce13mr23033097ejb.546.1593590933988; Wed, 01 Jul 2020 01:08:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593590933; cv=none; d=google.com; s=arc-20160816; b=pVwxpOOxKgahy1iz6Wx6L7cC0fOk6Db7bRsZzsFuulM5MwyOwn4Tgyz8keDXX6yb4A z/NkCJMEV6vR6ypq1EVCTf6TfeF+d65qtAU0ZbN+oIbGIvOn5j8kSiIk0IruRDIuSy+t OfbVyTJiw+jixhHss3GnnbOvyA5lpYoc++7p9d0NPoWAQ1AfLix3k7ifbk3sGkaDU+5i dbGT6CTVQSpn76W7Ikk5OOmMGA82+xeKcPFInH9L3SNICcyUeFoLpTd/qolA5h3sUrV5 sSf1uQQ3hB2u/FkjV1jdVwjlXmC/N1oPSDyq4M/BpbwUzCxvZ12SYcz6/y57zTictKgm Rs7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:ironport-sdr:ironport-sdr; bh=EYOcCBcMztalhNx7P5owYmYGlKiJiKvcOG7HOxl0SC4=; b=CZVBf1EIVa+eSNB3nYkdePL+hhJVKfvSw8vtCrkZ2uQAZ3JwEHyeVMpoyq/abNvjkB gW+/oQIFU50lemsH6RydsI/L49oPevBzgOBo/s8enM5TAtGSrgVDg/LT37D7bnh17rZP EmXLWPRPPmvbs03uP/cOVH7Boc3fJpb19uFEHM9RJxOdQQIbgri/amV5HL3Tr/dANU8H aeSWGAYOoOvj/cTOni6w4oG7Y42jYayywtOFQrJCsymRxjNx1Il1KHy7pTwoALu+VSUB sdlrKyyXIzpefThvlk/P+KAdSxzcteJYplHQ6muEvSbdNeoiYjGSoSY1Zj6EDFVL/6Pd ShWA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b7si4422484edz.250.2020.07.01.01.08.31; Wed, 01 Jul 2020 01:08:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728648AbgGAIEh (ORCPT + 99 others); Wed, 1 Jul 2020 04:04:37 -0400 Received: from mga14.intel.com ([192.55.52.115]:2418 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728542AbgGAIE1 (ORCPT ); Wed, 1 Jul 2020 04:04:27 -0400 IronPort-SDR: kCyYez8SbF4ojfKV+nMExKTnloaEq/pvC1DRhBlwoJkPIJF71ZfjH7X7Jy2vcZzvoVhl25+vpc r1bxNnsMxe+A== X-IronPort-AV: E=McAfee;i="6000,8403,9668"; a="145581877" X-IronPort-AV: E=Sophos;i="5.75,299,1589266800"; d="scan'208";a="145581877" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jul 2020 01:04:21 -0700 IronPort-SDR: IEZK2Ncsyc/n/I85fAQUdmYa0DgrawWG4GM+EFbYPGkBn4qge3sPE7cOL/ddvGyRTPIslE6w2y OK1xV3pFoNVQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,299,1589266800"; d="scan'208";a="455010267" Received: from unknown (HELO local-michael-cet-test.sh.intel.com) ([10.239.159.128]) by orsmga005.jf.intel.com with ESMTP; 01 Jul 2020 01:04:19 -0700 From: Yang Weijiang To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, pbonzini@redhat.com, sean.j.christopherson@intel.com, jmattson@google.com Cc: yu.c.zhang@linux.intel.com, Yang Weijiang Subject: [PATCH v13 04/11] KVM: VMX: Configure CET settings upon guest CR0/4 changing Date: Wed, 1 Jul 2020 16:04:04 +0800 Message-Id: <20200701080411.5802-5-weijiang.yang@intel.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20200701080411.5802-1-weijiang.yang@intel.com> References: <20200701080411.5802-1-weijiang.yang@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org CR4.CET is master control bit for CET function. There're mutual constrains between CR0.WP and CR4.CET, so need to check the dependent bit while changing the control registers. The processor does not allow CR4.CET to be set if CR0.WP = 0,similarly, it does not allow CR0.WP to be cleared while CR4.CET = 1. In either case, KVM would inject #GP to guest. CET state load bit is set/cleared along with CR4.CET bit set/clear. Note: SHSTK and IBT features share one control MSR: MSR_IA32_{U,S}_CET, which means it's difficult to hide one feature from another in the case of SHSTK != IBT, after discussed in community, it's agreed to allow guest control two features independently as it won't introduce security hole. Signed-off-by: Yang Weijiang --- arch/x86/kvm/vmx/capabilities.h | 5 +++++ arch/x86/kvm/vmx/vmx.c | 30 ++++++++++++++++++++++++++++-- arch/x86/kvm/x86.c | 3 +++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index 8903475f751e..52223f7d31d8 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -101,6 +101,11 @@ static inline bool cpu_has_load_perf_global_ctrl(void) (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL); } +static inline bool cpu_has_load_cet_ctrl(void) +{ + return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_CET_STATE) && + (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_CET_STATE); +} static inline bool cpu_has_vmx_mpx(void) { return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) && diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 97e766875a7e..7137e252ab38 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2440,7 +2440,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, VM_EXIT_LOAD_IA32_EFER | VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_PT_CONCEAL_PIP | - VM_EXIT_CLEAR_IA32_RTIT_CTL; + VM_EXIT_CLEAR_IA32_RTIT_CTL | + VM_EXIT_LOAD_CET_STATE; if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS, &_vmexit_control) < 0) return -EIO; @@ -2464,7 +2465,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, VM_ENTRY_LOAD_IA32_EFER | VM_ENTRY_LOAD_BNDCFGS | VM_ENTRY_PT_CONCEAL_PIP | - VM_ENTRY_LOAD_IA32_RTIT_CTL; + VM_ENTRY_LOAD_IA32_RTIT_CTL | + VM_ENTRY_LOAD_CET_STATE; if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS, &_vmentry_control) < 0) return -EIO; @@ -3027,6 +3029,12 @@ static bool is_cet_state_supported(struct kvm_vcpu *vcpu, u32 xss_states) guest_cpuid_has(vcpu, X86_FEATURE_IBT))); } +static bool is_cet_supported(struct kvm_vcpu *vcpu) +{ + return is_cet_state_supported(vcpu, XFEATURE_MASK_CET_USER | + XFEATURE_MASK_CET_KERNEL); +} + int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -3067,6 +3075,10 @@ int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) return 1; } + if ((cr4 & X86_CR4_CET) && (!is_cet_supported(vcpu) || + !(kvm_read_cr0(vcpu) & X86_CR0_WP))) + return 1; + if (vmx->nested.vmxon && !nested_cr4_valid(vcpu, cr4)) return 1; @@ -3097,6 +3109,20 @@ int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE); } + if (cpu_has_load_cet_ctrl()) { + if ((hw_cr4 & X86_CR4_CET) && is_cet_supported(vcpu)) { + vm_entry_controls_setbit(to_vmx(vcpu), + VM_ENTRY_LOAD_CET_STATE); + vm_exit_controls_setbit(to_vmx(vcpu), + VM_EXIT_LOAD_CET_STATE); + } else { + vm_entry_controls_clearbit(to_vmx(vcpu), + VM_ENTRY_LOAD_CET_STATE); + vm_exit_controls_clearbit(to_vmx(vcpu), + VM_EXIT_LOAD_CET_STATE); + } + } + vmcs_writel(CR4_READ_SHADOW, cr4); vmcs_writel(GUEST_CR4, hw_cr4); return 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6390b62c12ed..b63727318da1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -803,6 +803,9 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) if (!(cr0 & X86_CR0_PG) && kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE)) return 1; + if (!(cr0 & X86_CR0_WP) && kvm_read_cr4_bits(vcpu, X86_CR4_CET)) + return 1; + kvm_x86_ops.set_cr0(vcpu, cr0); if ((cr0 ^ old_cr0) & X86_CR0_PG) { -- 2.17.2