On Fri, Nov 22, 2024, Dave Hansen wrote: > On 11/15/24 12:20, Rick Edgecombe wrote: > > +struct tdx_td { > > + hpa_t tdr; > > + hpa_t *tdcs; > > +}; > > This is a step in the right direction because it gives the wrappers some > more type safety. > > But an hpa_t is _barely_ better than a u64. If the 'tdr' is a page, > then it needs to be _stored_ as a page: > > struct page *tdr_page; > > Also, please don't forget to spell these things out: > > /* TD root structure: */ > struct page *tdr_page; > > And the tdcs is an array of pages, right? So it should be: > > struct page **tdcs_pages; > > Or heck, I _think_ it can theoretically be defined as a variable-length > array: > > struct page *tdcs_pages[]; > > and use the helpers that we have for that. > > Putting it all together, you would have this: > > struct tdx_td { > /* TD root structure: */ > struct page *tdr_page; > > int tdcs_nr_pages; > /* TD control structure: */ > struct page *tdcs_pages[]; > }; > > That's *MUCH* harder to misuse. It's 100% obvious that you have a > single page, plus a variable-length array of pages. This is all from > just looking at the structure definition. I don't know the full context, but working with "struct page" is a pain when every user just wants the physical address. KVM SVM had a few cases where pointers were tracked as "struct page", and it was generally unpleasant to read and work with. I also don't like conflating the kernel's "struct page" with the architecture's definition of a 4KiB page. > You know that 'tdr' is not just some random physical address. It's a > whole physical page. It's page-aligned. It was allocated, from the > allocator. It doesn't point to special memory. Oh, but it does point to special memory. If it *didn't* point at special memory that is completely opaque and untouchable, then KVM could use a struct overlay, which would give contextual information and some amount of type safety. E.g. an equivalent without TDX is "struct vmcs *". Rather than "struct page", what if we add an address_space (in the Sparse sense), and a typedef for a TDX pages? Maybe __firmware? E.g. # define __firmware __attribute__((noderef, address_space(__firmware))) typedef u64 __firmware *tdx_page_t; That doesn't give as much compile-time safety, but in some ways it provides more type safety since KVM (or whatever else cares) would need to make an explicit and ugly cast to misuse the pointer. > Ditto for "hpa_t *tdcs". It's not obvious from the data structure that > it's an array or if it's an array how it got allocated or how large it is.