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>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 19 Jun 2014 14:40:24 +0100
From:	Matt Fleming <matt@...sole-pimps.org>
To:	linux-efi@...r.kernel.org
Cc:	linux-kernel@...r.kernel.org, Alan Cox <alan@...rguk.ukuu.org.uk>,
	"H. Peter Anvin" <hpa@...or.com>, Mark Salter <msalter@...hat.com>,
	Aubrey Li <aubrey.li@...ux.intel.com>,
	Matt Fleming <matt.fleming@...el.com>
Subject: [PATCH 2/3] efi/reboot: Allow powering off machines using EFI

From: Matt Fleming <matt.fleming@...el.com>

Not only can EfiResetSystem() be used to reboot, it can also be used to
power down machines.

By and large, this functionality doesn't work very well across the range
of EFI machines in the wild, so it should definitely only be used as a
last resort. In an ideal world, this wouldn't be needed at all.

Unfortunately, we're starting to see machines where EFI is the *only*
reliable way to power down, and nothing else, not PCI, not ACPI, works.

efi_poweroff_required() should be implemented on a per-architecture
basis, since exactly when we should be using EFI runtime services is a
platform-specific decision. There's no analogue for reboot because each
architecture handles reboot very differently - the x86 code in
particular is pretty complex.

Patches to enable this for specific classes of hardware will be
submitted separately.

Cc: Mark Salter <msalter@...hat.com>
Signed-off-by: Matt Fleming <matt.fleming@...el.com>
---
 drivers/firmware/efi/reboot.c | 22 ++++++++++++++++++++++
 include/linux/efi.h           |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
index d10acc0a0370..794a276dbe92 100644
--- a/drivers/firmware/efi/reboot.c
+++ b/drivers/firmware/efi/reboot.c
@@ -23,3 +23,25 @@ void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
 
 	efi.reset_system(efi_mode, EFI_SUCCESS, 0, NULL);
 }
+
+bool __weak efi_poweroff_required(void)
+{
+	return false;
+}
+
+static void efi_power_off(void)
+{
+	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
+}
+
+static int __init efi_shutdown_init(void)
+{
+	if (!efi_enabled(EFI_RUNTIME_SERVICES))
+		return -ENODEV;
+
+	if (efi_poweroff_required())
+		pm_power_off = efi_power_off;
+
+	return 0;
+}
+late_initcall(efi_shutdown_init);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 0958d4bb399f..2539aff31808 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -876,6 +876,8 @@ extern void efi_reserve_boot_services(void);
 extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
 extern struct efi_memory_map memmap;
 
+extern bool efi_poweroff_required(void);
+
 /* Iterate through an efi_memory_map */
 #define for_each_efi_memory_desc(m, md)					   \
 	for ((md) = (m)->map;						   \
-- 
1.9.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists