Received: by 2002:a05:7412:b995:b0:f9:9502:5bb8 with SMTP id it21csp21011rdb; Thu, 21 Dec 2023 01:19:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IFURNGfuGzxXPeUdJOJ5Ro/ZARJr3CIl2HOkEMarEyTJWo/H2WWAKYKeY4fVyBFhDJ/R9JO X-Received: by 2002:a17:902:e54c:b0:1d3:eea7:9268 with SMTP id n12-20020a170902e54c00b001d3eea79268mr1861454plf.97.1703150397399; Thu, 21 Dec 2023 01:19:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703150397; cv=none; d=google.com; s=arc-20160816; b=Br7AxMIVx7OLZiEfNPAORYCfrqWzRRfa0lwD1zKXrJ97AomMpzSmglzTmQuwT+R9Rc +RbFzeTWSoZVnjYoVim2ZDq0LGGFdqJ5u3cLiOk9PdSLo7fRdKe4NZJ9tqnqg1byi8M4 XRTPbxtcjFVvUKpx+U3Data5u6QWK01Ojs6tgXd11A/R9FSizy11935VyZboIb1Y5V6a uHHx41jnMnWMV9E/4ic9SJiQprfwG9Mm3nUHr4qqv6E+VZteM/uUMS512fMt7bvOOx9S emfSRqJd1MzZznBbMI+aBDzE39X9XG/N4eu030XfacaV6bLmr6tHnNmJvFd3d0QkH1I9 0mLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=EfXEr0isTI2qeZYuKigC4cW3dgq2u0iYOayvNQrlTRc=; fh=uy0EBGgYIm8+MgsxUvKHUXUo3s9z4H9hdLwRv8YoeJU=; b=S8yFv7HcSri2QX16qAiwZsLogAK9pi5CAJ79yxPKYCA/NoJa/bMGp7m1S11990evxQ NXKDhX8nheom7j1ZBh+nv11IG2AWljqmVIleEBieod8WRdYB7sZCM7Dt/BJOKFw7z8bW i+/MYgYS1cFX3SH6CmtyEpMqVozjMZmCdJ7Bv/ki3iQRpKqshOA7/ZswQCgf9uI9ie6M fUNJyDOBNmqvm3xwq/WCMDcainbswtUJ/U3OzE6+9DLE2WxTRK0oEDXqDtZ9sBZMp9Vb AfBfzTvfcW4AsVOwvaMaXtbao3bIyHYJ/Wr/gDe4zCn9GPjEhziM2wc1pXtXrxkWo4De lSzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JLwoMiLd; spf=pass (google.com: domain of linux-kernel+bounces-8084-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-8084-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id n12-20020a170903110c00b001d0a791c902si1239128plh.136.2023.12.21.01.19.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Dec 2023 01:19:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-8084-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JLwoMiLd; spf=pass (google.com: domain of linux-kernel+bounces-8084-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-8084-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id AAD3E2864C1 for ; Thu, 21 Dec 2023 09:19:47 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A06835A114; Thu, 21 Dec 2023 09:03:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="JLwoMiLd" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27C9E584E2; Thu, 21 Dec 2023 09:03:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703149437; x=1734685437; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BN9hsBQ2Z+9tGAlANCAp121KNF0ETD1YHCS41SLLuR0=; b=JLwoMiLdTnPdXPNsk0YqHyUCmtESIcgsefq79FtB9kFFOjPnlZk/UZnP 0IKOPBO1ZfXUPvmP11XLQaHDmewpCBuHKTlhpJSb70jljqr+FxCg8BnWT IDT0/fkhEE41Xo9211d3ZcdWkjYT5HPuxN6TyXmyz5Ae/iPk1SMVMg6lr FCWlSy8Fh18UpCHRmHoJmeUOdv4OfgrfJ75MqLajL5F59sx5h+TywJ+0T TTJ3AlbN0uQeoMVeAfGGQe/EBSs3zp6sEcgiFNqNKtf5JLbb5xxVmsAwo yUilP+z/flYau7vJA5/1g97DuRqDV56WYmcndnqf4JuyQRlBNr5/cewna Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10930"; a="398729732" X-IronPort-AV: E=Sophos;i="6.04,293,1695711600"; d="scan'208";a="398729732" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Dec 2023 01:03:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10930"; a="900028650" X-IronPort-AV: E=Sophos;i="6.04,293,1695711600"; d="scan'208";a="900028650" Received: from 984fee00a5ca.jf.intel.com (HELO embargo.jf.intel.com) ([10.165.9.183]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Dec 2023 01:03:12 -0800 From: Yang Weijiang To: seanjc@google.com, pbonzini@redhat.com, dave.hansen@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: peterz@infradead.org, chao.gao@intel.com, rick.p.edgecombe@intel.com, mlevitsk@redhat.com, john.allen@amd.com, weijiang.yang@intel.com Subject: [PATCH v8 26/26] KVM: nVMX: Enable CET support for nested guest Date: Thu, 21 Dec 2023 09:02:39 -0500 Message-Id: <20231221140239.4349-27-weijiang.yang@intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20231221140239.4349-1-weijiang.yang@intel.com> References: <20231221140239.4349-1-weijiang.yang@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Set up CET MSRs, related VM_ENTRY/EXIT control bits and fixed CR4 setting to enable CET for nested VM. vmcs12 and vmcs02 needs to be synced when L2 exits to L1 or when L1 wants to resume L2, that way correct CET states can be observed by one another. Suggested-by: Chao Gao Signed-off-by: Yang Weijiang --- arch/x86/kvm/vmx/nested.c | 57 +++++++++++++++++++++++++++++++++++++-- arch/x86/kvm/vmx/vmcs12.c | 6 +++++ arch/x86/kvm/vmx/vmcs12.h | 14 +++++++++- arch/x86/kvm/vmx/vmx.c | 2 ++ 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 468a7cf75035..dee718c65255 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -691,6 +691,28 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, MSR_IA32_FLUSH_CMD, MSR_TYPE_W); + /* Pass CET MSRs to nested VM if L0 and L1 are set to pass-through. */ + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_U_CET, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_S_CET, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_PL0_SSP, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_PL1_SSP, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_PL2_SSP, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_PL3_SSP, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_INT_SSP_TAB, MSR_TYPE_RW); + kvm_vcpu_unmap(vcpu, &vmx->nested.msr_bitmap_map, false); vmx->nested.force_msr_bitmap_recalc = false; @@ -2506,6 +2528,17 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) if (kvm_mpx_supported() && vmx->nested.nested_run_pending && (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)) vmcs_write64(GUEST_BNDCFGS, vmcs12->guest_bndcfgs); + + if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) { + if (guest_can_use(&vmx->vcpu, X86_FEATURE_SHSTK)) { + vmcs_writel(GUEST_SSP, vmcs12->guest_ssp); + vmcs_writel(GUEST_INTR_SSP_TABLE, + vmcs12->guest_ssp_tbl); + } + if (guest_can_use(&vmx->vcpu, X86_FEATURE_SHSTK) || + guest_can_use(&vmx->vcpu, X86_FEATURE_IBT)) + vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet); + } } if (nested_cpu_has_xsaves(vmcs12)) @@ -4344,6 +4377,15 @@ static void sync_vmcs02_to_vmcs12_rare(struct kvm_vcpu *vcpu, vmcs12->guest_pending_dbg_exceptions = vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); + if (guest_can_use(&vmx->vcpu, X86_FEATURE_SHSTK)) { + vmcs12->guest_ssp = vmcs_readl(GUEST_SSP); + vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE); + } + if (guest_can_use(&vmx->vcpu, X86_FEATURE_SHSTK) || + guest_can_use(&vmx->vcpu, X86_FEATURE_IBT)) { + vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET); + } + vmx->nested.need_sync_vmcs02_to_vmcs12_rare = false; } @@ -4569,6 +4611,16 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) vmcs_write64(GUEST_BNDCFGS, 0); + if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_CET_STATE) { + if (guest_can_use(vcpu, X86_FEATURE_SHSTK)) { + vmcs_writel(HOST_SSP, vmcs12->host_ssp); + vmcs_writel(HOST_INTR_SSP_TABLE, vmcs12->host_ssp_tbl); + } + if (guest_can_use(vcpu, X86_FEATURE_SHSTK) || + guest_can_use(vcpu, X86_FEATURE_IBT)) + vmcs_writel(HOST_S_CET, vmcs12->host_s_cet); + } + if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) { vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat); vcpu->arch.pat = vmcs12->host_ia32_pat; @@ -6840,7 +6892,7 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf, VM_EXIT_HOST_ADDR_SPACE_SIZE | #endif VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT | - VM_EXIT_CLEAR_BNDCFGS; + VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_LOAD_CET_STATE; msrs->exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | @@ -6862,7 +6914,8 @@ static void nested_vmx_setup_entry_ctls(struct vmcs_config *vmcs_conf, #ifdef CONFIG_X86_64 VM_ENTRY_IA32E_MODE | #endif - VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS; + VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS | + VM_ENTRY_LOAD_CET_STATE; msrs->entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER | VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL); diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index 106a72c923ca..4233b5ca9461 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -139,6 +139,9 @@ const unsigned short vmcs12_field_offsets[] = { FIELD(GUEST_PENDING_DBG_EXCEPTIONS, guest_pending_dbg_exceptions), FIELD(GUEST_SYSENTER_ESP, guest_sysenter_esp), FIELD(GUEST_SYSENTER_EIP, guest_sysenter_eip), + FIELD(GUEST_S_CET, guest_s_cet), + FIELD(GUEST_SSP, guest_ssp), + FIELD(GUEST_INTR_SSP_TABLE, guest_ssp_tbl), FIELD(HOST_CR0, host_cr0), FIELD(HOST_CR3, host_cr3), FIELD(HOST_CR4, host_cr4), @@ -151,5 +154,8 @@ const unsigned short vmcs12_field_offsets[] = { FIELD(HOST_IA32_SYSENTER_EIP, host_ia32_sysenter_eip), FIELD(HOST_RSP, host_rsp), FIELD(HOST_RIP, host_rip), + FIELD(HOST_S_CET, host_s_cet), + FIELD(HOST_SSP, host_ssp), + FIELD(HOST_INTR_SSP_TABLE, host_ssp_tbl), }; const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs12_field_offsets); diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 01936013428b..3884489e7f7e 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -117,7 +117,13 @@ struct __packed vmcs12 { natural_width host_ia32_sysenter_eip; natural_width host_rsp; natural_width host_rip; - natural_width paddingl[8]; /* room for future expansion */ + natural_width host_s_cet; + natural_width host_ssp; + natural_width host_ssp_tbl; + natural_width guest_s_cet; + natural_width guest_ssp; + natural_width guest_ssp_tbl; + natural_width paddingl[2]; /* room for future expansion */ u32 pin_based_vm_exec_control; u32 cpu_based_vm_exec_control; u32 exception_bitmap; @@ -292,6 +298,12 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_ia32_sysenter_eip, 656); CHECK_OFFSET(host_rsp, 664); CHECK_OFFSET(host_rip, 672); + CHECK_OFFSET(host_s_cet, 680); + CHECK_OFFSET(host_ssp, 688); + CHECK_OFFSET(host_ssp_tbl, 696); + CHECK_OFFSET(guest_s_cet, 704); + CHECK_OFFSET(guest_ssp, 712); + CHECK_OFFSET(guest_ssp_tbl, 720); CHECK_OFFSET(pin_based_vm_exec_control, 744); CHECK_OFFSET(cpu_based_vm_exec_control, 748); CHECK_OFFSET(exception_bitmap, 752); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index c802e790c0d5..7ddd3f6fe8ab 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7732,6 +7732,8 @@ static void nested_vmx_cr_fixed1_bits_update(struct kvm_vcpu *vcpu) cr4_fixed1_update(X86_CR4_PKE, ecx, feature_bit(PKU)); cr4_fixed1_update(X86_CR4_UMIP, ecx, feature_bit(UMIP)); cr4_fixed1_update(X86_CR4_LA57, ecx, feature_bit(LA57)); + cr4_fixed1_update(X86_CR4_CET, ecx, feature_bit(SHSTK)); + cr4_fixed1_update(X86_CR4_CET, edx, feature_bit(IBT)); entry = kvm_find_cpuid_entry_index(vcpu, 0x7, 1); cr4_fixed1_update(X86_CR4_LAM_SUP, eax, feature_bit(LAM)); -- 2.39.3