Skip to content

[Bug]: GRUB unbootable with default LUKS2/Argon2id encryption on firmware that fragments memory <4GB #470

Description

@Jaaaky

Kernel

7.0.11-1-cachyos

Desktop Environment / Window Manager

KDE Plasma

CPU

Intel Core Ultra 7 265 (Arrow Lake-S)

GPU / Driver

Intel Arrow Lake-S integrated graphics [8086:7d67] / i915

Description

A default CachyOS install with GRUB + btrfs + LUKS2 full-disk encryption
(Calamares default KDF = Argon2id, 1 GiB memory) is unbootable on a Dell Pro Tower QCT1250 (BIOS 1.14.0, Secure Boot off). - same issue faced on other modern hardware too- GRUB reaches the passphrase prompt and then fails — either rejecting a correct passphrase instantly, or
running out of memory while loading the kernel.

This is not an Argon2-support problem (GRUB 2.14 supports Argon2). It is GRUB's x86_64 EFI allocation cap of 4 GiB GRUB_EFI_MAX_USABLE_ADDRESS = 0xffffffff) on firmware that leaves almost no contiguous usable RAM below 4 GiB. The machine has 16 GB but only ~973 MiB contiguous below 4 GiB; ~14 GiB sits above 4 GiB and stock GRUB cannot allocate there — neither for its Argon2 heap nor for the kernel image.

Rebuilding GRUB with the cap raised above 4 GiB fixes it completely; the system now boots with the default 1 GiB Argon2id.

This issue has been troubleshooted with help of claude opus 4.8

Steps to Reproduce

  1. Install CachyOS on a Dell Pro Tower QCT1250 (or similar firmware that
    fragments conventional memory <4 GiB) with the GRUB + btrfs + LUKS2 encrypted
    layout (Calamares default: LUKS2, Argon2id, ~1 GiB memory cost).
  2. Reboot into the installed system.
  3. Enter the correct passphrase at the GRUB prompt.

Expected Behavior

GRUB unlocks the LUKS2 container and boots the kernel, as it does on machines whose firmware leaves a large contiguous region below 4 GiB.

Actual Behavior

  • With the default high Argon2 memory (~800 MB–1 GiB): GRUB instantly reports invalid passphrase for a correct passphrase (the Argon2 buffer cannot be allocated in the small heap, so the derived key is wrong).
  • If Argon2 memory is lowered (≤ ~500 MB) it unlocks, but then the kernel fails to load:
    error: loader/efi/linux.c:grub_cmd_linux:542:out of memory
    error: loader/efi/linux.c:grub_cmd_initrd:412:you need to load the kernel first.
    
  • A known-good encrypted disk from another working PC shows the same OOM on this Dell — i.e. the failure is a property of this firmware's memory map, not the disk/LUKS config.
  • No effect: GRUB_TERMINAL_OUTPUT=console, GFXPAYLOAD=text, 55 MB initramfs, two BIOS versions, toggling Secure Boot / preboot-DMA / TPM / Resizable BAR.

Logs / Error Messages

https://paste.cachyos.org/p/39eef2e.log

Additional Context

The failure is pre-boot GRUB output, so nothing lands in journald. Key evidence collected from the GRUB console (lsmmap) and the built binary:

GRUB memory map (lsmmap, 16 GB machine):

largest contiguous "available RAM" below 4GB:
  0x100000 .. 0x3cf53000                      ~973 MiB
0x3cf53000 .. 0x52000000                      shattered into KB/MB scraps
0x52000000 .. 0x100000000                     reserved MMIO hole
0x100000000  length 0x38fe50000               ~14.25 GiB available, ABOVE 4GB

GRUB allocator confines everything (heap + kernel placement) below
GRUB_EFI_MAX_USABLE_ADDRESS:

// include/grub/x86_64/efi/memory.h  (active branch, build is -mcmodel=large)
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff   // 4 GiB

via grub_efi_allocate_any_pages()
grub_efi_allocate_pages_real(GRUB_EFI_MAX_USABLE_ADDRESS, …, GRUB_EFI_ALLOCATE_MAX_ADDRESS, …).

LUKS2 keyslots on the affected install (cryptsetup luksDump, container
/dev/nvme0n1p4) — both slots are the default 1 GiB Argon2id:

0: luks2  PBKDF: argon2id  Memory: 1048576  Time cost: 4   Threads: 4   (passphrase)
1: luks2  PBKDF: argon2id  Memory: 1048576  Time cost: 10  Threads: 4   (keyfile, Calamares default)

Proof the fix lands (after rebuild with the raised cap):
/usr/lib/grub/x86_64-efi/kernel.img contains the new 64-bit immediate ff ff ff ff ff 00 00 00 (the 0xffffffffff movabs); stock GRUB never has this pattern (the 4 GiB value is a 32-bit mov). System now boots with both 1 GiB Argon2id slots.

Root cause. On x86_64 GRUB caps every EFI page allocation — its heap (used for the Argon2 work buffer) and the Linux kernel image placement — at 4 GiB.
This firmware reserves so much below 4 GiB that the largest contiguous free block is ~973 MiB, so a 1 GiB Argon2 buffer cannot be allocated (→ invalid passphrase) and, after a low-memory unlock, the kernel image cannot find a contiguous slot below 4 GiB (→ grub_cmd_linux:542:out of memory). The 14 GiB above 4 GiB is unusable by stock GRUB. Modern business desktops (Dell/HP/Lenovo, vPro/ME) are prone to this sub-4 GiB fragmentation.

Fix (one constant).

--- a/include/grub/x86_64/efi/memory.h
+++ b/include/grub/x86_64/efi/memory.h
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
+#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffULL

The kernel is then placed >4 GiB and the Argon2 heap fits. UEFI disk reads go
through firmware EFI_BLOCK_IO (64-bit DMA), so buffers >4 GiB are safe on
modern controllers. (If a controller could not DMA >4 GiB, an 8 GiB cap
0x1ffffffffULL also works.)

Secondary issue — grub 2.14 no longer builds with the current GCC. If
CachyOS rebuilds grub with the current toolchain it fails (this is why I had to
neutralize it when rebuilding):

util/probe.c:77:7:    error: assignment discards 'const' qualifier ... [-Werror=discarded-qualifiers]
util/resolve.c:144:8: error: assignment discards 'const' qualifier ... [-Werror=discarded-qualifiers]

GRUB 2.14 builds host utils with -Werror; either patch the const-qualifier
sources or drop -Werror for the host build.

Suggested action for CachyOS.

  1. Carry a patch raising GRUB_EFI_MAX_USABLE_ADDRESS on x86_64-efi (or backport
    the upstream "usable vs allocation address" split, so the kernel can be placed

    4 GiB while DMA buffers stay low). This makes the default encrypted GRUB
    install bootable on firmware with heavy sub-4 GiB reservations.

  2. Ensure grub builds with the current GCC (-Werror / discarded-qualifiers).

Upstream context: grub-devel "kern/efi/mm: ask for more than 4GB", bug #64471.

Workaround for affected users (rebuild grub with the raised cap, reinstall to the ESP, pin the package) — self-contained script that runs on a booted system or inside arch-chroot on a fresh install: fix-grub-dell-oom.sh (attached).

fix-grub-dell-oom.sh

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions