AMD SEV-SNP/Intel TDX: validation of memory pages

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everybody,

I'd like to kick-start the discussion on lazy validation of guest memory
for the purposes of AMD SEV-SNP and Intel TDX.

Both AMD SEV-SNP and Intel TDX require validation of guest memory before
it may be used by the guest.  This is needed for integrity protection from
a potentially malicious hypervisor or other host components.

For AMD SEV-SNP, the hypervisor assigns a page to the guest using the new
RMPUPDATE instruction.  The guest then transitions the page to a usable by
the new PVALIDATE instruction[1].  This sets the Validated flag in the
Reverse Map Table (RMP) for a guest addressable page, which opts into
hardware and firmware integrity protection.  This may only be done by the
guest itself and until that time, the guest cannot access the page.

The guest can only PVALIDATE memory for a gPA once; the RMP then
guarantees for each hPA that there is only a single gPA mapping.  This
validation can either be done all up front at the time the guest is booted
or it can be done lazily at runtime on fault if the guest keeps track of
Valid vs Invalid pages.  Because doing PVALIDATE for all guest memory at
boot would be extremely lengthy, I'd like to discuss the options for doing
it lazily.

Similarly, for Intel TDX, the hypervisor unmaps the gPA from the shared
EPT and invalidates the tlb and all caches for the TD's vcpus; it then
adds a page to the gPA address space for a TD by using the new
TDH.MEM.PAGE.AUG call.  The TDG.MEM.PAGE.ACCEPT TDCALL[2] then allows a
guest to accept a guest page for a gPA and initialize it using the private
key for that TD.  This may only be done by the TD itself and until that
time, the gPA cannot be used within the TD.

Both AMD SEV-SNP and Intel TDX support hugepages.  SEV-SNP supports 2MB
whereas TDX has accept TDCALL support for 2MB and 1GB.

I believe the UEFI ECR[3] for the unaccepted memory type to
EFI_MEMORY_TYPE was accepted in December.  This should enable the guest to
learn what memory has not yet been validated (or accepted) by the firmware
if all guest memory is not done completely up front.

This likely requires a pre-validation of all memory that can be accessed
when handling a #VC (or #VE for TDX) such as IST stacks, including memory
in the x86 boot sequence that must be validated before the core mm
subsystem is up and running to handle the lazy validation.  I believe
lazy validation can be done by the core mm after that, perhaps by
maintaining a new "validated" bit in struct page flags.

Has anybody looked into this or, even better, is anybody currently working
on this?

I think quite invasive changes are needed for the guest to support lazy
validation/acceptance to core areas that lots of people on the recipient
list have strong opinions about.  Some things that come to mind:

 - Annotations for pages that must be pre-validated in the x86 boot
   sequence, including IST stacks

 - Proliferation of these annotations throughout any kernel code that can
   access memory for #VC or #VE

 - Handling lazy validation of guest memory through the core mm layer,
   most likely involving a bit in struct page flags to track their status

 - Any need for validating memory that is not backed by struct page that
   needs to be special-cased

 - Any concerns about this for the DMA layer

One possibility for minimal disruption to the boot entry code is to
require the guest BIOS to validate 4GB and below, and then leave 4GB and
above to be done lazily (the true amount of memory will actually be less
due to the MMIO hole).

Thanks!

 [1] https://www.amd.com/system/files/TechDocs/56860.pdf
 [2] https://software.intel.com/content/dam/develop/external/us/en/documents/intel-tdx-module-1eas.pdf
 [3] https://github.com/microsoft/mu_basecore/blob/aa16ee6518b521a7d8101c34d2884ae09ef78bce/Unaccepted%20Memory%20UEFI%20ECR.md




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux