[PATCH v2 01/25] x86/virt/tdx: Share the global metadata structure for KVM to use

Rick Edgecombe posted 25 patches 3 weeks, 4 days ago
[PATCH v2 01/25] x86/virt/tdx: Share the global metadata structure for KVM to use
Posted by Rick Edgecombe 3 weeks, 4 days ago
From: Kai Huang <kai.huang@intel.com>

The TDX host tracks all global metadata fields in 'struct tdx_sys_info'.
For now they are only used by module initialization and are not shared
to other kernel components.

Future changes to support KVM TDX will need to read more global metadata
fields, e.g., those in "TD Control Structures" and "TD Configurability".
In the longer term, other TDX features like TDX Connect (which supports
assigning trusted devices to TDX guests) will also require other kernel
components such as pci/vt-d to access global metadata.

To meet all those requirements, the idea is the TDX host core-kernel to
to provide a centralized, canonical, and read-only structure for the
global metadata that comes out from the TDX module for all kernel
components to use.

To achieve "read-only", the ideal way is to annotate the whole structure
with __ro_after_init.  However currently all global metadata fields are
read by tdx_enable(), which could be called at any time at runtime thus
isn't annotated with __init.

The __ro_after_init can be done eventually, but it can only be done
after moving VMXON out of KVM to the core-kernel: after that we can
read all metadata during kernel boot (thus __ro_after_init), but
doesn't necessarily have to do it in tdx_enable().

For now, add a helper function to return a 'const struct tdx_sys_info *'
and export it for KVM to use.

Note, KVM doesn't need to access all global metadata for TDX, thus
exporting the entire 'struct tdx_sys_info' is overkill.  Another option
is to export sub-structures on demand.  But this will result in more
exports.  Given the export is done via a const pointer thus the other
in-kernel TDX won't be able to write to global metadata, simply export
all global metadata fields in one function.

The auto-generated 'tdx_global_metadata.h' contains declarations of
'struct tdx_sys_info' and its sub-structures.  Move it to
arch/x86/include/asm/ and include it to <asm/tdx.h> to expose those
structures.

Include 'tdx_global_metadata.h' inside the '#ifndef __ASSEMBLY__' since
otherwise there will be build warning due to <asm/tdx.h> is also
included by assembly.

Signed-off-by: Kai Huang <kai.huang@intel.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
uAPI breakout v2:
 - New patch
---
 arch/x86/include/asm/tdx.h                    |  3 ++
 .../tdx => include/asm}/tdx_global_metadata.h |  0
 arch/x86/virt/vmx/tdx/tdx.c                   | 28 +++++++++++++++----
 arch/x86/virt/vmx/tdx/tdx.h                   |  1 -
 4 files changed, 25 insertions(+), 7 deletions(-)
 rename arch/x86/{virt/vmx/tdx => include/asm}/tdx_global_metadata.h (100%)

diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index eba178996d84..b9758369d82c 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -33,6 +33,7 @@
 #ifndef __ASSEMBLY__
 
 #include <uapi/asm/mce.h>
+#include "tdx_global_metadata.h"
 
 /*
  * Used by the #VE exception handler to gather the #VE exception
@@ -116,11 +117,13 @@ static inline u64 sc_retry(sc_func_t func, u64 fn,
 int tdx_cpu_enable(void);
 int tdx_enable(void);
 const char *tdx_dump_mce_info(struct mce *m);
+const struct tdx_sys_info *tdx_get_sysinfo(void);
 #else
 static inline void tdx_init(void) { }
 static inline int tdx_cpu_enable(void) { return -ENODEV; }
 static inline int tdx_enable(void)  { return -ENODEV; }
 static inline const char *tdx_dump_mce_info(struct mce *m) { return NULL; }
+static inline const struct tdx_sys_info *tdx_get_sysinfo(void) { return NULL; }
 #endif	/* CONFIG_INTEL_TDX_HOST */
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
similarity index 100%
rename from arch/x86/virt/vmx/tdx/tdx_global_metadata.h
rename to arch/x86/include/asm/tdx_global_metadata.h
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 6982e100536d..7589c75eaa6c 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -52,6 +52,8 @@ static DEFINE_MUTEX(tdx_module_lock);
 /* All TDX-usable memory regions.  Protected by mem_hotplug_lock. */
 static LIST_HEAD(tdx_memlist);
 
+static struct tdx_sys_info tdx_sysinfo;
+
 typedef void (*sc_err_func_t)(u64 fn, u64 err, struct tdx_module_args *args);
 
 static inline void seamcall_err(u64 fn, u64 err, struct tdx_module_args *args)
@@ -1132,15 +1134,14 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_list)
 
 static int init_tdx_module(void)
 {
-	struct tdx_sys_info sysinfo;
 	int ret;
 
-	ret = init_tdx_sys_info(&sysinfo);
+	ret = init_tdx_sys_info(&tdx_sysinfo);
 	if (ret)
 		return ret;
 
 	/* Check whether the kernel can support this module */
-	ret = check_features(&sysinfo);
+	ret = check_features(&tdx_sysinfo);
 	if (ret)
 		return ret;
 
@@ -1161,13 +1162,14 @@ static int init_tdx_module(void)
 		goto out_put_tdxmem;
 
 	/* Allocate enough space for constructing TDMRs */
-	ret = alloc_tdmr_list(&tdx_tdmr_list, &sysinfo.tdmr);
+	ret = alloc_tdmr_list(&tdx_tdmr_list, &tdx_sysinfo.tdmr);
 	if (ret)
 		goto err_free_tdxmem;
 
 	/* Cover all TDX-usable memory regions in TDMRs */
-	ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr,
-			&sysinfo.cmr);
+	ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list,
+			      &tdx_sysinfo.tdmr, &tdx_sysinfo.cmr);
+
 	if (ret)
 		goto err_free_tdmrs;
 
@@ -1529,3 +1531,17 @@ void __init tdx_init(void)
 
 	check_tdx_erratum();
 }
+
+const struct tdx_sys_info *tdx_get_sysinfo(void)
+{
+	const struct tdx_sys_info *p = NULL;
+
+	/* Make sure all fields in @tdx_sysinfo have been populated */
+	mutex_lock(&tdx_module_lock);
+	if (tdx_module_status == TDX_MODULE_INITIALIZED)
+		p = (const struct tdx_sys_info *)&tdx_sysinfo;
+	mutex_unlock(&tdx_module_lock);
+
+	return p;
+}
+EXPORT_SYMBOL_GPL(tdx_get_sysinfo);
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
index c8be00f6b15a..9b708a8fb568 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -6,7 +6,6 @@
 #include <linux/compiler_attributes.h>
 #include <linux/stddef.h>
 #include <linux/bits.h>
-#include "tdx_global_metadata.h"
 
 /*
  * This file contains both macros and data structures defined by the TDX
-- 
2.47.0