From: Arthur Mesh <amesh@juniper.net>
To: <grub-devel@gnu.org>
Subject: [PATCH] Make EFI watchdog behaviour configurable
Date: Wed, 9 Sep 2015 17:11:33 -0700 [thread overview]
Message-ID: <20150910001133.GA35797@juniper.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 5757 bytes --]
Starting with d9a0c9413e81d3c0affc6383693bdd28dc863a5c, GRUB unconditionally
disables watchdog on EFI platforms. This opens up a window (starting at GRUB's
grub_efi_init(), until OS re-enables it) when EFI system operates w/o watchdog.
If an EFI system gets stuck in that window, the chipset will never reset the
system.
Add `--enable-efi-watchdog' configure argument, which defaults to Off.
When enabled, efi watchdog will not be disabled.
Otherwise, efi watchdog will be disabled.
Create a command line interface to enable/disable watchdog:
efi-watchdog (enable|disable) <timeout>
---
configure.ac | 18 +++++++++++++-
docs/grub.texi | 8 ++++++
grub-core/kern/efi/init.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index c864311..91de439 100644
--- a/configure.ac
+++ b/configure.ac
@@ -211,7 +211,10 @@ esac
case "$platform" in
coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;;
multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
- efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
+ efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1"
+ if test x"$enable_efi_watchdog" = xyes ; then
+ machine_CPPFLAGS="$machine_CPPFLAGS -DEFI_WATCHDOG_LEAVE_ALONE=1"
+ fi ;;
xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;;
ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
@@ -1705,6 +1708,10 @@ if test x"$enable_werror" != xno ; then
HOST_CFLAGS="$HOST_CFLAGS -Werror"
fi
+AC_ARG_ENABLE([efi-watchdog],
+ [AS_HELP_STRING([--enable-efi-watchdog],
+ [Do not explicitly disable EFI watchdog])])
+
TARGET_CPP="$TARGET_CC -E"
TARGET_CCAS=$TARGET_CC
@@ -1899,6 +1906,15 @@ echo efiemu runtime: Yes
else
echo efiemu runtime: No "($efiemu_excuse)"
fi
+
+if [ x"$platform" = xefi ]; then
+if [ x"$enable_efi_watchdog" != xyes ]; then
+echo disable EFI watchdog: Yes
+else
+echo disable EFI watchdog: No
+fi
+fi
+
if [ x"$grub_mkfont_excuse" = x ]; then
echo grub-mkfont: Yes
else
diff --git a/docs/grub.texi b/docs/grub.texi
index b9f41a7..4cfd50c 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -3784,6 +3784,7 @@ you forget a command, you can run the command @command{help}
* distrust:: Remove a pubkey from trusted keys
* drivemap:: Map a drive to another
* echo:: Display a line of text
+* efi-watchdog:: Manipulate EFI watchdog
* eval:: Evaluate agruments as GRUB commands
* export:: Export an environment variable
* false:: Do nothing, unsuccessfully
@@ -4192,6 +4193,13 @@ When interpreting backslash escapes, backslash followed by any other
character will print that character.
@end deffn
+@node efi-watchdog
+@subsection efi-watchdog
+
+@deffn Command efi-watchdog enable|disable <timeout>
+Enable or disable the system's watchdog timer. Only available in EFI targeted
+GRUB.
+@end deffn
@node eval
@subsection eval
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index e9c85de..47053d2 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -25,9 +25,62 @@
#include <grub/env.h>
#include <grub/mm.h>
#include <grub/kernel.h>
+#include <grub/extcmd.h>
+#include <grub/command.h>
grub_addr_t grub_modbase;
+static grub_command_t cmd_list;
+
+static grub_err_t
+grub_cmd_efi_watchdog (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ long input;
+ grub_efi_status_t status;
+ grub_efi_uintn_t timeout;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("efi-watchdog (enable|disable) <timeout>"));
+
+ if (grub_strcasecmp (args[0], "enable") == 0) {
+
+ if (argc != 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("efi-watchdog enable <timeout>"));
+
+ input = grub_strtol (args[1], 0, 0);
+
+ if (input >= 0) {
+ timeout = input;
+ } else {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("<timeout> must be non-negative"));
+ }
+
+ } else if (grub_strcasecmp (args[0], "disable") == 0) {
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("efi-watchdog disable"));
+ timeout = 0;
+
+ } else {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("efi-watchdog (enable|disable) <timeout>"));
+ }
+
+ status = efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
+ timeout, 0, sizeof(L"GRUB"), L"GRUB");
+
+ if (status != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_BUG,
+ N_("EFI SetWatchdogTimer() bug"));
+ else
+ return GRUB_ERR_NONE;
+}
+
void
grub_efi_init (void)
{
@@ -39,10 +92,15 @@ grub_efi_init (void)
/* Initialize the memory management system. */
grub_efi_mm_init ();
+#ifndef EFI_WATCHDOG_LEAVE_ALONE
efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
0, 0, 0, NULL);
+#endif
grub_efidisk_init ();
+
+ cmd_list = grub_register_command ("efi-watchdog", grub_cmd_efi_watchdog, 0,
+ N_("Enable/Disable system's watchdog timer."));
}
void (*grub_efi_net_config) (grub_efi_handle_t hnd,
@@ -77,4 +135,5 @@ grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_console_fini ();
+ grub_unregister_command (cmd_list);
}
--
1.7.9.5
[-- Attachment #2: Type: application/pgp-signature, Size: 648 bytes --]
next reply other threads:[~2015-09-10 0:11 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-10 0:11 Arthur Mesh [this message]
2015-09-11 14:32 ` [PATCH] Make EFI watchdog behaviour configurable Andrei Borzenkov
2015-09-11 14:53 ` Arthur Mesh
2015-09-11 15:24 ` Andrei Borzenkov
2015-09-11 15:57 ` Arthur Mesh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150910001133.GA35797@juniper.net \
--to=amesh@juniper.net \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.