summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@google.com>2022-11-29 13:20:45 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-12-09 19:12:36 +0000
commitd19765a9507e33c697bfd18038f860e62bd99161 (patch)
treee227ef9cb5b711fe7472c36d98f725c4ec45d4c6 /tests
parent05b81fcc18c905613ef56e09ca100ef79a6ee5d2 (diff)
downloadvboot-d19765a9507e33c697bfd18038f860e62bd99161.tar.gz
firmware/2lib: Introduce API to report previous boot failure
Currently when failures are reported before a slot is selected, vboot directly requests for recovery. Add a new API to report previous boot failure before a slot is selected. This will allow coreboot verstage to report any failures that happened in the previous boot such that verified boot can select the appropriate FW slot instead of booting into recovery mode directly. BUG=b:242825052 BRANCH=None TEST=Build Skyrim BIOS image. Run the unit test built for this API. Boot to OS in Skyrim. Corrupt certain sections in flashmap and report boot failures and ensured that vboot selected the appropriate FW slot. Change-Id: I3b1fe8e28fc754919cd4067eeed5029e7dbae7a4 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4064425 Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/vb2_misc_tests.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/tests/vb2_misc_tests.c b/tests/vb2_misc_tests.c
index 0365f008..b73c0478 100644
--- a/tests/vb2_misc_tests.c
+++ b/tests/vb2_misc_tests.c
@@ -390,10 +390,10 @@ static void fail_tests(void)
reset_common_data();
vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
+ vb2_nv_set(ctx, VB2_NV_FW_TRIED, 0);
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, 1);
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, VB2_FW_RESULT_UNKNOWN);
sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
- sd->fw_slot = 0;
- sd->last_fw_slot = 1;
- sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
vb2api_fail(ctx, 5, 6);
TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), 0, "vb2_failover");
TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
@@ -405,10 +405,10 @@ static void fail_tests(void)
/* Fail with other slot already failing triggers recovery */
reset_common_data();
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, 0);
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, VB2_FW_RESULT_FAILURE);
+ vb2_nv_set(ctx, VB2_NV_FW_TRIED, 1);
sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
- sd->fw_slot = 1;
- sd->last_fw_slot = 0;
- sd->last_fw_result = VB2_FW_RESULT_FAILURE;
vb2api_fail(ctx, 7, 8);
TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), 7,
"vb2api_fail both slots bad");
@@ -418,6 +418,60 @@ static void fail_tests(void)
"vb2api_fail try other slot");
}
+static void previous_boot_fail_tests(void)
+{
+ /* Previous boot fail (before even NV init) */
+ /* Fail with other slot good doesn't trigger recovery */
+ reset_common_data();
+ vb2_nv_set(ctx, VB2_NV_FW_TRIED, VB2_FW_SLOT_A);
+ vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
+ vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
+ sd->status &= ~VB2_SD_STATUS_NV_INIT;
+ vb2api_previous_boot_fail(ctx, 1, 2);
+ TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT,
+ 0, "vb2api_previous_boot_fail inits NV");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ 0, "vb2_previous_boot_fail over");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
+ VB2_FW_RESULT_FAILURE, "vb2api_previous_boot_fail result");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT),
+ 0, "vb2api_previous_boot_fail try count");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT),
+ 1, "vb2api_previous_boot_fail FW tried");
+
+ /* Fail with other slot already failing triggers recovery */
+ reset_common_data();
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, VB2_FW_SLOT_A);
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, VB2_FW_RESULT_FAILURE);
+ vb2_nv_set(ctx, VB2_NV_FW_TRIED, VB2_FW_SLOT_B);
+ vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
+ vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
+ sd->status &= ~VB2_SD_STATUS_NV_INIT;
+ vb2api_previous_boot_fail(ctx, 3, 4);
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ 3, "vb2api_previous_boot_fail both slots bad");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
+ VB2_FW_RESULT_FAILURE, "vb2api_previous_boot_fail result");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT),
+ 0, "vb2api_previous_boot_fail try count");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT),
+ 0, "vb2api_previous_boot_fail FW tried");
+
+ /* Repeated fail doesn't overwrite the error code */
+ reset_common_data();
+ vb2_nv_set(ctx, VB2_NV_TRY_NEXT, VB2_FW_SLOT_A);
+ vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
+ vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
+ sd->status &= ~VB2_SD_STATUS_NV_INIT;
+ vb2api_previous_boot_fail(ctx, 5, 6);
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
+ VB2_FW_RESULT_FAILURE, "vb2api_previous_boot_fail result");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT),
+ 3, "vb2api_previous_boot_fail try count");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT),
+ VB2_FW_SLOT_A, "vb2api_previous_boot_fail try next");
+}
+
static void recovery_tests(void)
{
/* No recovery */
@@ -1085,6 +1139,7 @@ int main(int argc, char* argv[])
misc_tests();
gbb_tests();
fail_tests();
+ previous_boot_fail_tests();
recovery_tests();
dev_switch_tests();
enable_dev_tests();