From df7b79ae5a95ef6946199410edf5340966d66129 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Mon, 11 Nov 2024 23:19:50 +0100 Subject: [PATCH] systemd: revert boot-breaking systemd-boot change Fixes boot for me. Closes: https://github.com/NixOS/nixpkgs/pull/355284 (cherry picked from commit 63ce4665b2ce60fbe35d7cdf2b434dd10f1b4095) (cherry picked from commit 91ea63fc21d90d9c017e600ae448a6bfc794c9aa) --- ...-initrd_prepare-semantically-equival.patch | 150 ++++++++++++++++++ pkgs/os-specific/linux/systemd/default.nix | 1 + 2 files changed, 151 insertions(+) create mode 100644 pkgs/os-specific/linux/systemd/0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch diff --git a/pkgs/os-specific/linux/systemd/0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch b/pkgs/os-specific/linux/systemd/0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch new file mode 100644 index 000000000000..f33b730d015a --- /dev/null +++ b/pkgs/os-specific/linux/systemd/0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch @@ -0,0 +1,150 @@ +From bc1abc37f1cf0368d9c320c9d3845154d85f66b1 Mon Sep 17 00:00:00 2001 +From: Alyssa Ross +Date: Mon, 11 Nov 2024 23:09:21 +0100 +Subject: [PATCH] Revert "boot: Make initrd_prepare() semantically equivalent + to combine_initrds()" + +This reverts commit d64193a2a652b15db9cb9ed10c6b77a17ca46cd2. + +This breaks boot on Apple Silicon, and probably other platforms with no memory +mapped below 4G. + +Link: https://github.com/systemd/systemd/issues/35026 +--- + src/boot/efi/boot.c | 60 ++++++++++++--------------------------------- + 1 file changed, 16 insertions(+), 44 deletions(-) + +diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c +index ecbb4e0509..f94b59db59 100644 +--- a/src/boot/efi/boot.c ++++ b/src/boot/efi/boot.c +@@ -11,7 +11,6 @@ + #include "initrd.h" + #include "linux.h" + #include "measure.h" +-#include "memory-util-fundamental.h" + #include "part-discovery.h" + #include "pe.h" + #include "proto/block-io.h" +@@ -2249,18 +2248,18 @@ static EFI_STATUS initrd_prepare( + EFI_FILE *root, + const BootEntry *entry, + char16_t **ret_options, +- Pages *ret_initrd_pages, ++ void **ret_initrd, + size_t *ret_initrd_size) { + + assert(root); + assert(entry); + assert(ret_options); +- assert(ret_initrd_pages); ++ assert(ret_initrd); + assert(ret_initrd_size); + + if (entry->type != LOADER_LINUX || !entry->initrd) { + *ret_options = NULL; +- *ret_initrd_pages = (Pages) {}; ++ *ret_initrd = NULL; + *ret_initrd_size = 0; + return EFI_SUCCESS; + } +@@ -2274,6 +2273,7 @@ static EFI_STATUS initrd_prepare( + + EFI_STATUS err; + size_t size = 0; ++ _cleanup_free_ uint8_t *initrd = NULL; + + STRV_FOREACH(i, entry->initrd) { + _cleanup_free_ char16_t *o = options; +@@ -2292,58 +2292,30 @@ static EFI_STATUS initrd_prepare( + if (err != EFI_SUCCESS) + return err; + +- if (!INC_SAFE(&size, ALIGN4(info->FileSize))) +- return EFI_OUT_OF_RESOURCES; +- } +- +- _cleanup_pages_ Pages pages = xmalloc_pages( +- AllocateMaxAddress, +- EfiLoaderData, +- EFI_SIZE_TO_PAGES(size), +- UINT32_MAX /* Below 4G boundary. */); +- uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr); +- +- STRV_FOREACH(i, entry->initrd) { +- _cleanup_(file_closep) EFI_FILE *handle = NULL; +- err = root->Open(root, &handle, *i, EFI_FILE_MODE_READ, 0); +- if (err != EFI_SUCCESS) +- return err; +- +- _cleanup_free_ EFI_FILE_INFO *info = NULL; +- err = get_file_info(handle, &info, NULL); +- if (err != EFI_SUCCESS) +- return err; +- + if (info->FileSize == 0) /* Automatically skip over empty files */ + continue; + +- size_t read_size = info->FileSize; +- err = chunked_read(handle, &read_size, p); ++ size_t new_size, read_size = info->FileSize; ++ if (!ADD_SAFE(&new_size, size, read_size)) ++ return EFI_OUT_OF_RESOURCES; ++ initrd = xrealloc(initrd, size, new_size); ++ ++ err = chunked_read(handle, &read_size, initrd + size); + if (err != EFI_SUCCESS) + return err; + + /* Make sure the actual read size is what we expected. */ +- assert(read_size == info->FileSize); +- p += read_size; +- +- size_t pad; +- pad = ALIGN4(read_size) - read_size; +- if (pad == 0) +- continue; +- +- memzero(p, pad); +- p += pad; ++ assert(size + read_size == new_size); ++ size = new_size; + } + +- assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + size) == p); +- + if (entry->options) { + _cleanup_free_ char16_t *o = options; + options = xasprintf("%ls %ls", o, entry->options); + } + + *ret_options = TAKE_PTR(options); +- *ret_initrd_pages = TAKE_STRUCT(pages); ++ *ret_initrd = TAKE_PTR(initrd); + *ret_initrd_size = size; + return EFI_SUCCESS; + } +@@ -2373,9 +2345,9 @@ static EFI_STATUS image_start( + return log_error_status(err, "Error making file device path: %m"); + + size_t initrd_size = 0; +- _cleanup_pages_ Pages initrd_pages = {}; ++ _cleanup_free_ void *initrd = NULL; + _cleanup_free_ char16_t *options_initrd = NULL; +- err = initrd_prepare(image_root, entry, &options_initrd, &initrd_pages, &initrd_size); ++ err = initrd_prepare(image_root, entry, &options_initrd, &initrd, &initrd_size); + if (err != EFI_SUCCESS) + return log_error_status(err, "Error preparing initrd: %m"); + +@@ -2393,7 +2365,7 @@ static EFI_STATUS image_start( + } + + _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL; +- err = initrd_register(PHYSICAL_ADDRESS_TO_POINTER(initrd_pages.addr), initrd_size, &initrd_handle); ++ err = initrd_register(initrd, initrd_size, &initrd_handle); + if (err != EFI_SUCCESS) + return log_error_status(err, "Error registering initrd: %m"); + +-- +2.47.0 + diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index 691dd4f815ba..5d10d3bcd3f0 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -232,6 +232,7 @@ stdenv.mkDerivation (finalAttrs: { ./0015-tpm2_context_init-fix-driver-name-checking.patch ./0016-systemctl-edit-suggest-systemdctl-edit-runtime-on-sy.patch ./0017-meson.build-do-not-create-systemdstatedir.patch + ./0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch # https://github.com/systemd/systemd/issues/33392 (fetchpatch2 {