From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED5C5C433EF for ; Wed, 2 Mar 2022 14:28:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242935AbiCBO2y (ORCPT ); Wed, 2 Mar 2022 09:28:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242911AbiCBO2o (ORCPT ); Wed, 2 Mar 2022 09:28:44 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F27091FCE3 for ; Wed, 2 Mar 2022 06:28:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1646231280; x=1677767280; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=USnPnlZ3slI1kkN96paVu2K2/7x4Up8RvHDtzRavBng=; b=QpM8Bk89WORhBJEOu63PHHzDDqu0HQJQuD45aYR1Vt+hJiFb2h1L3AzY vruvnhmbFBEZ2BiOb63Kf6I0aiau34qASK+jwansvU2KeW+4BrTm8vOXU eVhzVuAqeZHHCHGje5e22Lk3HCEnag0s0NskUcFOTHEG4HQKij/tIWJGL t8/KwP1HlRsbq6Czh5dLi7YdgexGuPO3gyyIut471hdj0VcJNPgb0y3wm iMDGbaWfybzrJEqpLjamOF5kTTw29pUXuZ4xOurffIU+Xl0bjac+YX7Z3 52HEswaAP1DyJB7+WxMLduWTgHlFuBEH92V4nqLEp5o4UAc7DDe1uy5Fn Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10274"; a="252239385" X-IronPort-AV: E=Sophos;i="5.90,149,1643702400"; d="scan'208";a="252239385" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Mar 2022 06:28:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,149,1643702400"; d="scan'208";a="609215402" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga004.fm.intel.com with ESMTP; 02 Mar 2022 06:27:54 -0800 Received: by black.fi.intel.com (Postfix, from userid 1000) id EDC1024C; Wed, 2 Mar 2022 16:28:11 +0200 (EET) From: "Kirill A. Shutemov" To: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@intel.com, luto@kernel.org, peterz@infradead.org Cc: sathyanarayanan.kuppuswamy@linux.intel.com, aarcange@redhat.com, ak@linux.intel.com, dan.j.williams@intel.com, david@redhat.com, hpa@zytor.com, jgross@suse.com, jmattson@google.com, joro@8bytes.org, jpoimboe@redhat.com, knsathya@kernel.org, pbonzini@redhat.com, sdeep@vmware.com, seanjc@google.com, tony.luck@intel.com, vkuznets@redhat.com, wanpengli@tencent.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, x86@kernel.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCHv5 04/30] x86/tdx: Extend the confidential computing API to support TDX guests Date: Wed, 2 Mar 2022 17:27:40 +0300 Message-Id: <20220302142806.51844-5-kirill.shutemov@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220302142806.51844-1-kirill.shutemov@linux.intel.com> References: <20220302142806.51844-1-kirill.shutemov@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Confidential Computing (CC) features (like string I/O unroll support, memory encryption/decryption support, etc) are conditionally enabled in the kernel using cc_platform_has() API. Since TDX guests also need to use these CC features, extend cc_platform_has() API and add TDX guest-specific CC attributes support. Like AMD SME/SEV, TDX uses a bit in the page table entry to indicate encryption status of the page, but the polarity of the mask is opposite to AMD: if the bit is set the page is accessible to VMM. Details about which bit in the page table entry to be used to indicate shared/private state can be determined by using the TDINFO TDCALL. Signed-off-by: Kirill A. Shutemov --- arch/x86/Kconfig | 1 + arch/x86/coco/core.c | 4 ++++ arch/x86/coco/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c346d66b51fc..93e67842e369 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -884,6 +884,7 @@ config INTEL_TDX_GUEST bool "Intel TDX (Trust Domain Extensions) - Guest Support" depends on X86_64 && CPU_SUP_INTEL depends on X86_X2APIC + select ARCH_HAS_CC_PLATFORM help Support running as a guest under Intel TDX. Without this support, the guest kernel can not boot or run under TDX. diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c index fc1365dd927e..9113baebbfd2 100644 --- a/arch/x86/coco/core.c +++ b/arch/x86/coco/core.c @@ -90,6 +90,8 @@ u64 cc_mkenc(u64 val) switch (vendor) { case CC_VENDOR_AMD: return val | cc_mask; + case CC_VENDOR_INTEL: + return val & ~cc_mask; default: return val; } @@ -100,6 +102,8 @@ u64 cc_mkdec(u64 val) switch (vendor) { case CC_VENDOR_AMD: return val & ~cc_mask; + case CC_VENDOR_INTEL: + return val | cc_mask; default: return val; } diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c index 17365fd40ba2..912ef12e434e 100644 --- a/arch/x86/coco/tdx.c +++ b/arch/x86/coco/tdx.c @@ -5,8 +5,12 @@ #define pr_fmt(fmt) "tdx: " fmt #include +#include #include +/* TDX module Call Leaf IDs */ +#define TDX_GET_INFO 1 + /* * Wrapper for standard use of __tdx_hypercall with no output aside from * return code. @@ -25,8 +29,32 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15) return __tdx_hypercall(&args, 0); } +static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, + struct tdx_module_output *out) +{ + if (__tdx_module_call(fn, rcx, rdx, r8, r9, out)) + panic("TDCALL %lld failed (Buggy TDX module!)\n", fn); +} + +static void get_info(unsigned int *gpa_width) +{ + struct tdx_module_output out; + + /* + * TDINFO TDX module call is used to get the TD execution environment + * information like GPA width, number of available vcpus, debug mode + * information, etc. More details about the ABI can be found in TDX + * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL + * [TDG.VP.INFO]. + */ + tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out); + + *gpa_width = out.rcx & GENMASK(5, 0); +} + void __init tdx_early_init(void) { + unsigned int gpa_width; u32 eax, sig[3]; cpuid_count(TDX_CPUID_LEAF_ID, 0, &eax, &sig[0], &sig[2], &sig[1]); @@ -37,5 +65,15 @@ void __init tdx_early_init(void) setup_force_cpu_cap(X86_FEATURE_TDX_GUEST); + get_info(&gpa_width); + + cc_set_vendor(CC_VENDOR_INTEL); + + /* + * The highest bit of a guest physical address is the "sharing" bit. + * Set it for shared pages and clear it for private pages. + */ + cc_set_mask(BIT_ULL(gpa_width - 1)); + pr_info("Guest detected\n"); } -- 2.34.1