efi/libstub: Implement support for unaccepted memory
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Tue, 6 Jun 2023 14:26:31 +0000 (17:26 +0300)
committerBorislav Petkov (AMD) <bp@alien8.de>
Tue, 6 Jun 2023 14:58:23 +0000 (16:58 +0200)
commit745e3ed85f71a6382a239b03d9278a8025f2beae
treeaf0b35cb1821223b4546dba8ec3453c75ef1f3e1
parent2e9f46ee1599be8a50a5366eb3ef4a4b5acff0b7
efi/libstub: Implement support for unaccepted memory

UEFI Specification version 2.9 introduces the concept of memory
acceptance: Some Virtual Machine platforms, such as Intel TDX or AMD
SEV-SNP, requiring memory to be accepted before it can be used by the
guest. Accepting happens via a protocol specific for the Virtual
Machine platform.

Accepting memory is costly and it makes VMM allocate memory for the
accepted guest physical address range. It's better to postpone memory
acceptance until memory is needed. It lowers boot time and reduces
memory overhead.

The kernel needs to know what memory has been accepted. Firmware
communicates this information via memory map: a new memory type --
EFI_UNACCEPTED_MEMORY -- indicates such memory.

Range-based tracking works fine for firmware, but it gets bulky for
the kernel: e820 (or whatever the arch uses) has to be modified on every
page acceptance. It leads to table fragmentation and there's a limited
number of entries in the e820 table.

Another option is to mark such memory as usable in e820 and track if the
range has been accepted in a bitmap. One bit in the bitmap represents a
naturally aligned power-2-sized region of address space -- unit.

For x86, unit size is 2MiB: 4k of the bitmap is enough to track 64GiB or
physical address space.

In the worst-case scenario -- a huge hole in the middle of the
address space -- It needs 256MiB to handle 4PiB of the address
space.

Any unaccepted memory that is not aligned to unit_size gets accepted
upfront.

The bitmap is allocated and constructed in the EFI stub and passed down
to the kernel via EFI configuration table. allocate_e820() allocates the
bitmap if unaccepted memory is present, according to the size of
unaccepted region.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20230606142637.5171-4-kirill.shutemov@linux.intel.com
12 files changed:
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/mem.c [new file with mode: 0644]
arch/x86/include/asm/efi.h
drivers/firmware/efi/Kconfig
drivers/firmware/efi/efi.c
drivers/firmware/efi/libstub/Makefile
drivers/firmware/efi/libstub/bitmap.c [new file with mode: 0644]
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/find.c [new file with mode: 0644]
drivers/firmware/efi/libstub/unaccepted_memory.c [new file with mode: 0644]
drivers/firmware/efi/libstub/x86-stub.c
include/linux/efi.h