@@ -26,6 +26,7 @@
#include <linux/pfn.h>
#include <linux/align.h>
#include <linux/sort.h>
+#include <linux/log2.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
#include <asm/page.h>
@@ -900,6 +901,41 @@ static int construct_tdmrs(struct list_head *tmb_list,
return ret;
}
+static int config_tdx_module(struct tdmr_info_list *tdmr_list, u64 global_keyid)
+{
+ struct tdx_module_args args = {};
+ u64 *tdmr_pa_array;
+ size_t array_sz;
+ int i, ret;
+
+ /*
+ * TDMRs are passed to the TDX module via an array of physical
+ * addresses of each TDMR. The array itself also has certain
+ * alignment requirement.
+ */
+ array_sz = tdmr_list->nr_consumed_tdmrs * sizeof(u64);
+ array_sz = roundup_pow_of_two(array_sz);
+ if (array_sz < TDMR_INFO_PA_ARRAY_ALIGNMENT)
+ array_sz = TDMR_INFO_PA_ARRAY_ALIGNMENT;
+
+ tdmr_pa_array = kzalloc(array_sz, GFP_KERNEL);
+ if (!tdmr_pa_array)
+ return -ENOMEM;
+
+ for (i = 0; i < tdmr_list->nr_consumed_tdmrs; i++)
+ tdmr_pa_array[i] = __pa(tdmr_entry(tdmr_list, i));
+
+ args.rcx = __pa(tdmr_pa_array);
+ args.rdx = tdmr_list->nr_consumed_tdmrs;
+ args.r8 = global_keyid;
+ ret = seamcall_prerr(TDH_SYS_CONFIG, &args);
+
+ /* Free the array as it is not required anymore. */
+ kfree(tdmr_pa_array);
+
+ return ret;
+}
+
static int init_tdx_module(void)
{
struct tdsysinfo_struct *tdsysinfo;
@@ -955,16 +991,21 @@ static int init_tdx_module(void)
if (ret)
goto out_free_tdmrs;
+ /* Pass the TDMRs and the global KeyID to the TDX module */
+ ret = config_tdx_module(&tdmr_list, tdx_global_keyid);
+ if (ret)
+ goto out_free_pamts;
+
/*
* TODO:
*
- * - Configure the TDMRs and the global KeyID to the TDX module.
* - Configure the global KeyID on all packages.
* - Initialize all TDMRs.
*
* Return error before all steps are done.
*/
ret = -EINVAL;
+out_free_pamts:
if (ret)
tdmrs_free_pamt_all(&tdmr_list);
else
@@ -19,6 +19,7 @@
#define TDH_SYS_INFO 32
#define TDH_SYS_INIT 33
#define TDH_SYS_LP_INIT 35
+#define TDH_SYS_CONFIG 45
struct cmr_info {
u64 base;
@@ -85,6 +86,7 @@ struct tdmr_reserved_area {
} __packed;
#define TDMR_INFO_ALIGNMENT 512
+#define TDMR_INFO_PA_ARRAY_ALIGNMENT 512
struct tdmr_info {
u64 base;