#include <linux/pfn.h>
 #include <linux/align.h>
 #include <linux/sort.h>
+#include <linux/log2.h>
+#include <asm/page.h>
 #include <asm/msr-index.h>
 #include <asm/msr.h>
 #include <asm/cpufeature.h>
        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 tdx_tdmr_sysinfo tdmr_sysinfo;
        if (ret)
                goto err_free_tdmrs;
 
+       /* Pass the TDMRs and the global KeyID to the TDX module */
+       ret = config_tdx_module(&tdx_tdmr_list, tdx_global_keyid);
+       if (ret)
+               goto err_free_pamts;
+
        /*
         * TODO:
         *
-        *  - Configure the TDMRs and the global KeyID to the TDX module.
         *  - Configure the global KeyID on all packages.
         *  - Initialize all TDMRs.
         *