On Fri, 2023-01-06 at 11:36 -0800, Dave Hansen wrote: > On 12/8/22 22:52, Kai Huang wrote: > > Start to transit out the "multi-steps" to construct a list of "TD Memory > > Regions" (TDMRs) to cover all TDX-usable memory regions. > > > > The kernel configures TDX-usable memory regions by passing a list of > > TDMRs "TD Memory Regions" (TDMRs) to the TDX module. Each TDMR contains > > the information of the base/size of a memory region, the base/size of the > > associated Physical Address Metadata Table (PAMT) and a list of reserved > > areas in the region. > > > > Do the first step to fill out a number of TDMRs to cover all TDX memory > > regions. To keep it simple, always try to use one TDMR for each memory > > region. As the first step only set up the base/size for each TDMR. > > > > Each TDMR must be 1G aligned and the size must be in 1G granularity. > > This implies that one TDMR could cover multiple memory regions. If a > > memory region spans the 1GB boundary and the former part is already > > covered by the previous TDMR, just use a new TDMR for the remaining > > part. > > > > TDX only supports a limited number of TDMRs. Disable TDX if all TDMRs > > are consumed but there is more memory region to cover. > > This could probably use some discussion of why it is not being > future-proofed. Maybe: > > There are fancier things that could be done like trying to merge > adjacent TDMRs. This would allow more pathological memory > layouts to be supported. But, current systems are not even > close to exhausting the existing TDMR resources in practice. > For now, keep it simple. Looks great. Thanks. > > > diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c > > index d36ac72ef299..5b1de0200c6b 100644 > > --- a/arch/x86/virt/vmx/tdx/tdx.c > > +++ b/arch/x86/virt/vmx/tdx/tdx.c > > @@ -407,6 +407,90 @@ static void free_tdmr_list(struct tdmr_info_list *tdmr_list) > > tdmr_list->max_tdmrs * tdmr_list->tdmr_sz); > > } > > > > +/* Get the TDMR from the list at the given index. */ > > +static struct tdmr_info *tdmr_entry(struct tdmr_info_list *tdmr_list, > > + int idx) > > +{ > > + return (struct tdmr_info *)((unsigned long)tdmr_list->first_tdmr + > > + tdmr_list->tdmr_sz * idx); > > +} > > I think that's more complicated and has more casting than necessary. > This looks nicer: > > int tdmr_info_offset = tdmr_list->tdmr_sz * idx; > > return (void *)tdmr_list->first_tdmr + tdmr_info_offset; > > Also, it might even be worth keeping ->first_tdmr as a void*. It isn't > a real C array and keeping it as void* would keep anyone from doing: > > tdmr_foo = tdmr_list->first_tdmr[foo]; Yes good point. Will do. [snip] > > Otherwise this actually looks fine. Thanks.