lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Mon, 7 Feb 2022 16:16:18 +0100
From:   Krzysztof Adamski <krzysztof.adamski@...ia.com>
To:     Catalin Marinas <catalin.marinas@....com>,
        Will Deacon <will@...nel.org>,
        Mark Rutland <mark.rutland@....com>,
        Peter Collingbourne <pcc@...gle.com>,
        Guenter Roeck <linux@...ck-us.net>,
        Wolfram Sang <wsa+renesas@...g-engineering.com>,
        Ard Biesheuvel <ardb@...nel.org>
Cc:     Alexander Sverdlin <alexander.sverdlin@...ia.com>,
        linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
        linux-efi@...r.kernel.org
Subject: [PATCH v3] arm64: move efi_reboot to restart handler

On EFI enabled arm64 systems, efi_reboot was called before
do_kernel_restart, completely omitting the reset_handlers functionality.
By registering efi_reboot as part of the chain with elevated priority,
we make it run before the default handler but still allow plugging in
other handlers.

This is useful in two scenarios:
 - Abusing the restart handler as a notification mechanism similar to
   reboot notifiers, but working in wider spectrum of cases, (notably
   also at emergency_restart) and just before reset. This is useful for
   things like in-kernel pwrseq_emmc, or any other place where it is
   beneficial for an *external* component to know about the restart, but
   not performing the reset itself.
 - Providing higher priority reset handler, where resetting the SoC is
   not enough, and reset of the whole board should be orchestrated by
   some external component, that the firmware is not aware of (like an
   FPGA or some PMIC).

This change moves the conditional efi_reboot() call from arm64 specific
machine_restart() function to an arm efi initialization code where it is
registered as a restart handler with a very high (but not the highest)
priority, leaving a small window of opportunity for some code to be run
prior to the actual reset, like on other architectures.

The restart handlers mechanism is proven to work reliably as we depend
on it heavily on other platforms so there is almost no cost for this
change but it adds flexibility and unifies our infrastructure with other
ports (where one can depend on restart handlers working).

Signed-off-by: Krzysztof Adamski <krzysztof.adamski@...ia.com>
---

While previous attempts got mixed feedback, my explanations did not seen
counterarguments so I am trying another round:

Changes in v3:
  - Bump the priority much higher, to almost maximal value
  - Add a comment discouraging from registering higher prio handlers
  - Update the commit message to contain some more justifications

Changes in v2:
  - Register the handler in EFI code, instead of arm64 setup.c
  - Remove the contdition from the handler - it should be run in all
    cases when it is registered
  - Bump the priority to 130 to make it completly obious this should be
    run before PSCI (which has priority of 129)

 arch/arm64/kernel/process.c        |  7 -------
 drivers/firmware/efi/arm-runtime.c | 25 +++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..b86ef77bb0c8 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -130,13 +130,6 @@ void machine_restart(char *cmd)
 	local_irq_disable();
 	smp_send_stop();
 
-	/*
-	 * UpdateCapsule() depends on the system being reset via
-	 * ResetSystem().
-	 */
-	if (efi_enabled(EFI_RUNTIME_SERVICES))
-		efi_reboot(reboot_mode, NULL);
-
 	/* Now call the architecture specific reboot code. */
 	do_kernel_restart(cmd);
 
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index 3359ae2adf24..b29f47783bbc 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -80,6 +80,28 @@ static bool __init efi_virtmap_init(void)
 	return true;
 }
 
+static int efi_restart(struct notifier_block *nb, unsigned long action,
+		       void *data)
+{
+	/*
+	 * UpdateCapsule() depends on the system being reset via
+	 * ResetSystem().
+	 */
+	efi_reboot(reboot_mode, NULL);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block efi_restart_nb = {
+	.notifier_call = efi_restart,
+	/**
+	 * If you are running UEFI based system, you most certainly should let
+	 * efi_reboot() do a reset for you. If you think you know better, we
+	 * leave you a window of opportunity here by not using maximal priority.
+	 */
+	.priority = 251,
+};
+
 /*
  * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
  * non-early mapping of the UEFI system table and virtual mappings for all
@@ -148,6 +170,9 @@ static int __init arm_enable_runtime_services(void)
 	efi_native_runtime_setup();
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 
+	if (IS_ENABLED(CONFIG_ARM64))
+		register_restart_handler(&efi_restart_nb);
+
 	return 0;
 }
 early_initcall(arm_enable_runtime_services);
-- 
2.34.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ