[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8e46f932-8ec9-0621-4423-e6233747b231@intel.com>
Date: Fri, 6 Jan 2023 16:17:32 -0800
From: Dave Hansen <dave.hansen@...el.com>
To: Kai Huang <kai.huang@...el.com>, linux-kernel@...r.kernel.org,
kvm@...r.kernel.org
Cc: linux-mm@...ck.org, peterz@...radead.org, tglx@...utronix.de,
seanjc@...gle.com, pbonzini@...hat.com, dan.j.williams@...el.com,
rafael.j.wysocki@...el.com, kirill.shutemov@...ux.intel.com,
ying.huang@...el.com, reinette.chatre@...el.com,
len.brown@...el.com, tony.luck@...el.com, ak@...ux.intel.com,
isaku.yamahata@...el.com, chao.gao@...el.com,
sathyanarayanan.kuppuswamy@...ux.intel.com, bagasdotme@...il.com,
sagis@...gle.com, imammedo@...hat.com
Subject: Re: [PATCH v8 14/16] x86/virt/tdx: Initialize all TDMRs
On 12/8/22 22:52, Kai Huang wrote:
> 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 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.
The changelog probably also needs a note about this being a long process
and also at least touching on *why* it takes so long.
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index 4c779e8412f1..8b7314f19df2 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.c
> +++ b/arch/x86/virt/vmx/tdx/tdx.c
> @@ -1006,6 +1006,55 @@ static int config_global_keyid(void)
> return ret;
> }
>
> +static int init_tdmr(struct tdmr_info *tdmr)
> +{
> + u64 next;
> +
> + /*
> + * Initializing a TDMR can be time consuming. To avoid long
> + * SEAMCALLs, the TDX module may only initialize a part of the
> + * TDMR in each call.
> + */
> + do {
> + struct tdx_module_output out;
> + int ret;
> +
> + /* All 0's are unused parameters, they mean nothing. */
> + 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.
This reads strangely. "Success" to me really is different from "partial
success". Sure, partial success is also not an error, *but* this can be
explained better. How about:
* RDX contains 'next-to-initialize' address if
* TDH.SYS.TDMR.INT did not fully complete and should
* be retried.
> + */
> + next = out.rdx;
> + cond_resched();
> + /* Keep making SEAMCALLs until the TDMR is done */
> + } while (next < tdmr->base + tdmr->size);
> +
> + return 0;
> +}
> +
> +static int init_tdmrs(struct tdmr_info_list *tdmr_list)
> +{
> + int i;
> +
> + /*
> + * This operation is costly. It can be parallelized,
> + * but keep it simple for now.
> + */
> + for (i = 0; i < tdmr_list->nr_tdmrs; i++) {
> + int ret;
> +
> + ret = init_tdmr(tdmr_entry(tdmr_list, i));
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static int init_tdx_module(void)
> {
> /*
> @@ -1076,14 +1125,10 @@ static int init_tdx_module(void)
> if (ret)
> goto out_free_pamts;
>
> - /*
> - * TODO:
> - *
> - * - Initialize all TDMRs.
> - *
> - * Return error before all steps are done.
> - */
> - ret = -EINVAL;
> + /* Initialize TDMRs to complete the TDX module initialization */
> + ret = init_tdmrs(&tdmr_list);
> + if (ret)
> + goto out_free_pamts;
> out_free_pamts:
> if (ret) {
> /*
> diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
> index f5c12a2543d4..163c4876dee4 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.h
> +++ b/arch/x86/virt/vmx/tdx/tdx.h
> @@ -21,6 +21,7 @@
> */
> #define TDH_SYS_KEY_CONFIG 31
> #define TDH_SYS_INFO 32
> +#define TDH_SYS_TDMR_INIT 36
> #define TDH_SYS_CONFIG 45
>
> struct cmr_info {
Powered by blists - more mailing lists