Re: [PATCH] x86: efi: avoid BUILD_BUG_ON() for non-constant p4d_index
From: Ard Biesheuvel <ardb@kernel.org>
Date: 2021-02-03 20:30:17
Also in:
lkml, platform-driver-x86
On Wed, 3 Feb 2021 at 19:51, Nathan Chancellor [off-list ref] wrote:
On Wed, Jan 20, 2021 at 10:33:43AM +0100, Ard Biesheuvel wrote:quoted
On Mon, 18 Jan 2021 at 22:42, Arvind Sankar [off-list ref] wrote:quoted
On Mon, Jan 18, 2021 at 09:24:09PM +0100, Borislav Petkov wrote:quoted
quoted
quoted
quoted
As a matter of fact, it seems like the four assertions could be combined into: BUILD_BUG_ON((EFI_VA_END & P4D_MASK) != (MODULES_END & P4D_MASK)); BUILD_BUG_ON((EFI_VA_START & P4D_MASK) != (EFI_VA_END & P4D_MASK)); instead of separately asserting they're the same PGD entry and the same P4D entry. Thanks.I actually don't quite get the MODULES_END check -- Ard, do you know what that's for?Maybe Boris remembers? He wrote the original code for the 'new' EFI page table layout.That was added by Kirill for 5-level pgtables: e981316f5604 ("x86/efi: Add 5-level paging support")That just duplicates the existing pgd_index() check for the p4d_index() as well. It looks like the original commit adding efi_sync_low_kernel_mappings() used to copy upto the PGD entry including MODULES_END: d2f7cbe7b26a7 ("x86/efi: Runtime services virtual mapping") and then Matt changed that when creating efi_mm: 67a9108ed4313 ("x86/efi: Build our own page table structures") to use EFI_VA_END instead but have a check that EFI_VA_END is in the same entry as MODULES_END. AFAICT, MODULES_END is only relevant as being something that happens to be in the top 512GiB, and -1ul would be clearer.quoted
Documentation/x86/x86_64/mm.rst should explain the pagetable layout: ffffff8000000000 | -512 GB | ffffffeeffffffff | 444 GB | ... unused hole ffffffef00000000 | -68 GB | fffffffeffffffff | 64 GB | EFI region mapping space ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | ... unused hole ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | kernel text mapping, mapped to physical address 0 ffffffff80000000 |-2048 MB | | | ffffffffa0000000 |-1536 MB | fffffffffeffffff | 1520 MB | module mapping space ffffffffff000000 | -16 MB | | | FIXADDR_START | ~-11 MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset That thing which starts at -512 GB above is the last PGD on the pagetable. In it, between -4G and -68G there are 64G which are the EFI region mapping space for runtime services. Frankly I'm not sure what this thing is testing because the EFI VA range is hardcoded and I can't imagine it being somewhere else *except* in the last PGD.It's just so that someone doesn't just change the #define's for EFI_VA_END/START and think that it will work, I guess. Another reasonable option, for example, would be to reserve an entire PGD entry, allowing everything but the PGD level to be shared, and adding the EFI PGD to the pgd_list and getting rid of efi_sync_low_kernel_mappings() altogether. There aren't that many PGD entries still unused though, so this is probably not worth it.The churn doesn't seem to be worth it, tbh. So could we get rid of the complexity here, and only build_bug() on the start address of the EFI region being outside the topmost p4d? That should make the PGD test redundant as well.Was there ever a resolution to this conversation or a patch sent? I am still seeing the build failure that Arnd initially sent the patch for. x86_64 all{mod,yes}config with clang are going to ship broken in 5.11.
I think we have agreement on the approach but it is unclear who is going to write the patch.