From f2dcd9dd81575aa74cb695feeae4135014402205 Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Mon, 5 Dec 2022 14:43:46 -0700 Subject: [PATCH] security/vboot: Update vbnv_init signature If the temporary nvdata storage inside the vboot context is already initialized then return immediately without reinitializing from the backup NV storage. This allows vbnv_init to be called more than once. Also the check to enable USB Device Controller (UDC) happens after NVdata is initialized. Hence the nvdata in vboot context can be used instead of reading from the backup storage again. BUG=b:242825052 TEST=Build Skyrim BIOS image and boot to OS in Skyrim. Change-Id: Id72709e2fc3fe6a12ee96df8df25e55cf11e50a7 Signed-off-by: Karthikeyan Ramasubramanian Reviewed-on: https://review.coreboot.org/c/coreboot/+/70380 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Julius Werner --- src/security/vboot/vbnv.c | 40 +++++++++++++++++--------------- src/security/vboot/vbnv.h | 2 +- src/security/vboot/vboot_logic.c | 2 +- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/security/vboot/vbnv.c b/src/security/vboot/vbnv.c index e9223c08ae..1428a30b33 100644 --- a/src/security/vboot/vbnv.c +++ b/src/security/vboot/vbnv.c @@ -3,11 +3,12 @@ #include #include #include +#include #include #include +#include -static int vbnv_initialized; -static uint8_t vbnv[VBOOT_VBNV_BLOCK_SIZE]; +static bool vbnv_initialized; /* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. */ static uint8_t crc8_vbnv(const uint8_t *data, int len) @@ -32,15 +33,6 @@ void vbnv_reset(uint8_t *vbnv_copy) memset(vbnv_copy, 0, VBOOT_VBNV_BLOCK_SIZE); } -/* Read VBNV data into cache. */ -static void vbnv_setup(void) -{ - if (!vbnv_initialized) { - read_vbnv(vbnv); - vbnv_initialized = 1; - } -} - /* Verify VBNV header and checksum. */ int verify_vbnv(uint8_t *vbnv_copy) { @@ -84,21 +76,31 @@ void save_vbnv(const uint8_t *vbnv_copy) save_vbnv_flash(vbnv_copy); else dead_code(); - - /* Clear initialized flag to force cached data to be updated */ - vbnv_initialized = 0; } /* Read the USB Device Controller(UDC) enable flag from VBNV. */ int vbnv_udc_enable_flag(void) { - vbnv_setup(); - return (vbnv[DEV_FLAGS_OFFSET] & DEV_ENABLE_UDC) ? 1 : 0; + struct vb2_context *ctx = vboot_get_context(); + + /* This function is expected to be called after temporary nvdata storage in vboot + context is initialized. */ + assert(vbnv_initialized); + + return (ctx->nvdata[DEV_FLAGS_OFFSET] & DEV_ENABLE_UDC) ? 1 : 0; } -void vbnv_init(uint8_t *vbnv_copy) +void vbnv_init(void) { + struct vb2_context *ctx; + + /* NV data already initialized and read */ + if (vbnv_initialized) + return; + + ctx = vboot_get_context(); if (CONFIG(VBOOT_VBNV_CMOS)) - vbnv_init_cmos(vbnv_copy); - read_vbnv(vbnv_copy); + vbnv_init_cmos(ctx->nvdata); + read_vbnv(ctx->nvdata); + vbnv_initialized = true; } diff --git a/src/security/vboot/vbnv.h b/src/security/vboot/vbnv.h index eb435e2e58..c4112a2b29 100644 --- a/src/security/vboot/vbnv.h +++ b/src/security/vboot/vbnv.h @@ -15,7 +15,7 @@ void regen_vbnv_crc(uint8_t *vbnv_copy); int vbnv_udc_enable_flag(void); /* Initialize and read vbnv. This is used in the main vboot logic path. */ -void vbnv_init(uint8_t *vbnv_copy); +void vbnv_init(void); /* Reset vbnv snapshot to a known state. */ void vbnv_reset(uint8_t *vbnv_copy); diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index f7b4801ad1..a72ea87c7f 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -249,7 +249,7 @@ void verstage_main(void) ctx = vboot_get_context(); /* Initialize and read nvdata from non-volatile storage. */ - vbnv_init(ctx->nvdata); + vbnv_init(); /* Set S3 resume flag if vboot should behave differently when selecting * which slot to boot. This is only relevant to vboot if the platform