linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kai Huang <kai.huang@intel.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: dave.hansen@intel.com, seanjc@google.com, pbonzini@redhat.com,
	kirill.shutemov@linux.intel.com,
	sathyanarayanan.kuppuswamy@linux.intel.com, peterz@infradead.org,
	tony.luck@intel.com, ak@linux.intel.com,
	dan.j.williams@intel.com, isaku.yamahata@intel.com,
	kai.huang@intel.com
Subject: [PATCH v2 18/21] x86/virt/tdx: Initialize all TDMRs
Date: Sun, 13 Mar 2022 23:49:58 +1300	[thread overview]
Message-ID: <3af7ece5cf86dfe83f755b7a7c541d8f691e4133.1647167475.git.kai.huang@intel.com> (raw)
In-Reply-To: <cover.1647167475.git.kai.huang@intel.com>

Initialize TDMRs via TDH.SYS.TDMR.INIT as the last step to complete the
TDX initialization.

All TDMRs need to be initialized using TDH.SYS.TDMR.INIT SEAMCALL before
the TDX memory can be used to run any TD guest.  The SEAMCALL internally
uses the global KeyID to initialize PAMTs in order to crypto protect
them from malicious host kernel.  TDH.SYS.TDMR.INIT can be done any cpu.

The time of initializing TDMR is proportional to the size of the TDMR.
To avoid long latency caused in one SEAMCALL, TDH.SYS.TDMR.INIT only
initializes an (implementation-specific) subset of PAMT entries of one
TDMR in one invocation.  The caller is responsible for calling
TDH.SYS.TDMR.INIT iteratively until all PAMT entries of the requested
TDMR are initialized.

Current implementation initializes TDMRs one by one.  It takes ~100ms on
a 2-socket machine with 2.2GHz CPUs and 64GB memory when the system is
idle.  Each TDH.SYS.TDMR.INIT takes ~7us on average.

TDX does allow different TDMRs to be initialized concurrently on
multiple CPUs. This parallel scheme could be introduced later when the
total initialization time becomes a real concern, e.g. on a platform
with a much bigger memory size.

Signed-off-by: Kai Huang <kai.huang@intel.com>
---
 arch/x86/virt/vmx/tdx.c | 75 ++++++++++++++++++++++++++++++++++++++---
 arch/x86/virt/vmx/tdx.h |  1 +
 2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/arch/x86/virt/vmx/tdx.c b/arch/x86/virt/vmx/tdx.c
index 39b1b7d0417d..f2b9c98191ed 100644
--- a/arch/x86/virt/vmx/tdx.c
+++ b/arch/x86/virt/vmx/tdx.c
@@ -1370,6 +1370,65 @@ static int config_global_keyid(u64 global_keyid)
 	return seamcall_on_each_package_serialized(&sc);
 }
 
+/* Initialize one TDMR */
+static int init_tdmr(struct tdmr_info *tdmr)
+{
+	u64 next;
+
+	/*
+	 * Initializing PAMT entries might be time-consuming (in
+	 * proportion to the size of the requested TDMR).  To avoid long
+	 * latency in one SEAMCALL, TDH.SYS.TDMR.INIT only initializes
+	 * an (implementation-defined) subset of PAMT entries in one
+	 * invocation.
+	 *
+	 * Call TDH.SYS.TDMR.INIT iteratively until all PAMT entries
+	 * of the requested TDMR are initialized (if next-to-initialize
+	 * address matches the end address of the TDMR).
+	 */
+	do {
+		struct tdx_module_output out;
+		int ret;
+
+		ret = seamcall(TDH_SYS_TDMR_INIT, tdmr->base, 0, 0, 0,
+				NULL, &out);
+		if (ret)
+			return ret;
+		/*
+		 * RDX contains 'next-to-initialize' address if
+		 * TDH.SYS.TDMR.INT succeeded.
+		 */
+		next = out.rdx;
+		if (need_resched())
+			cond_resched();
+	} while (next < tdmr->base + tdmr->size);
+
+	return 0;
+}
+
+/* Initialize all TDMRs */
+static int init_tdmrs(struct tdmr_info **tdmr_array, int tdmr_num)
+{
+	int i;
+
+	/*
+	 * Initialize TDMRs one-by-one for simplicity, though the TDX
+	 * architecture does allow different TDMRs to be initialized in
+	 * parallel on multiple CPUs.  Parallel initialization could
+	 * be added later when the time spent in the serialized scheme
+	 * becomes a real concern.
+	 */
+	for (i = 0; i < tdmr_num; i++) {
+		int ret;
+
+		ret = init_tdmr(tdmr_array[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int init_tdx_module(void)
 {
 	struct tdmr_info **tdmr_array;
@@ -1451,11 +1510,12 @@ static int init_tdx_module(void)
 	if (ret)
 		goto out_free_pamts;
 
-	/*
-	 * Return -EFAULT until all steps of TDX module
-	 * initialization are done.
-	 */
-	ret = -EFAULT;
+	/* Initialize TDMRs to complete the TDX module initialization */
+	ret = init_tdmrs(tdmr_array, tdmr_num);
+	if (ret)
+		goto out_free_pamts;
+
+	tdx_module_status = TDX_MODULE_INITIALIZED;
 out_free_pamts:
 	/*
 	 * Free PAMTs allocated in construct_tdmrs() when TDX module
@@ -1478,6 +1538,11 @@ static int init_tdx_module(void)
 	free_tdmrs(tdmr_array, tdmr_num);
 	kfree(tdmr_array);
 out:
+	if (ret)
+		pr_info("Failed to initialize TDX module.\n");
+	else
+		pr_info("TDX module initialized.\n");
+
 	return ret;
 }
 
diff --git a/arch/x86/virt/vmx/tdx.h b/arch/x86/virt/vmx/tdx.h
index bba8cabea4bb..212f83374c0a 100644
--- a/arch/x86/virt/vmx/tdx.h
+++ b/arch/x86/virt/vmx/tdx.h
@@ -126,6 +126,7 @@ struct tdmr_info {
 #define TDH_SYS_INFO		32
 #define TDH_SYS_INIT		33
 #define TDH_SYS_LP_INIT		35
+#define TDH_SYS_TDMR_INIT	36
 #define TDH_SYS_LP_SHUTDOWN	44
 #define TDH_SYS_CONFIG		45
 
-- 
2.35.1


  parent reply	other threads:[~2022-03-13 10:51 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-13 10:49 [PATCH v2 00/21] TDX host kernel support Kai Huang
2022-03-13 10:49 ` [PATCH v2 01/21] x86/virt/tdx: Detect SEAM Kai Huang
2022-03-23  3:21   ` Tian, Kevin
2022-03-28  3:55     ` Kai Huang
2022-03-28  8:10       ` Tian, Kevin
2022-03-29 17:52         ` Isaku Yamahata
2022-03-29 23:28           ` Kai Huang
2022-03-13 10:49 ` [PATCH v2 02/21] x86/virt/tdx: Detect TDX private KeyIDs Kai Huang
2022-03-13 10:49 ` [PATCH v2 03/21] x86/virt/tdx: Implement the SEAMCALL base function Kai Huang
2022-03-23  3:35   ` Tian, Kevin
2022-03-28  1:41     ` Kai Huang
2022-03-28  8:16       ` Tian, Kevin
2022-03-28  9:10         ` Kai Huang
2022-03-13 10:49 ` [PATCH v2 04/21] x86/virt/tdx: Add skeleton for detecting and initializing TDX on demand Kai Huang
2022-03-23  6:49   ` Tian, Kevin
2022-03-28  1:57     ` Kai Huang
2022-03-28  8:26       ` Tian, Kevin
2022-03-28  9:24         ` Kai Huang
2022-03-28 11:47           ` Tian, Kevin
2022-03-28 22:55             ` Kai Huang
2022-03-29  2:36               ` Tian, Kevin
2022-03-29  3:10                 ` Kai Huang
2022-03-29  3:17                   ` Kai Huang
2022-03-13 10:49 ` [PATCH v2 05/21] x86/virt/tdx: Detect P-SEAMLDR and TDX module Kai Huang
2022-03-13 10:49 ` [PATCH v2 06/21] x86/virt/tdx: Shut down TDX module in case of error Kai Huang
2022-03-13 10:49 ` [PATCH v2 07/21] x86/virt/tdx: Do TDX module global initialization Kai Huang
2022-03-13 10:49 ` [PATCH v2 08/21] x86/virt/tdx: Do logical-cpu scope TDX module initialization Kai Huang
2022-03-13 10:49 ` [PATCH v2 09/21] x86/virt/tdx: Get information about TDX module and convertible memory Kai Huang
2022-03-24 17:43   ` Isaku Yamahata
2022-03-28  1:30     ` Kai Huang
2022-03-28 20:22       ` Isaku Yamahata
2022-03-28 20:30         ` Dave Hansen
2022-03-28 23:40           ` Kai Huang
2022-03-28 23:44             ` Dave Hansen
2022-03-29  0:04               ` Kai Huang
2022-03-13 10:49 ` [PATCH v2 10/21] x86/virt/tdx: Add placeholder to coveret all system RAM as TDX memory Kai Huang
2022-03-13 10:49 ` [PATCH v2 11/21] x86/virt/tdx: Choose to use " Kai Huang
2022-03-13 10:49 ` [PATCH v2 12/21] x86/virt/tdx: Create TDMRs to cover all system RAM Kai Huang
2022-03-13 10:49 ` [PATCH v2 13/21] x86/virt/tdx: Allocate and set up PAMTs for TDMRs Kai Huang
2022-03-24 18:06   ` Isaku Yamahata
2022-03-28  1:16     ` Kai Huang
2022-03-13 10:49 ` [PATCH v2 14/21] x86/virt/tdx: Set up reserved areas for all TDMRs Kai Huang
2022-03-13 10:49 ` [PATCH v2 15/21] x86/virt/tdx: Reserve TDX module global KeyID Kai Huang
2022-03-13 10:49 ` [PATCH v2 16/21] x86/virt/tdx: Configure TDX module with TDMRs and " Kai Huang
2022-03-13 10:49 ` [PATCH v2 17/21] x86/virt/tdx: Configure global KeyID on all packages Kai Huang
2022-03-24 18:18   ` isaku.yamahata
2022-03-28  1:19     ` Kai Huang
2022-03-13 10:49 ` Kai Huang [this message]
2022-03-13 10:49 ` [PATCH v2 19/21] x86: Flush cache of TDX private memory during kexec() Kai Huang
2022-03-13 10:50 ` [PATCH v2 20/21] x86/virt/tdx: Add kernel command line to opt-in TDX host support Kai Huang
2022-03-13 10:50 ` [PATCH v2 21/21] Documentation/x86: Add documentation for " Kai Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3af7ece5cf86dfe83f755b7a7c541d8f691e4133.1647167475.git.kai.huang@intel.com \
    --to=kai.huang@intel.com \
    --cc=ak@linux.intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=isaku.yamahata@intel.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=seanjc@google.com \
    --cc=tony.luck@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).