lkml.org 
[lkml]   [2023]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [PATCH v8 14/16] x86/virt/tdx: Initialize all TDMRs
    From
    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 {

    \
     
     \ /
      Last update: 2023-03-26 23:31    [W:4.112 / U:1.376 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site