Joel Kitching has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36300 )
Change subject: vboot: use vboot persistent context ......................................................................
vboot: use vboot persistent context
vb2_context object is now stored on the workbuf as part of vb2_shared_data. Use vboot's new API functions vb2api_init and vb2api_reinit to create and restore the context object respectively.
BUG=b:124141368, chromium:994060 TEST=Build locally BRANCH=none
Change-Id: I051be1e47bf79b15a1689d49a5d4c031e9363dfa Signed-off-by: Joel Kitching kitching@google.com --- M 3rdparty/blobs M src/mainboard/google/drallion/chromeos.c M src/mainboard/google/sarien/chromeos.c M src/security/vboot/bootmode.c M src/security/vboot/common.c M src/security/vboot/misc.h M src/security/vboot/vboot_logic.c 7 files changed, 64 insertions(+), 64 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/00/36300/1
diff --git a/3rdparty/blobs b/3rdparty/blobs index 62aa0e0..678b4c4 160000 --- a/3rdparty/blobs +++ b/3rdparty/blobs @@ -1 +1 @@ -Subproject commit 62aa0e0c54295bbb7b1a3e5e73f960bafdb59d04 +Subproject commit 678b4c4a81069bb6e10e2e59f5374b83d727cd2b diff --git a/src/mainboard/google/drallion/chromeos.c b/src/mainboard/google/drallion/chromeos.c index 0eb311b..00571ed 100644 --- a/src/mainboard/google/drallion/chromeos.c +++ b/src/mainboard/google/drallion/chromeos.c @@ -95,8 +95,8 @@ * and the value from the TPM would be wrong anyway since the verstage * read would have cleared the value on the TPM. * - * The TPM recovery request is passed between stages through the - * vboot_get_shared_data or cbmem depending on stage. + * The TPM recovery request is passed between stages through vboot data + * or cbmem depending on stage. */ if (ENV_VERSTAGE && tlcl_cr50_get_recovery_button(&cr50_state) == TPM_SUCCESS && diff --git a/src/mainboard/google/sarien/chromeos.c b/src/mainboard/google/sarien/chromeos.c index 6643d9b..bdd414c 100644 --- a/src/mainboard/google/sarien/chromeos.c +++ b/src/mainboard/google/sarien/chromeos.c @@ -93,8 +93,8 @@ * and the value from the TPM would be wrong anyway since the verstage * read would have cleared the value on the TPM. * - * The TPM recovery request is passed between stages through the - * vboot_get_shared_data or cbmem depending on stage. + * The TPM recovery request is passed between stages through vboot data + * or cbmem depending on stage. */ if (ENV_VERSTAGE && tlcl_cr50_get_recovery_button(&cr50_state) == TPM_SUCCESS && diff --git a/src/security/vboot/bootmode.c b/src/security/vboot/bootmode.c index 4625bcd..25650b4 100644 --- a/src/security/vboot/bootmode.c +++ b/src/security/vboot/bootmode.c @@ -26,7 +26,8 @@
static int vboot_get_recovery_reason_shared_data(void) { - struct vb2_shared_data *sd = vboot_get_shared_data(); + struct vb2_shared_data *sd = + (struct vb2_shared_data *)vboot_get_workbuf(); assert(sd); return sd->recovery_reason; } diff --git a/src/security/vboot/common.c b/src/security/vboot/common.c index 626fbc5..421c7a7 100644 --- a/src/security/vboot/common.c +++ b/src/security/vboot/common.c @@ -40,40 +40,40 @@ return wd; }
-void vboot_init_work_context(struct vb2_context *ctx) +struct vb2_context *vboot_get_context(void) { + static struct vb2_context *ctx; struct vboot_working_data *wd;
- /* First initialize the working data region. */ + /* Return if context has already been restored / initialized. */ + if (ctx) + return ctx; + wd = vboot_get_working_data(); - memset(wd, 0, VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE); + + /* Restore context from a previous stage. */ + if (wd->buffer_offset == ALIGN_UP(sizeof(*wd), 16)) { + assert(vb2api_reinit(vboot_get_workbuf(), &ctx)); + return ctx; + }
/* * vboot prefers 16-byte alignment. This takes away 16 bytes * from the VBOOT2_WORK region, but the vboot devs said that's okay. */ + memset(wd, 0, sizeof(*wd)); wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16); wd->buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE - wd->buffer_offset;
- /* Initialize the vb2_context. */ - memset(ctx, 0, sizeof(*ctx)); - ctx->workbuf = (void *)vboot_get_shared_data(); - ctx->workbuf_size = wd->buffer_size; + /* Initialize vb2_shared_data and friends. */ + assert(vb2api_init(vboot_get_workbuf(), wd->buffer_size, &ctx) + == VB2_SUCCESS); + + return ctx; }
-void vboot_finalize_work_context(struct vb2_context *ctx) -{ - /* - * Shrink buffer_size so that vboot_migrate_cbmem knows how - * much of vboot_working_data needs to be copied into CBMEM - * (if applicable), and so that downstream users know how much - * of the workbuf is currently used. - */ - vboot_get_working_data()->buffer_size = ctx->workbuf_used; -} - -struct vb2_shared_data *vboot_get_shared_data(void) +void *vboot_get_workbuf(void) { struct vboot_working_data *wd = vboot_get_working_data(); return (void *)((uintptr_t)wd + wd->buffer_offset); @@ -128,7 +128,8 @@ { const struct vboot_working_data *wd_preram = (struct vboot_working_data *)_vboot2_work; - size_t cbmem_size = wd_preram->buffer_offset + wd_preram->buffer_size; + /* TODO: We don't know the workbuf size with the current API... */ + size_t cbmem_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE; struct vboot_working_data *wd_cbmem = cbmem_add(CBMEM_ID_VBOOT_WORKBUF, cbmem_size); assert(wd_cbmem != NULL); diff --git a/src/security/vboot/misc.h b/src/security/vboot/misc.h index 1458354..c64214b 100644 --- a/src/security/vboot/misc.h +++ b/src/security/vboot/misc.h @@ -54,9 +54,8 @@ * Source: security/vboot/common.c */ struct vboot_working_data *vboot_get_working_data(void); -void vboot_init_work_context(struct vb2_context *ctx); -void vboot_finalize_work_context(struct vb2_context *ctx); -struct vb2_shared_data *vboot_get_shared_data(void); +struct vb2_context *vboot_get_context(void); +void *vboot_get_workbuf(void);
/* Returns 0 on success. < 0 on failure. */ int vboot_get_selected_region(struct region *region); diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index da6231a..5110147 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -319,17 +319,17 @@ */ void verstage_main(void) { - struct vb2_context ctx; + struct vb2_context *ctx; struct region_device fw_main; vb2_error_t rv;
timestamp_add_now(TS_START_VBOOT);
/* Set up context and work buffer */ - vboot_init_work_context(&ctx); + ctx = vboot_get_context();
/* Initialize and read nvdata from non-volatile storage. */ - vbnv_init(ctx.nvdata); + vbnv_init(ctx->nvdata);
/* Set S3 resume flag if vboot should behave differently when selecting * which slot to boot. This is only relevant to vboot if the platform @@ -337,51 +337,51 @@ * the same slot that it booted from. */ if (CONFIG(RESUME_PATH_SAME_AS_BOOT) && vboot_platform_is_resuming()) - ctx.flags |= VB2_CONTEXT_S3_RESUME; + ctx->flags |= VB2_CONTEXT_S3_RESUME;
/* Read secdata from TPM. Initialize TPM if secdata not found. We don't * check the return value here because vb2api_fw_phase1 will catch * invalid secdata and tell us what to do (=reboot). */ timestamp_add_now(TS_START_TPMINIT); - if (vboot_setup_tpm(&ctx) == TPM_SUCCESS) - antirollback_read_space_firmware(&ctx); + if (vboot_setup_tpm(ctx) == TPM_SUCCESS) + antirollback_read_space_firmware(ctx); timestamp_add_now(TS_END_TPMINIT);
/* Enable measured boot mode */ if (CONFIG(VBOOT_MEASURED_BOOT) && - !(ctx.flags & VB2_CONTEXT_S3_RESUME)) { + !(ctx->flags & VB2_CONTEXT_S3_RESUME)) { if (vboot_init_crtm() != VB2_SUCCESS) die_with_post_code(POST_INVALID_ROM, "Initializing measured boot mode failed!"); }
if (get_recovery_mode_switch()) { - ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE; + ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE; if (CONFIG(VBOOT_DISABLE_DEV_ON_RECOVERY)) - ctx.flags |= VB2_CONTEXT_DISABLE_DEVELOPER_MODE; + ctx->flags |= VB2_CONTEXT_DISABLE_DEVELOPER_MODE; }
if (CONFIG(VBOOT_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch()) - ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE; + ctx->flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
if (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch()) - ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT; + ctx->flags |= VB2_CONTEXT_NOFAIL_BOOT;
/* Mainboard/SoC always initializes display. */ if (!CONFIG(VBOOT_MUST_REQUEST_DISPLAY)) - ctx.flags |= VB2_CONTEXT_DISPLAY_INIT; + ctx->flags |= VB2_CONTEXT_DISPLAY_INIT;
/* Do early init (set up secdata and NVRAM, load GBB) */ printk(BIOS_INFO, "Phase 1\n"); - rv = vb2api_fw_phase1(&ctx); + rv = vb2api_fw_phase1(ctx);
/* Jot down some information from vboot which may be required later on in coreboot boot flow. */ - if (ctx.flags & VB2_CONTEXT_DISPLAY_INIT) + if (ctx->flags & VB2_CONTEXT_DISPLAY_INIT) /* Mainboard/SoC should initialize display. */ vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; - if (ctx.flags & VB2_CONTEXT_DEVELOPER_MODE) + if (ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DEVELOPER_MODE;
if (rv) { @@ -393,58 +393,58 @@ */ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) { printk(BIOS_INFO, "Recovery requested (%x)\n", rv); - save_if_needed(&ctx); - extend_pcrs(&ctx); /* ignore failures */ + save_if_needed(ctx); + extend_pcrs(ctx); /* ignore failures */ goto verstage_main_exit; }
printk(BIOS_INFO, "Reboot requested (%x)\n", rv); - save_if_needed(&ctx); + save_if_needed(ctx); vboot_reboot(); }
/* Determine which firmware slot to boot (based on NVRAM) */ printk(BIOS_INFO, "Phase 2\n"); - rv = vb2api_fw_phase2(&ctx); + rv = vb2api_fw_phase2(ctx); if (rv) { printk(BIOS_INFO, "Reboot requested (%x)\n", rv); - save_if_needed(&ctx); + save_if_needed(ctx); vboot_reboot(); }
/* Try that slot (verify its keyblock and preamble) */ printk(BIOS_INFO, "Phase 3\n"); timestamp_add_now(TS_START_VERIFY_SLOT); - rv = vb2api_fw_phase3(&ctx); + rv = vb2api_fw_phase3(ctx); timestamp_add_now(TS_END_VERIFY_SLOT); if (rv) { printk(BIOS_INFO, "Reboot requested (%x)\n", rv); - save_if_needed(&ctx); + save_if_needed(ctx); vboot_reboot(); }
printk(BIOS_INFO, "Phase 4\n"); - rv = locate_firmware(&ctx, &fw_main); + rv = locate_firmware(ctx, &fw_main); if (rv) die_with_post_code(POST_INVALID_ROM, "Failed to read FMAP to locate firmware");
- rv = hash_body(&ctx, &fw_main); - save_if_needed(&ctx); + rv = hash_body(ctx, &fw_main); + save_if_needed(ctx); if (rv) { printk(BIOS_INFO, "Reboot requested (%x)\n", rv); vboot_reboot(); }
/* Only extend PCRs once on boot. */ - if (!(ctx.flags & VB2_CONTEXT_S3_RESUME)) { + if (!(ctx->flags & VB2_CONTEXT_S3_RESUME)) { timestamp_add_now(TS_START_TPMPCR); - rv = extend_pcrs(&ctx); + rv = extend_pcrs(ctx); if (rv) { printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv); - vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv); - save_if_needed(&ctx); + vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv); + save_if_needed(ctx); vboot_reboot(); } timestamp_add_now(TS_END_TPMPCR); @@ -456,8 +456,8 @@ rv = antirollback_lock_space_firmware(); if (rv) { printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv); - vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0); - save_if_needed(&ctx); + vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0); + save_if_needed(ctx); vboot_reboot(); } timestamp_add_now(TS_END_TPMLOCK); @@ -468,14 +468,14 @@ if (rv) { printk(BIOS_INFO, "Failed to lock rec hash space(%x)\n", rv); - vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR, + vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR, 0); - save_if_needed(&ctx); + save_if_needed(ctx); vboot_reboot(); } }
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B'); + printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(ctx) ? 'A' : 'B'); vboot_set_selected_region(region_device_region(&fw_main));
verstage_main_exit: @@ -487,6 +487,5 @@ /* Save recovery reason in case of unexpected reboots on x86. */ vboot_save_recovery_reason_vbnv();
- vboot_finalize_work_context(&ctx); timestamp_add_now(TS_END_VBOOT); }