On Wed, 5 Jun 2024 at 06:36, Kalra, Ashish <ashish.kalra@xxxxxxx> wrote: > > Re-sending as the earlier response got line-wrapped. > > On 6/3/2024 12:12 PM, Borislav Petkov wrote: > > On Mon, Jun 03, 2024 at 12:08:48PM -0500, Kalra, Ashish wrote: > >> efi_arch_mem_reserve(). > > Now it only remains for you to explain why... > > Here is a detailed explanation of what is causing the EFI memory map corruption, with added debug logs and memblock debugging enabled: > > Initially at boot, efi_memblock_x86_reserve_range() does early_memremap() of the EFI memory map passed as part of setup_data, as the following logs show: > > ... > > [ 0.000000] efi: in efi_memblock_x86_reserve_range, phys map 0x27fff9110 > [ 0.000000] memblock_reserve: [0x000000027fff9110-0x000000027fffa12f] efi_memblock_x86_reserve_range+0x168/0x2a0 > > ... > > Later, efi_arch_mem_reserve() is invoked, which calls efi_memmap_alloc() which does memblock_phys_alloc() to insert new EFI memory descriptor into efi.memap: > > ... > > [ 0.733263] memblock_reserve: [0x000000027ffcaf80-0x000000027ffcbfff] memblock_alloc_range_nid+0xf1/0x1b0 > [ 0.734787] efi: efi_arch_mem_reserve, efi phys map 0x27ffcaf80 > > ... > > Finally, at the end of boot, kexec_enter_virtual_mode() is called. > > It does mapping of efi regions which were passed via setup_data. > > So it unregisters the early mem-remapped EFI memmap and installs the new EFI memory map as below: > > ( Because of efi_arch_mem_reserve() getting invoked, the new EFI memmap phys base being remapped now is the memblock allocation done in efi_arch_mem_reserve()). > > [ 4.042160] efi: efi memmap phys map 0x27ffcaf80 > > So, kexec_enter_virtual_mode() does the following : > > if (efi_memmap_init_late(efi.memmap.phys_map, <- refers to the new EFI memmap phys base allocated via memblock in efi_arch_mem_reserve(). > efi.memmap.desc_size * efi.memmap.nr_map)) { ... > > This late init, does a memremap() on this memblock-allocated memory, but then immediately frees it : > > drivers/firmware/efi/memmap.c: > > int __init __efi_memmap_init(struct efi_memory_map_data *data) > { > > .. > > phys_map = data->phys_map; <- refers to the new EFI memmap phys base allocated via memblock in efi_arch_mem_reserve(). > > if (data->flags & EFI_MEMMAP_LATE) > map.map = memremap(phys_map, data->size, MEMREMAP_WB); > ... > ... > if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB)) { > __efi_memmap_free(efi.memmap.phys_map, > efi.memmap.desc_size * efi.memmap.nr_map, efi.memmap.flags); > }