From 886a9047f07d6bf9f424fd83247136c79706e136 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Mon, 11 Feb 2013 10:08:51 -0800 Subject: [PATCH] Software sync checks for shutdown-requested in all code paths Previously, 1) AP-RO, EC-RO -> checked 2) AP-RW, EC-RO transition to EC-RW -> checked 3) AP-RW, EC-RW already -> NOT checked Now, (3) calls VbExIsShutdownRequested() as well. This fix is needed to avoid inconsistent behavior of software sync after we ship a RW update. Whether we *should* actually shut down or not based on how/why we booted is a separate issue to be addressed by the U-boot implementation of VbExIsShutdownRequested() in a separate CL. BUG=chromium-os:38645 BRANCH=all TEST=make runtests Manual testing also possible - force AP-RW firmware, then reboot with lid closed. Previously, the first boot would shut down because of (2), but subsequent reboots of the AP only wouldn't because of (3). Change-Id: I226202f48d793b88a30ffa62731de878f8c22315 Signed-off-by: Randall Spangler Reviewed-on: https://gerrit.chromium.org/gerrit/43044 Reviewed-by: Simon Glass --- firmware/lib/vboot_api_kernel.c | 12 ++++++++++++ tests/vboot_api_kernel3_tests.c | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index 9b596fc247..a55d806499 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -742,6 +742,18 @@ VbError_t VbEcSoftwareSync(VbCommonParams *cparams) } VBDEBUG(("VbEcSoftwareSync() in EC-RW and it matches\n")); + + /* + * If shutdown is requested, just power the AP back off. This + * covers the case where the lid is closed when then system + * boots. + */ + if (VbExIsShutdownRequested()) { + VBDEBUG(("VbEcSoftwareSync() " + "sees shutdown-requested\n")); + return VBERROR_SHUTDOWN_REQUESTED; + } + return VBERROR_SUCCESS; } diff --git a/tests/vboot_api_kernel3_tests.c b/tests/vboot_api_kernel3_tests.c index 836a48de62..9ec6f19be3 100644 --- a/tests/vboot_api_kernel3_tests.c +++ b/tests/vboot_api_kernel3_tests.c @@ -35,6 +35,7 @@ static int ec_run_image; static int update_retval; static int ec_updated; static int get_expected_retval; +static int shutdown_request_calls_left; static uint8_t mock_ec_hash[32]; static int mock_ec_hash_size; @@ -79,6 +80,7 @@ static void ResetMocks(void) update_retval = VBERROR_SUCCESS; run_retval = VBERROR_SUCCESS; get_expected_retval = VBERROR_SUCCESS; + shutdown_request_calls_left = -1; Memset(mock_ec_hash, 0, sizeof(mock_ec_hash)); mock_ec_hash[0] = 42; @@ -99,6 +101,16 @@ static void ResetMocks(void) /* Mock functions */ +uint32_t VbExIsShutdownRequested(void) +{ + if (shutdown_request_calls_left == 0) + return 1; + else if (shutdown_request_calls_left > 0) + shutdown_request_calls_left--; + + return 0; +} + int VbExTrustEC(void) { return trust_ec; @@ -232,6 +244,11 @@ static void VbSoftwareSyncTest(void) test_ssync(VBERROR_SIMULATED, VBNV_RECOVERY_EC_PROTECT, "Protect error"); + ResetMocks(); + shared->flags |= VBSD_LF_USE_RO_NORMAL; + shutdown_request_calls_left = 0; + test_ssync(VBERROR_SHUTDOWN_REQUESTED, 0, "AP-RO shutdown requested"); + /* Calculate hashes */ ResetMocks(); mock_ec_hash_size = 0; @@ -325,6 +342,16 @@ static void VbSoftwareSyncTest(void) protect_retval = VBERROR_SIMULATED; test_ssync(VBERROR_SIMULATED, VBNV_RECOVERY_EC_PROTECT, "Protect error"); + + ResetMocks(); + shutdown_request_calls_left = 0; + test_ssync(VBERROR_SHUTDOWN_REQUESTED, 0, + "AP-RW, EC-RO -> EC-RW shutdown requested"); + + ResetMocks(); + mock_in_rw = 1; + shutdown_request_calls_left = 0; + test_ssync(VBERROR_SHUTDOWN_REQUESTED, 0, "AP-RW shutdown requested"); } int main(void)