systemd: fix systemd-boot keyboard handling lockup

In v248 compiler weirdness and refactoring lead to the bootloader
erroring out handling keyboard input on some systems.
See https://github.com/systemd/systemd/issues/19191

This should be redundant in v249.6 when it officially gets tagged in
systemd-stable.

Closes https://github.com/NixOS/nixpkgs/issues/143847

Anund d216b215 9a96e0ec

+767 -38
+2 -2
pkgs/os-specific/linux/systemd/0001-Start-device-units-for-uninitialised-encrypted-devic.patch
··· 1 - From 06a8dbb65584b6f705fee8a486f32dab12f72082 Mon Sep 17 00:00:00 2001 1 + From d4ea219a35a09fe02bc9e47e8530644cb4fc4146 Mon Sep 17 00:00:00 2001 2 2 From: Eelco Dolstra <eelco.dolstra@logicblox.com> 3 3 Date: Tue, 8 Jan 2013 15:46:30 +0100 4 - Subject: [PATCH 01/19] Start device units for uninitialised encrypted devices 4 + Subject: [PATCH 01/21] Start device units for uninitialised encrypted devices 5 5 6 6 This is necessary because the NixOS service that initialises the 7 7 filesystem depends on the appearance of the device unit. Also, this
+2 -2
pkgs/os-specific/linux/systemd/0002-Don-t-try-to-unmount-nix-or-nix-store.patch
··· 1 - From 2c98ff115f7027bebde14cf3e74f2c51b343874c Mon Sep 17 00:00:00 2001 1 + From 67abd8f22f70d9348bc9d8e0e93dde4d325627ba Mon Sep 17 00:00:00 2001 2 2 From: Eelco Dolstra <eelco.dolstra@logicblox.com> 3 3 Date: Fri, 12 Apr 2013 13:16:57 +0200 4 - Subject: [PATCH 02/19] Don't try to unmount /nix or /nix/store 4 + Subject: [PATCH 02/21] Don't try to unmount /nix or /nix/store 5 5 6 6 They'll still be remounted read-only. 7 7
+2 -2
pkgs/os-specific/linux/systemd/0003-Fix-NixOS-containers.patch
··· 1 - From 16f441b6495ff4c4d1d0b71a7f1650505147173d Mon Sep 17 00:00:00 2001 1 + From 37c9471f59bd57223014a4a645b5f96a71d78787 Mon Sep 17 00:00:00 2001 2 2 From: Eelco Dolstra <eelco.dolstra@logicblox.com> 3 3 Date: Wed, 16 Apr 2014 10:59:28 +0200 4 - Subject: [PATCH 03/19] Fix NixOS containers 4 + Subject: [PATCH 03/21] Fix NixOS containers 5 5 6 6 In NixOS containers, the init script is bind-mounted into the 7 7 container, so checking early whether it exists will fail.
+2 -2
pkgs/os-specific/linux/systemd/0004-Look-for-fsck-in-the-right-place.patch
··· 1 - From 261423bc039378115ad9223c2b6ede9c395847b2 Mon Sep 17 00:00:00 2001 1 + From 987d6f94dac8e1a75615fd9ddcfb0eb1c2c4c349 Mon Sep 17 00:00:00 2001 2 2 From: Eelco Dolstra <eelco.dolstra@logicblox.com> 3 3 Date: Thu, 1 May 2014 14:10:10 +0200 4 - Subject: [PATCH 04/19] Look for fsck in the right place 4 + Subject: [PATCH 04/21] Look for fsck in the right place 5 5 6 6 --- 7 7 src/fsck/fsck.c | 2 +-
+2 -2
pkgs/os-specific/linux/systemd/0005-Add-some-NixOS-specific-unit-directories.patch
··· 1 - From 18b45c20499747bcc66714ee87edf34d4f6e3dca Mon Sep 17 00:00:00 2001 1 + From da4f855044b2babe052ce303cca1de736cf952cd Mon Sep 17 00:00:00 2001 2 2 From: Eelco Dolstra <eelco.dolstra@logicblox.com> 3 3 Date: Fri, 19 Dec 2014 14:46:17 +0100 4 - Subject: [PATCH 05/19] Add some NixOS-specific unit directories 4 + Subject: [PATCH 05/21] Add some NixOS-specific unit directories 5 5 6 6 Look in `/nix/var/nix/profiles/default/lib/systemd/{system,user}` for 7 7 units provided by packages installed into the default profile via
+2 -2
pkgs/os-specific/linux/systemd/0006-Get-rid-of-a-useless-message-in-user-sessions.patch
··· 1 - From 8b8f4168828a12cac17c3e8803cacebf31608c68 Mon Sep 17 00:00:00 2001 1 + From c06abdb631527f56a626b739340d1b275349612c Mon Sep 17 00:00:00 2001 2 2 From: Eelco Dolstra <eelco.dolstra@logicblox.com> 3 3 Date: Mon, 11 May 2015 15:39:38 +0200 4 - Subject: [PATCH 06/19] Get rid of a useless message in user sessions 4 + Subject: [PATCH 06/21] Get rid of a useless message in user sessions 5 5 6 6 Namely lots of variants of 7 7
+2 -2
pkgs/os-specific/linux/systemd/0007-hostnamed-localed-timedated-disable-methods-that-cha.patch
··· 1 - From e147e9defaf2bb5e8040566537661d90b4008daf Mon Sep 17 00:00:00 2001 1 + From 207c69466cdd164c42ed1901deb06f57b12f4363 Mon Sep 17 00:00:00 2001 2 2 From: Gabriel Ebner <gebner@gebner.org> 3 3 Date: Sun, 6 Dec 2015 14:26:36 +0100 4 - Subject: [PATCH 07/19] hostnamed, localed, timedated: disable methods that 4 + Subject: [PATCH 07/21] hostnamed, localed, timedated: disable methods that 5 5 change system settings. 6 6 7 7 ---
+2 -2
pkgs/os-specific/linux/systemd/0008-Fix-hwdb-paths.patch
··· 1 - From 992d0e6abb09aacceee2f8646c4bcdacf7277dc7 Mon Sep 17 00:00:00 2001 1 + From 3ca3855259c3015615983587063fa159cfa7e93c Mon Sep 17 00:00:00 2001 2 2 From: Nikolay Amiantov <ab@fmap.me> 3 3 Date: Thu, 7 Jul 2016 02:47:13 +0300 4 - Subject: [PATCH 08/19] Fix hwdb paths 4 + Subject: [PATCH 08/21] Fix hwdb paths 5 5 6 6 Patch by vcunat. 7 7 ---
+2 -2
pkgs/os-specific/linux/systemd/0009-Change-usr-share-zoneinfo-to-etc-zoneinfo.patch
··· 1 - From 462bc01b3a38468fd617066a3d7f27b1acca9e0a Mon Sep 17 00:00:00 2001 1 + From 717226ad0dc37ceb6c667c1f56396848978b6e83 Mon Sep 17 00:00:00 2001 2 2 From: Nikolay Amiantov <ab@fmap.me> 3 3 Date: Tue, 11 Oct 2016 13:12:08 +0300 4 - Subject: [PATCH 09/19] Change /usr/share/zoneinfo to /etc/zoneinfo 4 + Subject: [PATCH 09/21] Change /usr/share/zoneinfo to /etc/zoneinfo 5 5 6 6 NixOS uses this path. 7 7 ---
+2 -2
pkgs/os-specific/linux/systemd/0010-localectl-use-etc-X11-xkb-for-list-x11.patch
··· 1 - From fbb302d00c63dc17a210f83648f24a1da983b2c0 Mon Sep 17 00:00:00 2001 1 + From 75d12cf65073458f091899d673c613dfc43f60c0 Mon Sep 17 00:00:00 2001 2 2 From: Imuli <i@imu.li> 3 3 Date: Wed, 19 Oct 2016 08:46:47 -0400 4 - Subject: [PATCH 10/19] localectl: use /etc/X11/xkb for list-x11-* 4 + Subject: [PATCH 10/21] localectl: use /etc/X11/xkb for list-x11-* 5 5 6 6 NixOS has an option to link the xkb data files to /etc/X11, but not to 7 7 /usr/share/X11.
+2 -2
pkgs/os-specific/linux/systemd/0011-build-don-t-create-statedir-and-don-t-touch-prefixdi.patch
··· 1 - From b850dae349de8ac6906d4f920a21ef275cecb2de Mon Sep 17 00:00:00 2001 1 + From bce75eb4cdeb0b86df6b0a577e886c49a88303f6 Mon Sep 17 00:00:00 2001 2 2 From: Franz Pletz <fpletz@fnordicwalking.de> 3 3 Date: Sun, 11 Feb 2018 04:37:44 +0100 4 - Subject: [PATCH 11/19] build: don't create statedir and don't touch prefixdir 4 + Subject: [PATCH 11/21] build: don't create statedir and don't touch prefixdir 5 5 6 6 --- 7 7 meson.build | 3 ---
+2 -2
pkgs/os-specific/linux/systemd/0012-inherit-systemd-environment-when-calling-generators.patch
··· 1 - From beefb6d381286769cc47c71c82b831a37a405d90 Mon Sep 17 00:00:00 2001 1 + From ecdf0c5d9f88f526521f093cc9ee85f43efab4b7 Mon Sep 17 00:00:00 2001 2 2 From: Andreas Rammhold <andreas@rammhold.de> 3 3 Date: Fri, 2 Nov 2018 21:15:42 +0100 4 - Subject: [PATCH 12/19] inherit systemd environment when calling generators. 4 + Subject: [PATCH 12/21] inherit systemd environment when calling generators. 5 5 6 6 Systemd generators need access to the environment configured in 7 7 stage-2-init.sh since it schedules fsck and mkfs executions based on
+2 -2
pkgs/os-specific/linux/systemd/0013-add-rootprefix-to-lookup-dir-paths.patch
··· 1 - From 146b79d55cc4fdfdb5fd4978e68b21f5c1df1679 Mon Sep 17 00:00:00 2001 1 + From 39969a1b01d6c223a21c770093209b7f4047aaa4 Mon Sep 17 00:00:00 2001 2 2 From: Andreas Rammhold <andreas@rammhold.de> 3 3 Date: Thu, 9 May 2019 11:15:22 +0200 4 - Subject: [PATCH 13/19] add rootprefix to lookup dir paths 4 + Subject: [PATCH 13/21] add rootprefix to lookup dir paths 5 5 6 6 systemd does not longer use the UDEVLIBEXEC directory as root for 7 7 discovery default udev rules. By adding `$out/lib` to the lookup paths
+2 -2
pkgs/os-specific/linux/systemd/0014-systemd-shutdown-execute-scripts-in-etc-systemd-syst.patch
··· 1 - From 8edd810e74e2308f34eba6e8072e559e69307830 Mon Sep 17 00:00:00 2001 1 + From e7c960789b0ca97b24a66e9eeaa56ea645d9c66b Mon Sep 17 00:00:00 2001 2 2 From: Nikolay Amiantov <ab@fmap.me> 3 3 Date: Thu, 25 Jul 2019 20:45:55 +0300 4 - Subject: [PATCH 14/19] systemd-shutdown: execute scripts in 4 + Subject: [PATCH 14/21] systemd-shutdown: execute scripts in 5 5 /etc/systemd/system-shutdown 6 6 7 7 This is needed for NixOS to use such scripts as systemd directory is immutable.
+2 -2
pkgs/os-specific/linux/systemd/0015-systemd-sleep-execute-scripts-in-etc-systemd-system-.patch
··· 1 - From 9ed24199dd3ce91d3f7fbfbdf823312c124aba56 Mon Sep 17 00:00:00 2001 1 + From 6124720aa2b9dbc07f2fb898f0db150a44a86041 Mon Sep 17 00:00:00 2001 2 2 From: Nikolay Amiantov <ab@fmap.me> 3 3 Date: Thu, 25 Jul 2019 20:46:58 +0300 4 - Subject: [PATCH 15/19] systemd-sleep: execute scripts in 4 + Subject: [PATCH 15/21] systemd-sleep: execute scripts in 5 5 /etc/systemd/system-sleep 6 6 7 7 This is needed for NixOS to use such scripts as systemd directory is immutable.
+2 -2
pkgs/os-specific/linux/systemd/0016-kmod-static-nodes.service-Update-ConditionFileNotEmp.patch
··· 1 - From 6db7ad4d5526a82e4ed9b135daf1054a8b71e1c7 Mon Sep 17 00:00:00 2001 1 + From bee1d855d4fb7f2d6f6b9beb1dfd14b1dea31887 Mon Sep 17 00:00:00 2001 2 2 From: Florian Klink <flokli@flokli.de> 3 3 Date: Sat, 7 Mar 2020 22:40:27 +0100 4 - Subject: [PATCH 16/19] kmod-static-nodes.service: Update ConditionFileNotEmpty 4 + Subject: [PATCH 16/21] kmod-static-nodes.service: Update ConditionFileNotEmpty 5 5 6 6 On NixOS, kernel modules of the currently booted systems are located at 7 7 /run/booted-system/kernel-modules/lib/modules/%v/, not /lib/modules/%v/.
+2 -2
pkgs/os-specific/linux/systemd/0017-path-util.h-add-placeholder-for-DEFAULT_PATH_NORMAL.patch
··· 1 - From 160d32c336c96744bbfb618eae4c12cb90138644 Mon Sep 17 00:00:00 2001 1 + From 62198599bbc559eeb8e2a3caebce7b9135085270 Mon Sep 17 00:00:00 2001 2 2 From: Florian Klink <flokli@flokli.de> 3 3 Date: Sun, 8 Mar 2020 01:05:54 +0100 4 - Subject: [PATCH 17/19] path-util.h: add placeholder for DEFAULT_PATH_NORMAL 4 + Subject: [PATCH 17/21] path-util.h: add placeholder for DEFAULT_PATH_NORMAL 5 5 6 6 This will be the $PATH used to lookup ExecStart= etc. options, which 7 7 systemd itself uses extensively.
+2 -2
pkgs/os-specific/linux/systemd/0018-pkg-config-derive-prefix-from-prefix.patch
··· 1 - From 777d61550f95b1dcf253e1d2132f9db7010a18f3 Mon Sep 17 00:00:00 2001 1 + From 7654964344ba083529cb232ab229db7c0888f782 Mon Sep 17 00:00:00 2001 2 2 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io> 3 3 Date: Sun, 6 Dec 2020 08:34:19 +0100 4 - Subject: [PATCH 18/19] pkg-config: derive prefix from --prefix 4 + Subject: [PATCH 18/21] pkg-config: derive prefix from --prefix 5 5 6 6 Point prefix to the one configured, instead of `/usr` `systemd` has limited 7 7 support for making the pkgconfig prefix overridable, and interpolates those
+2 -2
pkgs/os-specific/linux/systemd/0019-core-handle-lookup-paths-being-symlinks.patch
··· 1 - From 273e706ff561f2164b84c714148346ac92dd8846 Mon Sep 17 00:00:00 2001 1 + From 4e9b4aa87d299be08cffc77a86d6f473a7a4109a Mon Sep 17 00:00:00 2001 2 2 From: Andreas Rammhold <andreas@rammhold.de> 3 3 Date: Wed, 18 Aug 2021 19:10:08 +0200 4 - Subject: [PATCH 19/19] core: handle lookup paths being symlinks 4 + Subject: [PATCH 19/21] core: handle lookup paths being symlinks 5 5 6 6 With a recent change paths leaving the statically known lookup paths 7 7 would be treated differently then those that remained within those. That
+401
pkgs/os-specific/linux/systemd/0020-sd-boot-Unify-error-handling.patch
··· 1 + From 3cf1b5fb6d1dc342e836cf0990df3170d2e9db49 Mon Sep 17 00:00:00 2001 2 + From: Jan Janssen <medhefgo@web.de> 3 + Date: Wed, 11 Aug 2021 14:59:46 +0200 4 + Subject: [PATCH 20/21] sd-boot: Unify error handling 5 + 6 + log_error_stall() and log_error_status_stall() will ensure the user has 7 + a chance to catch an error message by stalling and also forcing a 8 + lightred/black color on it. Also, convert several Print() calls to it 9 + since they are actually error messages. 10 + 11 + (cherry picked from commit 8aba0eec499b762657f528988c2f093ac490620d) 12 + --- 13 + src/boot/efi/boot.c | 62 ++++++++++---------------------- 14 + src/boot/efi/random-seed.c | 73 +++++++++++++------------------------- 15 + src/boot/efi/stub.c | 24 ++++--------- 16 + src/boot/efi/util.c | 17 +++++++-- 17 + src/boot/efi/util.h | 9 +++++ 18 + 5 files changed, 75 insertions(+), 110 deletions(-) 19 + 20 + diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c 21 + index 13940a6df7..54d704f0d1 100644 22 + --- a/src/boot/efi/boot.c 23 + +++ b/src/boot/efi/boot.c 24 + @@ -527,7 +527,7 @@ static BOOLEAN menu_run( 25 + err = console_set_mode(&config->console_mode, config->console_mode_change); 26 + if (EFI_ERROR(err)) { 27 + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); 28 + - Print(L"Error switching console mode to %ld: %r.\r", (UINT64)config->console_mode, err); 29 + + log_error_stall(L"Error switching console mode to %lu: %r", (UINT64)config->console_mode, err); 30 + } 31 + } else 32 + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); 33 + @@ -1221,8 +1221,7 @@ static VOID config_entry_bump_counters( 34 + break; 35 + 36 + if (r != EFI_BUFFER_TOO_SMALL || file_info_size * 2 < file_info_size) { 37 + - Print(L"\nFailed to get file info for '%s': %r\n", old_path, r); 38 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 39 + + log_error_stall(L"Failed to get file info for '%s': %r", old_path, r); 40 + return; 41 + } 42 + 43 + @@ -1234,8 +1233,7 @@ static VOID config_entry_bump_counters( 44 + StrCpy(file_info->FileName, entry->next_name); 45 + r = uefi_call_wrapper(handle->SetInfo, 4, handle, &EfiFileInfoGuid, file_info_size, file_info); 46 + if (EFI_ERROR(r)) { 47 + - Print(L"\nFailed to rename '%s' to '%s', ignoring: %r\n", old_path, entry->next_name, r); 48 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 49 + + log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, r); 50 + return; 51 + } 52 + 53 + @@ -2165,18 +2163,12 @@ static EFI_STATUS image_start( 54 + EFI_STATUS err; 55 + 56 + path = FileDevicePath(entry->device, entry->loader); 57 + - if (!path) { 58 + - Print(L"Error getting device path."); 59 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 60 + - return EFI_INVALID_PARAMETER; 61 + - } 62 + + if (!path) 63 + + return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path."); 64 + 65 + err = uefi_call_wrapper(BS->LoadImage, 6, FALSE, parent_image, path, NULL, 0, &image); 66 + - if (EFI_ERROR(err)) { 67 + - Print(L"Error loading %s: %r", entry->loader, err); 68 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 69 + - return err; 70 + - } 71 + + if (EFI_ERROR(err)) 72 + + return log_error_status_stall(err, L"Error loading %s: %r", entry->loader, err); 73 + 74 + if (config->options_edit) 75 + options = config->options_edit; 76 + @@ -2190,8 +2182,7 @@ static EFI_STATUS image_start( 77 + err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, 78 + parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 79 + if (EFI_ERROR(err)) { 80 + - Print(L"Error getting LoadedImageProtocol handle: %r", err); 81 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 82 + + log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err); 83 + goto out_unload; 84 + } 85 + loaded_image->LoadOptions = options; 86 + @@ -2202,10 +2193,8 @@ static EFI_STATUS image_start( 87 + err = tpm_log_event(SD_TPM_PCR, 88 + (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions, 89 + loaded_image->LoadOptionsSize, loaded_image->LoadOptions); 90 + - if (EFI_ERROR(err)) { 91 + - Print(L"Unable to add image options measurement: %r", err); 92 + - uefi_call_wrapper(BS->Stall, 1, 200 * 1000); 93 + - } 94 + + if (EFI_ERROR(err)) 95 + + log_error_stall(L"Unable to add image options measurement: %r", err); 96 + #endif 97 + } 98 + 99 + @@ -2231,9 +2220,7 @@ static EFI_STATUS reboot_into_firmware(VOID) { 100 + return err; 101 + 102 + err = uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL); 103 + - Print(L"Error calling ResetSystem: %r", err); 104 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 105 + - return err; 106 + + return log_error_status_stall(err, L"Error calling ResetSystem: %r", err); 107 + } 108 + 109 + static VOID config_free(Config *config) { 110 + @@ -2305,30 +2292,21 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 111 + 112 + err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, 113 + image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 114 + - if (EFI_ERROR(err)) { 115 + - Print(L"Error getting a LoadedImageProtocol handle: %r", err); 116 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 117 + - return err; 118 + - } 119 + + if (EFI_ERROR(err)) 120 + + return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err); 121 + 122 + /* export the device path this image is started from */ 123 + if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) 124 + efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, 0); 125 + 126 + root_dir = LibOpenRoot(loaded_image->DeviceHandle); 127 + - if (!root_dir) { 128 + - Print(L"Unable to open root directory."); 129 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 130 + - return EFI_LOAD_ERROR; 131 + - } 132 + + if (!root_dir) 133 + + return log_error_status_stall(EFI_LOAD_ERROR, L"Unable to open root directory.", EFI_LOAD_ERROR); 134 + 135 + if (secure_boot_enabled() && shim_loaded()) { 136 + err = security_policy_install(); 137 + - if (EFI_ERROR(err)) { 138 + - Print(L"Error installing security policy: %r ", err); 139 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 140 + - return err; 141 + - } 142 + + if (EFI_ERROR(err)) 143 + + return log_error_status_stall(err, L"Error installing security policy: %r", err); 144 + } 145 + 146 + /* the filesystem path to this image, to prevent adding ourselves to the menu */ 147 + @@ -2367,8 +2345,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 148 + } 149 + 150 + if (config.entry_count == 0) { 151 + - Print(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed."); 152 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 153 + + log_error_stall(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed."); 154 + goto out; 155 + } 156 + 157 + @@ -2440,8 +2417,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 158 + err = image_start(image, &config, entry); 159 + if (EFI_ERROR(err)) { 160 + graphics_mode(FALSE); 161 + - Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err); 162 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 163 + + log_error_stall(L"Failed to execute %s (%s): %r", entry->title, entry->loader, err); 164 + goto out; 165 + } 166 + 167 + diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c 168 + index 3e179851b0..939daf3e41 100644 169 + --- a/src/boot/efi/random-seed.c 170 + +++ b/src/boot/efi/random-seed.c 171 + @@ -35,10 +35,8 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { 172 + return log_oom(); 173 + 174 + err = uefi_call_wrapper(rng->GetRNG, 3, rng, NULL, size, data); 175 + - if (EFI_ERROR(err)) { 176 + - Print(L"Failed to acquire RNG data: %r\n", err); 177 + - return err; 178 + - } 179 + + if (EFI_ERROR(err)) 180 + + return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err); 181 + 182 + *ret = TAKE_PTR(data); 183 + return EFI_SUCCESS; 184 + @@ -149,14 +147,12 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) { 185 + err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size); 186 + if (EFI_ERROR(err)) { 187 + if (err != EFI_NOT_FOUND) 188 + - Print(L"Failed to read LoaderSystemToken EFI variable: %r", err); 189 + + log_error_stall(L"Failed to read LoaderSystemToken EFI variable: %r", err); 190 + return err; 191 + } 192 + 193 + - if (size <= 0) { 194 + - Print(L"System token too short, ignoring."); 195 + - return EFI_NOT_FOUND; 196 + - } 197 + + if (size <= 0) 198 + + return log_error_status_stall(EFI_NOT_FOUND, L"System token too short, ignoring."); 199 + 200 + *ret = TAKE_PTR(data); 201 + *ret_size = size; 202 + @@ -209,8 +205,7 @@ static VOID validate_sha256(void) { 203 + sha256_finish_ctx(&hash, result); 204 + 205 + if (CompareMem(result, array[i].hash, HASH_VALUE_SIZE) != 0) { 206 + - Print(L"SHA256 failed validation.\n"); 207 + - uefi_call_wrapper(BS->Stall, 1, 120 * 1000 * 1000); 208 + + log_error_stall(L"SHA256 failed validation."); 209 + return; 210 + } 211 + } 212 + @@ -246,7 +241,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { 213 + err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL); 214 + if (EFI_ERROR(err)) { 215 + if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED) 216 + - Print(L"Failed to open random seed file: %r\n", err); 217 + + log_error_stall(L"Failed to open random seed file: %r", err); 218 + return err; 219 + } 220 + 221 + @@ -255,15 +250,11 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { 222 + return log_oom(); 223 + 224 + size = info->FileSize; 225 + - if (size < RANDOM_MAX_SIZE_MIN) { 226 + - Print(L"Random seed file is too short?\n"); 227 + - return EFI_INVALID_PARAMETER; 228 + - } 229 + + if (size < RANDOM_MAX_SIZE_MIN) 230 + + return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too short."); 231 + 232 + - if (size > RANDOM_MAX_SIZE_MAX) { 233 + - Print(L"Random seed file is too large?\n"); 234 + - return EFI_INVALID_PARAMETER; 235 + - } 236 + + if (size > RANDOM_MAX_SIZE_MAX) 237 + + return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too large."); 238 + 239 + seed = AllocatePool(size); 240 + if (!seed) 241 + @@ -271,20 +262,14 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { 242 + 243 + rsize = size; 244 + err = uefi_call_wrapper(handle->Read, 3, handle, &rsize, seed); 245 + - if (EFI_ERROR(err)) { 246 + - Print(L"Failed to read random seed file: %r\n", err); 247 + - return err; 248 + - } 249 + - if (rsize != size) { 250 + - Print(L"Short read on random seed file\n"); 251 + - return EFI_PROTOCOL_ERROR; 252 + - } 253 + + if (EFI_ERROR(err)) 254 + + return log_error_status_stall(err, L"Failed to read random seed file: %r", err); 255 + + if (rsize != size) 256 + + return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file."); 257 + 258 + err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0); 259 + - if (EFI_ERROR(err)) { 260 + - Print(L"Failed to seek to beginning of random seed file: %r\n", err); 261 + - return err; 262 + - } 263 + + if (EFI_ERROR(err)) 264 + + return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err); 265 + 266 + /* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good 267 + * idea to use it because it helps us for cases where users mistakenly include a random seed in 268 + @@ -299,27 +284,19 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { 269 + /* Update the random seed on disk before we use it */ 270 + wsize = size; 271 + err = uefi_call_wrapper(handle->Write, 3, handle, &wsize, new_seed); 272 + - if (EFI_ERROR(err)) { 273 + - Print(L"Failed to write random seed file: %r\n", err); 274 + - return err; 275 + - } 276 + - if (wsize != size) { 277 + - Print(L"Short write on random seed file\n"); 278 + - return EFI_PROTOCOL_ERROR; 279 + - } 280 + + if (EFI_ERROR(err)) 281 + + return log_error_status_stall(err, L"Failed to write random seed file: %r", err); 282 + + if (wsize != size) 283 + + return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file."); 284 + 285 + err = uefi_call_wrapper(handle->Flush, 1, handle); 286 + - if (EFI_ERROR(err)) { 287 + - Print(L"Failed to flush random seed file: %r\n"); 288 + - return err; 289 + - } 290 + + if (EFI_ERROR(err)) 291 + + return log_error_status_stall(err, L"Failed to flush random seed file: %r", err); 292 + 293 + /* We are good to go */ 294 + err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, 0); 295 + - if (EFI_ERROR(err)) { 296 + - Print(L"Failed to write random seed to EFI variable: %r\n", err); 297 + - return err; 298 + - } 299 + + if (EFI_ERROR(err)) 300 + + return log_error_status_stall(err, L"Failed to write random seed to EFI variable: %r", err); 301 + 302 + return EFI_SUCCESS; 303 + } 304 + diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c 305 + index 082fe91c9e..82da1d3ec4 100644 306 + --- a/src/boot/efi/stub.c 307 + +++ b/src/boot/efi/stub.c 308 + @@ -36,18 +36,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 309 + 310 + err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, 311 + image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 312 + - if (EFI_ERROR(err)) { 313 + - Print(L"Error getting a LoadedImageProtocol handle: %r ", err); 314 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 315 + - return err; 316 + - } 317 + + if (EFI_ERROR(err)) 318 + + return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err); 319 + 320 + err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs); 321 + - if (EFI_ERROR(err)) { 322 + - Print(L"Unable to locate embedded .linux section: %r ", err); 323 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 324 + - return err; 325 + - } 326 + + if (EFI_ERROR(err)) 327 + + return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err); 328 + 329 + if (szs[0] > 0) 330 + cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0]; 331 + @@ -72,10 +66,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 332 + err = tpm_log_event(SD_TPM_PCR, 333 + (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions, 334 + loaded_image->LoadOptionsSize, loaded_image->LoadOptions); 335 + - if (EFI_ERROR(err)) { 336 + - Print(L"Unable to add image options measurement: %r", err); 337 + - uefi_call_wrapper(BS->Stall, 1, 200 * 1000); 338 + - } 339 + + if (EFI_ERROR(err)) 340 + + log_error_stall(L"Unable to add image options measurement: %r", err); 341 + #endif 342 + } 343 + 344 + @@ -126,7 +118,5 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 345 + (UINTN)loaded_image->ImageBase + addrs[2], szs[2]); 346 + 347 + graphics_mode(FALSE); 348 + - Print(L"Execution of embedded linux image failed: %r\n", err); 349 + - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 350 + - return err; 351 + + return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err); 352 + } 353 + diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c 354 + index 6f4e5933d3..aee076060b 100644 355 + --- a/src/boot/efi/util.c 356 + +++ b/src/boot/efi/util.c 357 + @@ -411,8 +411,21 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s 358 + return err; 359 + } 360 + 361 + +VOID log_error_stall(const CHAR16 *fmt, ...) { 362 + + va_list args; 363 + + 364 + + uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK); 365 + + 366 + + Print(L"\n"); 367 + + va_start(args, fmt); 368 + + VPrint(fmt, args); 369 + + va_end(args); 370 + + Print(L"\n"); 371 + + 372 + + uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 373 + +} 374 + + 375 + EFI_STATUS log_oom(void) { 376 + - Print(L"Out of memory."); 377 + - (void) uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); 378 + + log_error_stall(L"Out of memory."); 379 + return EFI_OUT_OF_RESOURCES; 380 + } 381 + diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h 382 + index 1a42b01033..d3bf848a95 100644 383 + --- a/src/boot/efi/util.h 384 + +++ b/src/boot/efi/util.h 385 + @@ -74,4 +74,13 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) { 386 + #define UINT64_MAX ((UINT64) -1) 387 + #endif 388 + 389 + +VOID log_error_stall(const CHAR16 *fmt, ...); 390 + EFI_STATUS log_oom(void); 391 + + 392 + +/* This works just like log_error_errno() from userspace, but requires you 393 + + * to provide err a second time if you want to use %r in the message! */ 394 + +#define log_error_status_stall(err, fmt, ...) \ 395 + + ({ \ 396 + + log_error_stall(fmt, ##__VA_ARGS__); \ 397 + + err; \ 398 + + }) 399 + -- 400 + 2.33.0 401 +
+320
pkgs/os-specific/linux/systemd/0021-sd-boot-Rework-console-input-handling.patch
··· 1 + From 2d9fcfcfa38667ada306e095599944f941576e53 Mon Sep 17 00:00:00 2001 2 + From: Jan Janssen <medhefgo@web.de> 3 + Date: Wed, 11 Aug 2021 14:59:46 +0200 4 + Subject: [PATCH 21/21] sd-boot: Rework console input handling 5 + 6 + Fixes: #15847 7 + Probably fixes: #19191 8 + 9 + (cherry picked from commit e98d271e57f3d0356e444b6ea2d48836ee2769b0) 10 + --- 11 + src/boot/efi/boot.c | 55 +++++++--------------- 12 + src/boot/efi/console.c | 102 +++++++++++++++++++++++++++++------------ 13 + src/boot/efi/console.h | 2 +- 14 + 3 files changed, 91 insertions(+), 68 deletions(-) 15 + 16 + diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c 17 + index 54d704f0d1..b4f3b9605a 100644 18 + --- a/src/boot/efi/boot.c 19 + +++ b/src/boot/efi/boot.c 20 + @@ -134,7 +134,7 @@ static BOOLEAN line_edit( 21 + uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print); 22 + uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos); 23 + 24 + - err = console_key_read(&key, TRUE); 25 + + err = console_key_read(&key, 0); 26 + if (EFI_ERROR(err)) 27 + continue; 28 + 29 + @@ -387,7 +387,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { 30 + Print(L"OsIndicationsSupported: %d\n", indvar); 31 + 32 + Print(L"\n--- press key ---\n\n"); 33 + - console_key_read(&key, TRUE); 34 + + console_key_read(&key, 0); 35 + 36 + Print(L"timeout: %u\n", config->timeout_sec); 37 + if (config->timeout_sec_efivar >= 0) 38 + @@ -432,7 +432,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { 39 + Print(L"LoaderEntryDefault: %s\n", defaultstr); 40 + 41 + Print(L"\n--- press key ---\n\n"); 42 + - console_key_read(&key, TRUE); 43 + + console_key_read(&key, 0); 44 + 45 + for (UINTN i = 0; i < config->entry_count; i++) { 46 + ConfigEntry *entry; 47 + @@ -482,7 +482,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { 48 + entry->path, entry->next_name); 49 + 50 + Print(L"\n--- press key ---\n\n"); 51 + - console_key_read(&key, TRUE); 52 + + console_key_read(&key, 0); 53 + } 54 + 55 + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); 56 + @@ -509,11 +509,10 @@ static BOOLEAN menu_run( 57 + UINTN y_max; 58 + CHAR16 *status; 59 + CHAR16 *clearline; 60 + - INTN timeout_remain; 61 + + UINTN timeout_remain = config->timeout_sec; 62 + INT16 idx; 63 + BOOLEAN exit = FALSE; 64 + BOOLEAN run = TRUE; 65 + - BOOLEAN wait = FALSE; 66 + 67 + graphics_mode(FALSE); 68 + uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE); 69 + @@ -538,12 +537,6 @@ static BOOLEAN menu_run( 70 + y_max = 25; 71 + } 72 + 73 + - /* we check 10 times per second for a keystroke */ 74 + - if (config->timeout_sec > 0) 75 + - timeout_remain = config->timeout_sec * 10; 76 + - else 77 + - timeout_remain = -1; 78 + - 79 + idx_highlight = config->idx_default; 80 + idx_highlight_prev = 0; 81 + 82 + @@ -643,7 +636,7 @@ static BOOLEAN menu_run( 83 + 84 + if (timeout_remain > 0) { 85 + FreePool(status); 86 + - status = PoolPrint(L"Boot in %d sec.", (timeout_remain + 5) / 10); 87 + + status = PoolPrint(L"Boot in %d s.", timeout_remain); 88 + } 89 + 90 + /* print status at last line of screen */ 91 + @@ -664,27 +657,18 @@ static BOOLEAN menu_run( 92 + uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len); 93 + } 94 + 95 + - err = console_key_read(&key, wait); 96 + - if (EFI_ERROR(err)) { 97 + - /* timeout reached */ 98 + + err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : 0); 99 + + if (err == EFI_TIMEOUT) { 100 + + timeout_remain--; 101 + if (timeout_remain == 0) { 102 + exit = TRUE; 103 + break; 104 + } 105 + 106 + - /* sleep and update status */ 107 + - if (timeout_remain > 0) { 108 + - uefi_call_wrapper(BS->Stall, 1, 100 * 1000); 109 + - timeout_remain--; 110 + - continue; 111 + - } 112 + - 113 + - /* timeout disabled, wait for next key */ 114 + - wait = TRUE; 115 + + /* update status */ 116 + continue; 117 + - } 118 + - 119 + - timeout_remain = -1; 120 + + } else 121 + + timeout_remain = 0; 122 + 123 + /* clear status after keystroke */ 124 + if (status) { 125 + @@ -787,7 +771,7 @@ static BOOLEAN menu_run( 126 + config->timeout_sec_efivar, 127 + EFI_VARIABLE_NON_VOLATILE); 128 + if (config->timeout_sec_efivar > 0) 129 + - status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); 130 + + status = PoolPrint(L"Menu timeout set to %d s.", config->timeout_sec_efivar); 131 + else 132 + status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu."); 133 + } else if (config->timeout_sec_efivar <= 0){ 134 + @@ -795,7 +779,7 @@ static BOOLEAN menu_run( 135 + efivar_set( 136 + LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE); 137 + if (config->timeout_sec_config > 0) 138 + - status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.", 139 + + status = PoolPrint(L"Menu timeout of %d s is defined by configuration file.", 140 + config->timeout_sec_config); 141 + else 142 + status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu."); 143 + @@ -813,7 +797,7 @@ static BOOLEAN menu_run( 144 + config->timeout_sec_efivar, 145 + EFI_VARIABLE_NON_VOLATILE); 146 + if (config->timeout_sec_efivar > 0) 147 + - status = PoolPrint(L"Menu timeout set to %d sec.", 148 + + status = PoolPrint(L"Menu timeout set to %d s.", 149 + config->timeout_sec_efivar); 150 + else 151 + status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu."); 152 + @@ -2369,13 +2353,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 153 + else { 154 + UINT64 key; 155 + 156 + - err = console_key_read(&key, FALSE); 157 + - 158 + - if (err == EFI_NOT_READY) { 159 + - uefi_call_wrapper(BS->Stall, 1, 100 * 1000); 160 + - err = console_key_read(&key, FALSE); 161 + - } 162 + - 163 + + /* Block up to 100ms to give firmware time to get input working. */ 164 + + err = console_key_read(&key, 100 * 1000); 165 + if (!EFI_ERROR(err)) { 166 + INT16 idx; 167 + 168 + diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c 169 + index 83619d2147..369c549daf 100644 170 + --- a/src/boot/efi/console.c 171 + +++ b/src/boot/efi/console.c 172 + @@ -11,61 +11,105 @@ 173 + 174 + #define EFI_SIMPLE_TEXT_INPUT_EX_GUID &(EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID 175 + 176 + -EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) { 177 + +static inline void EventClosep(EFI_EVENT *event) { 178 + + if (!*event) 179 + + return; 180 + + 181 + + uefi_call_wrapper(BS->CloseEvent, 1, *event); 182 + +} 183 + + 184 + +/* 185 + + * Reading input from the console sounds like an easy task to do, but thanks to broken 186 + + * firmware it is actually a nightmare. 187 + + * 188 + + * There is a ConIn and TextInputEx API for this. Ideally we want to use TextInputEx, 189 + + * because that gives us Ctrl/Alt/Shift key state information. Unfortunately, it is not 190 + + * always available and sometimes just non-functional. 191 + + * 192 + + * On the other hand we have ConIn, where some firmware likes to just freeze on us 193 + + * if we call ReadKeyStroke on it. 194 + + * 195 + + * Therefore, we use WaitForEvent on both ConIn and TextInputEx (if available) along 196 + + * with a timer event. The timer ensures there is no need to call into functions 197 + + * that might freeze on us, while still allowing us to show a timeout counter. 198 + + */ 199 + +EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) { 200 + static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; 201 + static BOOLEAN checked; 202 + UINTN index; 203 + EFI_INPUT_KEY k; 204 + EFI_STATUS err; 205 + + _cleanup_(EventClosep) EFI_EVENT timer = NULL; 206 + + EFI_EVENT events[3] = { ST->ConIn->WaitForKey }; 207 + + UINTN n_events = 1; 208 + 209 + if (!checked) { 210 + err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx); 211 + - if (EFI_ERROR(err)) 212 + + if (EFI_ERROR(err) || 213 + + uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx) == EFI_INVALID_PARAMETER) 214 + + /* If WaitForKeyEx fails here, the firmware pretends it talks this 215 + + * protocol, but it really doesn't. */ 216 + TextInputEx = NULL; 217 + + else 218 + + events[n_events++] = TextInputEx->WaitForKeyEx; 219 + 220 + checked = TRUE; 221 + } 222 + 223 + - /* wait until key is pressed */ 224 + - if (wait) 225 + - uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index); 226 + + if (timeout_usec > 0) { 227 + + err = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &timer); 228 + + if (EFI_ERROR(err)) 229 + + return log_error_status_stall(err, L"Error creating timer event: %r", err); 230 + + 231 + + /* SetTimer expects 100ns units for some reason. */ 232 + + err = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerRelative, timeout_usec * 10); 233 + + if (EFI_ERROR(err)) 234 + + return log_error_status_stall(err, L"Error arming timer event: %r", err); 235 + 236 + - if (TextInputEx) { 237 + + events[n_events++] = timer; 238 + + } 239 + + 240 + + err = uefi_call_wrapper(BS->WaitForEvent, 3, n_events, events, &index); 241 + + if (EFI_ERROR(err)) 242 + + return log_error_status_stall(err, L"Error waiting for events: %r", err); 243 + + 244 + + if (timeout_usec > 0 && timer == events[index]) 245 + + return EFI_TIMEOUT; 246 + + 247 + + /* TextInputEx might be ready too even if ConIn got to signal first. */ 248 + + if (TextInputEx && !EFI_ERROR(uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx))) { 249 + EFI_KEY_DATA keydata; 250 + UINT64 keypress; 251 + + UINT32 shift = 0; 252 + 253 + err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata); 254 + - if (!EFI_ERROR(err)) { 255 + - UINT32 shift = 0; 256 + - 257 + - /* do not distinguish between left and right keys */ 258 + - if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) { 259 + - if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED)) 260 + - shift |= EFI_CONTROL_PRESSED; 261 + - if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED)) 262 + - shift |= EFI_ALT_PRESSED; 263 + - }; 264 + - 265 + - /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */ 266 + - keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar); 267 + - if (keypress > 0) { 268 + - *key = keypress; 269 + - return 0; 270 + - } 271 + + if (EFI_ERROR(err)) 272 + + return err; 273 + + 274 + + /* do not distinguish between left and right keys */ 275 + + if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) { 276 + + if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED)) 277 + + shift |= EFI_CONTROL_PRESSED; 278 + + if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED)) 279 + + shift |= EFI_ALT_PRESSED; 280 + + }; 281 + + 282 + + /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */ 283 + + keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar); 284 + + if (keypress > 0) { 285 + + *key = keypress; 286 + + return EFI_SUCCESS; 287 + } 288 + + 289 + + return EFI_NOT_READY; 290 + } 291 + 292 + - /* fallback for firmware which does not support SimpleTextInputExProtocol 293 + - * 294 + - * This is also called in case ReadKeyStrokeEx did not return a key, because 295 + - * some broken firmwares offer SimpleTextInputExProtocol, but never actually 296 + - * handle any key. */ 297 + err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k); 298 + if (EFI_ERROR(err)) 299 + return err; 300 + 301 + *key = KEYPRESS(0, k.ScanCode, k.UnicodeChar); 302 + - return 0; 303 + + return EFI_SUCCESS; 304 + } 305 + 306 + static EFI_STATUS change_mode(UINTN mode) { 307 + diff --git a/src/boot/efi/console.h b/src/boot/efi/console.h 308 + index 2c69af552a..23848a9c58 100644 309 + --- a/src/boot/efi/console.h 310 + +++ b/src/boot/efi/console.h 311 + @@ -16,5 +16,5 @@ enum console_mode_change_type { 312 + CONSOLE_MODE_MAX, 313 + }; 314 + 315 + -EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait); 316 + +EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec); 317 + EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how); 318 + -- 319 + 2.33.0 320 +
+8
pkgs/os-specific/linux/systemd/default.nix
··· 164 164 # all our root unit dirs if they are symlinks. This does exactly what we 165 165 # need (AFAICT). 166 166 ./0019-core-handle-lookup-paths-being-symlinks.patch 167 + 168 + # In v248 compiler weirdness and refactoring lead to the bootloader 169 + # erroring out handling keyboard input on some systems. See 170 + # https://github.com/systemd/systemd/issues/19191 171 + # This should be redundant in v249.6 when it offically gets tagged in 172 + # systemd-stable 173 + ./0020-sd-boot-Unify-error-handling.patch 174 + ./0021-sd-boot-Rework-console-input-handling.patch 167 175 ] ++ lib.optional stdenv.hostPlatform.isMusl (let 168 176 oe-core = fetchzip { 169 177 url = "https://git.openembedded.org/openembedded-core/snapshot/openembedded-core-14c6e5a4b72d0e4665279158a0740dd1dc21f72f.tar.bz2";