From patchwork Fri Nov 24 05:53:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yang, Weijiang" X-Patchwork-Id: 169256 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce62:0:b0:403:3b70:6f57 with SMTP id o2csp984560vqx; Fri, 24 Nov 2023 00:01:11 -0800 (PST) X-Google-Smtp-Source: AGHT+IHhPRNMBrNeESug72PPVyaGxyxAE9Bxi9DIeW3ytPcPpAYJwvulSEUVr/QtufzvY/Zu+R3Y X-Received: by 2002:a05:6870:e391:b0:1ef:b803:4bbc with SMTP id x17-20020a056870e39100b001efb8034bbcmr2091840oad.2.1700812870953; Fri, 24 Nov 2023 00:01:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700812870; cv=none; d=google.com; s=arc-20160816; b=O/G5uePMSof3Mgdgm5Y3ZGEhkTRq/wIaZBYC+Tb+sdffWIolejgnKLjOLo2THANFa9 UFFs89lZ0Mi42F6KrOxYgRIJxvjmkxUgYMacZpyI4Wz5uYKFM1mP3ec26OBFU8AzgWyR o5qsFmW7ycJ6m/6wZ1jUWUpdYM91bO11ctcyz+yGGv5m9YqMPsNpTKWSwuDVoDQfyMWB M87bo0YNF0iFkmljdT+col5pAqGr6SG2lNZbEd8wETN6OfXMdW3trldkvmfuksTFc+ZK NFsHcSYkV/ZBcX4CLL0UIWpXGc7cfPDVSITgX23/rbqNOMbDJnLiglFThCuxWLBE0mu8 G4oA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=hRMTB+dbX9leq+/VVI5aqzgKOQpQirLUdUyHCTBmygQ=; fh=uy0EBGgYIm8+MgsxUvKHUXUo3s9z4H9hdLwRv8YoeJU=; b=nfU71eEZ8oZ9e+J7wHbbLU5zKiD7HKJpa5u46EgVitPDPtl2bih12Lzo1U3V9OoryK afZCsI0/tRxW4z1Ghxi2mC2qk68p84F8YMY2+QfYnQ0lFBU1hHBlh8OsMNz6nRo+kt0P 9MyMqSVgLUu/Wsbp5PIkyVr8kzYBJBlcSqic6hZjR4RtfpwxV4NbHFaqcPKzUKreK/ct F15g/ATZCBt/wtxg6GoEZ+2tDp4Wtohg36Qg4fd2YxbLuUwyk9awyX2PDQR+3cvVu/v6 8/JI2Tt3RmfHwiYfpYLhGN7yeYelocak1WlEsMRaLKsTZF4cNwriG8cPBx3hJ8wrGWGq k5gg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Uyime4Gt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id w5-20020a056870230500b001f5c9110d17si1122552oao.152.2023.11.24.00.01.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 00:01:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Uyime4Gt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id 3FDFF80936D8; Fri, 24 Nov 2023 00:01:06 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345255AbjKXIA3 (ORCPT + 29 others); Fri, 24 Nov 2023 03:00:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232893AbjKXH6m (ORCPT ); Fri, 24 Nov 2023 02:58:42 -0500 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.100]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 889D110F2; Thu, 23 Nov 2023 23:58:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1700812728; x=1732348728; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EIDBnN3Fa/jfofaQS+71ohT8d44MUV2gyhWnvNd70ww=; b=Uyime4Gt35a6C0Ng7oXrRq9ns+mW8guoWHyPvCvS8FaY4cWZhv7pIB8i NgMRfiY1TImvcx/0aZAiheZnR49oSL7AKBvGQztzklf6XZ7JiyU3McI6Z xxY7snhjDcipDCR3XM4NiTtLQvBvm7U4CIS1Nqa+AC+EfPtmwpwaCVyDb WyZf28Fhx9vcARmzl8kQSgBpiemUF1035uh16awnoMkEgJEgq2WdvU8a8 8grRNjbkDgQ16MTbWEuJnzGcBvqJx2wpoth58kAT2V0pYKeEP8yvcpyFE gLKrBJ7uHRCTV3XHCJZaWvXdOEllcWRWts+09wQ9EwsT+3dGTHajHeb8o g==; X-IronPort-AV: E=McAfee;i="6600,9927,10902"; a="458872387" X-IronPort-AV: E=Sophos;i="6.04,223,1695711600"; d="scan'208";a="458872387" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2023 23:58:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10902"; a="833629853" X-IronPort-AV: E=Sophos;i="6.04,223,1695711600"; d="scan'208";a="833629853" Received: from unknown (HELO embargo.jf.intel.com) ([10.165.9.183]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2023 23:58:42 -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 v7 20/26] KVM: VMX: Emulate read and write to CET MSRs Date: Fri, 24 Nov 2023 00:53:24 -0500 Message-Id: <20231124055330.138870-21-weijiang.yang@intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20231124055330.138870-1-weijiang.yang@intel.com> References: <20231124055330.138870-1-weijiang.yang@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Fri, 24 Nov 2023 00:01:06 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783431557117777674 X-GMAIL-MSGID: 1783431557117777674 Add emulation interface for CET MSR access. The emulation code is split into common part and vendor specific part. The former does common checks for MSRs, e.g., accessibility, data validity etc., then pass the operation to either XSAVE-managed MSRs via the helpers or CET VMCS fields. Suggested-by: Sean Christopherson Signed-off-by: Yang Weijiang --- arch/x86/kvm/vmx/vmx.c | 18 +++++++++ arch/x86/kvm/x86.c | 88 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index f6ad5ba5d518..554f665e59c3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2111,6 +2111,15 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) else msr_info->data = vmx->pt_desc.guest.addr_a[index / 2]; break; + case MSR_IA32_S_CET: + msr_info->data = vmcs_readl(GUEST_S_CET); + break; + case MSR_KVM_SSP: + msr_info->data = vmcs_readl(GUEST_SSP); + break; + case MSR_IA32_INT_SSP_TAB: + msr_info->data = vmcs_readl(GUEST_INTR_SSP_TABLE); + break; case MSR_IA32_DEBUGCTLMSR: msr_info->data = vmcs_read64(GUEST_IA32_DEBUGCTL); break; @@ -2420,6 +2429,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) else vmx->pt_desc.guest.addr_a[index / 2] = data; break; + case MSR_IA32_S_CET: + vmcs_writel(GUEST_S_CET, data); + break; + case MSR_KVM_SSP: + vmcs_writel(GUEST_SSP, data); + break; + case MSR_IA32_INT_SSP_TAB: + vmcs_writel(GUEST_INTR_SSP_TABLE, data); + break; case MSR_IA32_PERF_CAPABILITIES: if (data && !vcpu_to_pmu(vcpu)->version) return 1; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 74d2d00a1681..5792ed16e61b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1847,6 +1847,36 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type) } EXPORT_SYMBOL_GPL(kvm_msr_allowed); +#define CET_US_RESERVED_BITS GENMASK(9, 6) +#define CET_US_SHSTK_MASK_BITS GENMASK(1, 0) +#define CET_US_IBT_MASK_BITS (GENMASK_ULL(5, 2) | GENMASK_ULL(63, 10)) +#define CET_US_LEGACY_BITMAP_BASE(data) ((data) >> 12) + +static bool is_set_cet_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u64 data, + bool host_initiated) +{ + bool msr_ctrl = index == MSR_IA32_S_CET || index == MSR_IA32_U_CET; + + if (guest_can_use(vcpu, X86_FEATURE_SHSTK)) + return true; + + if (msr_ctrl && guest_can_use(vcpu, X86_FEATURE_IBT)) + return true; + + /* + * If KVM supports the MSR, i.e. has enumerated the MSR existence to + * userspace, then userspace is allowed to write '0' irrespective of + * whether or not the MSR is exposed to the guest. + */ + if (!host_initiated || data) + return false; + + if (kvm_cpu_cap_has(X86_FEATURE_SHSTK)) + return true; + + return msr_ctrl && kvm_cpu_cap_has(X86_FEATURE_IBT); +} + /* * Write @data into the MSR specified by @index. Select MSR specific fault * checks are bypassed if @host_initiated is %true. @@ -1906,6 +1936,43 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data, data = (u32)data; break; + case MSR_IA32_U_CET: + case MSR_IA32_S_CET: + if (!is_set_cet_msr_allowed(vcpu, index, data, host_initiated)) + return 1; + if (data & CET_US_RESERVED_BITS) + return 1; + if (!guest_can_use(vcpu, X86_FEATURE_SHSTK) && + (data & CET_US_SHSTK_MASK_BITS)) + return 1; + if (!guest_can_use(vcpu, X86_FEATURE_IBT) && + (data & CET_US_IBT_MASK_BITS)) + return 1; + if (!IS_ALIGNED(CET_US_LEGACY_BITMAP_BASE(data), 4)) + return 1; + /* IBT can be suppressed iff the TRACKER isn't WAIT_ENDBR. */ + if ((data & CET_SUPPRESS) && (data & CET_WAIT_ENDBR)) + return 1; + break; + case MSR_IA32_INT_SSP_TAB: + if (!is_set_cet_msr_allowed(vcpu, index, data, host_initiated) || + !guest_cpuid_has(vcpu, X86_FEATURE_LM)) + return 1; + if (is_noncanonical_address(data, vcpu)) + return 1; + break; + case MSR_KVM_SSP: + if (!host_initiated) + return 1; + fallthrough; + case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: + if (!is_set_cet_msr_allowed(vcpu, index, data, host_initiated)) + return 1; + if (is_noncanonical_address(data, vcpu)) + return 1; + if (!IS_ALIGNED(data, 4)) + return 1; + break; } msr.data = data; @@ -1949,6 +2016,19 @@ static int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, !guest_cpuid_has(vcpu, X86_FEATURE_RDPID)) return 1; break; + case MSR_IA32_INT_SSP_TAB: + if (!guest_can_use(vcpu, X86_FEATURE_SHSTK) || + !guest_cpuid_has(vcpu, X86_FEATURE_LM)) + return 1; + break; + case MSR_KVM_SSP: + if (!host_initiated) + return 1; + fallthrough; + case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: + if (!guest_can_use(vcpu, X86_FEATURE_SHSTK)) + return 1; + break; } msr.index = index; @@ -4118,6 +4198,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) vcpu->arch.guest_fpu.xfd_err = data; break; #endif + case MSR_IA32_U_CET: + case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: + kvm_set_xstate_msr(vcpu, msr_info); + break; default: if (kvm_pmu_is_valid_msr(vcpu, msr)) return kvm_pmu_set_msr(vcpu, msr_info); @@ -4475,6 +4559,10 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = vcpu->arch.guest_fpu.xfd_err; break; #endif + case MSR_IA32_U_CET: + case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: + kvm_get_xstate_msr(vcpu, msr_info); + break; default: if (kvm_pmu_is_valid_msr(vcpu, msr_info->index)) return kvm_pmu_get_msr(vcpu, msr_info);