Skip to content

Commit 0b2bc38

Browse files
kaihuanghansendc
authored andcommitted
x86/virt/tdx: Initialize all TDMRs
After the global KeyID has been configured on all packages, initialize all TDMRs to make all TDX-usable memory regions that are passed to the TDX module become usable. This is the last step of initializing the TDX module. Initializing TDMRs can be time consuming on large memory systems as it involves initializing all metadata entries for all pages that can be used by TDX guests. Initializing different TDMRs can be parallelized. For now to keep it simple, just initialize all TDMRs one by one. It can be enhanced in the future. Signed-off-by: Kai Huang <kai.huang@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Isaku Yamahata <isaku.yamahata@intel.com> Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Reviewed-by: Yuan Yao <yuan.yao@intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lore.kernel.org/all/20231208170740.53979-15-dave.hansen%40intel.com
1 parent e56d28d commit 0b2bc38

2 files changed

Lines changed: 53 additions & 9 deletions

File tree

arch/x86/virt/vmx/tdx/tdx.c

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,56 @@ static int config_global_keyid(void)
10341034
return ret;
10351035
}
10361036

1037+
static int init_tdmr(struct tdmr_info *tdmr)
1038+
{
1039+
u64 next;
1040+
1041+
/*
1042+
* Initializing a TDMR can be time consuming. To avoid long
1043+
* SEAMCALLs, the TDX module may only initialize a part of the
1044+
* TDMR in each call.
1045+
*/
1046+
do {
1047+
struct tdx_module_args args = {
1048+
.rcx = tdmr->base,
1049+
};
1050+
int ret;
1051+
1052+
ret = seamcall_prerr_ret(TDH_SYS_TDMR_INIT, &args);
1053+
if (ret)
1054+
return ret;
1055+
/*
1056+
* RDX contains 'next-to-initialize' address if
1057+
* TDH.SYS.TDMR.INIT did not fully complete and
1058+
* should be retried.
1059+
*/
1060+
next = args.rdx;
1061+
cond_resched();
1062+
/* Keep making SEAMCALLs until the TDMR is done */
1063+
} while (next < tdmr->base + tdmr->size);
1064+
1065+
return 0;
1066+
}
1067+
1068+
static int init_tdmrs(struct tdmr_info_list *tdmr_list)
1069+
{
1070+
int i;
1071+
1072+
/*
1073+
* This operation is costly. It can be parallelized,
1074+
* but keep it simple for now.
1075+
*/
1076+
for (i = 0; i < tdmr_list->nr_consumed_tdmrs; i++) {
1077+
int ret;
1078+
1079+
ret = init_tdmr(tdmr_entry(tdmr_list, i));
1080+
if (ret)
1081+
return ret;
1082+
}
1083+
1084+
return 0;
1085+
}
1086+
10371087
static int init_tdx_module(void)
10381088
{
10391089
struct tdx_tdmr_sysinfo tdmr_sysinfo;
@@ -1079,15 +1129,8 @@ static int init_tdx_module(void)
10791129
if (ret)
10801130
goto err_reset_pamts;
10811131

1082-
/*
1083-
* TODO:
1084-
*
1085-
* - Configure the global KeyID on all packages.
1086-
* - Initialize all TDMRs.
1087-
*
1088-
* Return error before all steps are done.
1089-
*/
1090-
ret = -EINVAL;
1132+
/* Initialize TDMRs to complete the TDX module initialization */
1133+
ret = init_tdmrs(&tdx_tdmr_list);
10911134
if (ret)
10921135
goto err_reset_pamts;
10931136

arch/x86/virt/vmx/tdx/tdx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define TDH_SYS_INIT 33
1919
#define TDH_SYS_RD 34
2020
#define TDH_SYS_LP_INIT 35
21+
#define TDH_SYS_TDMR_INIT 36
2122
#define TDH_SYS_CONFIG 45
2223

2324
/*

0 commit comments

Comments
 (0)