efi_selftest: test reboot by watchdog

A test is added that verifies that the watchdog timer actually
causes a reboot upon timeout. The test is only executed on
request using

    setenv efi_selftest watchdog reboot
    bootefi selftest

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Heinrich Schuchardt 2017-10-18 18:13:16 +02:00 committed by Alexander Graf
parent b57f48a87c
commit 7bbae6f293

View file

@ -5,11 +5,16 @@
* *
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
* *
* This unit test checks that the watchdog timer will not cause * The 'watchdog timer' unit test checks that the watchdog timer
* a system restart during the timeout period after a timer reset. * will not cause a system restart during the timeout period after
* a timer reset.
* *
* Testing that the watchdog timer actually will reset the system * The 'watchdog reboot' unit test checks that the watchdog timer
* after a timeout is not possible within the used framework. * actually reboots the system after a timeout. The test is only
* executed on explicit request. Use the following commands:
*
* setenv efi_selftest watchdog reboot
* bootefi selftest
*/ */
#include <efi_selftest.h> #include <efi_selftest.h>
@ -28,6 +33,7 @@ static struct efi_event *event_notify;
static struct efi_event *event_wait; static struct efi_event *event_wait;
static struct efi_boot_services *boottime; static struct efi_boot_services *boottime;
static struct notify_context notification_context; static struct notify_context notification_context;
static bool watchdog_reset;
/* /*
* Notification function, increments the notfication count if parameter * Notification function, increments the notfication count if parameter
@ -88,6 +94,34 @@ static int setup(const efi_handle_t handle,
return EFI_ST_SUCCESS; return EFI_ST_SUCCESS;
} }
/*
* Execute the test resetting the watchdog in a timely manner. No reboot occurs.
*
* @handle: handle of the loaded image
* @systable: system table
* @return: EFI_ST_SUCCESS for success
*/
static int setup_timer(const efi_handle_t handle,
const struct efi_system_table *systable)
{
watchdog_reset = true;
return setup(handle, systable);
}
/*
* Execute the test without resetting the watchdog. A system reboot occurs.
*
* @handle: handle of the loaded image
* @systable: system table
* @return: EFI_ST_SUCCESS for success
*/
static int setup_reboot(const efi_handle_t handle,
const struct efi_system_table *systable)
{
watchdog_reset = false;
return setup(handle, systable);
}
/* /*
* Tear down unit test. * Tear down unit test.
* *
@ -146,11 +180,14 @@ static int execute(void)
efi_st_error("Setting watchdog timer failed\n"); efi_st_error("Setting watchdog timer failed\n");
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }
/* Set 600 ms timer */ if (watchdog_reset) {
ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 6000000); /* Set 600 ms timer */
if (ret != EFI_SUCCESS) { ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC,
efi_st_error("Could not set timer\n"); 6000000);
return EFI_ST_FAILURE; if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
} }
/* Set 1350 ms timer */ /* Set 1350 ms timer */
ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 13500000); ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 13500000);
@ -176,10 +213,19 @@ static int execute(void)
return EFI_ST_SUCCESS; return EFI_ST_SUCCESS;
} }
EFI_UNIT_TEST(watchdog) = { EFI_UNIT_TEST(watchdog1) = {
.name = "watchdog timer", .name = "watchdog timer",
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
.setup = setup, .setup = setup_timer,
.execute = execute, .execute = execute,
.teardown = teardown, .teardown = teardown,
}; };
EFI_UNIT_TEST(watchdog2) = {
.name = "watchdog reboot",
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
.setup = setup_reboot,
.execute = execute,
.teardown = teardown,
.on_request = true,
};