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 <kramasub@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/70380
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Karthikeyan Ramasubramanian 2022-12-05 14:43:46 -07:00 committed by Karthik Ramasubramanian
parent d901077335
commit f2dcd9dd81
3 changed files with 23 additions and 21 deletions

View File

@ -3,11 +3,12 @@
#include <assert.h>
#include <string.h>
#include <types.h>
#include <security/vboot/misc.h>
#include <security/vboot/vbnv.h>
#include <security/vboot/vbnv_layout.h>
#include <vb2_api.h>
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;
}

View File

@ -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);

View File

@ -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