From b5a20b29b7a2709b120e3c8258c2f16d9c38b590 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Tue, 6 Oct 2015 17:29:03 -0500 Subject: vboot: restructure vboot work buffer handling For the purpose of isolating the work buffer logic the surface area of the API was slimmed down. The vb2_working_data structure is no longer exposed, and the function signatures are updated accordingly. BUG=chrome-os-partner:44827 BRANCH=None TEST=Built and booted glados. Change-Id: If64184a79e9571ee8ef9822cfce1eda20fceee00 Signed-off-by: Aaron Durbin Reviewed-on: http://review.coreboot.org/11818 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/vendorcode/google/chromeos/vboot2/common.c | 75 +++++++++++++++++++++- src/vendorcode/google/chromeos/vboot2/misc.h | 52 +++------------ .../google/chromeos/vboot2/vboot_handoff.c | 7 +- .../google/chromeos/vboot2/vboot_loader.c | 12 +--- .../google/chromeos/vboot2/vboot_logic.c | 26 +------- 5 files changed, 89 insertions(+), 83 deletions(-) diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c index f6f5b96070..a33fb8e98e 100644 --- a/src/vendorcode/google/chromeos/vboot2/common.c +++ b/src/vendorcode/google/chromeos/vboot2/common.c @@ -21,14 +21,30 @@ #include #include #include +#include +#include #include "../chromeos.h" #include "../symbols.h" #include "../vboot_handoff.h" #include "misc.h" +/* + * this is placed at the start of the vboot work buffer. selected_region is used + * for the verstage to return the location of the selected slot. buffer is used + * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses + * stage boundaries. + */ +struct vb2_working_data { + uint32_t selected_region_offset; + uint32_t selected_region_size; + /* offset of the buffer from the start of this struct */ + uint32_t buffer_offset; + uint32_t buffer_size; +}; + static const size_t vb_work_buf_size = 16 * KiB; -struct vb2_working_data * const vboot_get_working_data(void) +static struct vb2_working_data * const vboot_get_working_data(void) { if (IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)) /* cbmem_add() does a cbmem_find() first. */ @@ -37,7 +53,7 @@ struct vb2_working_data * const vboot_get_working_data(void) return (struct vb2_working_data *)_vboot2_work; } -size_t vb2_working_data_size(void) +static size_t vb2_working_data_size(void) { if (IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)) return vb_work_buf_size; @@ -45,7 +61,60 @@ size_t vb2_working_data_size(void) return _vboot2_work_size; } -void *vboot_get_work_buffer(struct vb2_working_data *wd) +void vb2_init_work_context(struct vb2_context *ctx) { + struct vb2_working_data *wd; + size_t work_size; + + /* First initialize the working data region. */ + work_size = vb2_working_data_size(); + wd = vboot_get_working_data(); + memset(wd, 0, work_size); + + /* + * vboot prefers 16-byte alignment. This takes away 16 bytes + * from the VBOOT2_WORK region, but the vboot devs said that's okay. + */ + wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16); + wd->buffer_size = work_size - wd->buffer_offset; + + /* Initialize the vb2_context. */ + memset(ctx, 0, sizeof(*ctx)); + ctx->workbuf = (void *)vb2_get_shared_data(); + ctx->workbuf_size = wd->buffer_size; + +} + +struct vb2_shared_data *vb2_get_shared_data(void) +{ + struct vb2_working_data *wd = vboot_get_working_data(); return (void *)((uintptr_t)wd + wd->buffer_offset); } + +int vb2_get_selected_region(struct region_device *rdev) +{ + const struct vb2_working_data *wd = vboot_get_working_data(); + struct region reg = { + .offset = wd->selected_region_offset, + .size = wd->selected_region_size, + }; + return vboot_region_device(®, rdev); +} + +void vb2_set_selected_region(struct region_device *rdev) +{ + struct vb2_working_data *wd = vboot_get_working_data(); + wd->selected_region_offset = region_device_offset(rdev); + wd->selected_region_size = region_device_sz(rdev); +} + +int vboot_is_slot_selected(void) +{ + const struct vb2_working_data *wd = vboot_get_working_data(); + return wd->selected_region_size > 0; +} + +int vboot_is_readonly_path(void) +{ + return !vboot_is_slot_selected(); +} diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h index 305d0daf1a..fbbc46ef5c 100644 --- a/src/vendorcode/google/chromeos/vboot2/misc.h +++ b/src/vendorcode/google/chromeos/vboot2/misc.h @@ -22,55 +22,21 @@ #include "../vboot_common.h" +struct vb2_context; +struct vb2_shared_data; + void vboot_fill_handoff(void); void *vboot_load_stage(int stage_index, struct region *fw_main, struct vboot_components *fw_info); -/* - * this is placed at the start of the vboot work buffer. selected_region is used - * for the verstage to return the location of the selected slot. buffer is used - * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses - * stage boundaries. - */ -struct vb2_working_data { - uint32_t selected_region_offset; - uint32_t selected_region_size; - /* offset of the buffer from the start of this struct */ - uint32_t buffer_offset; - uint32_t buffer_size; -}; - -struct vb2_working_data * const vboot_get_working_data(void); -size_t vb2_working_data_size(void); -void *vboot_get_work_buffer(struct vb2_working_data *wd); +void vb2_init_work_context(struct vb2_context *ctx); +struct vb2_shared_data *vb2_get_shared_data(void); /* Returns 0 on success. < 0 on failure. */ -static inline int vb2_get_selected_region(struct vb2_working_data *wd, - struct region_device *rdev) -{ - struct region reg = { - .offset = wd->selected_region_offset, - .size = wd->selected_region_size, - }; - return vboot_region_device(®, rdev); -} - -static inline void vb2_set_selected_region(struct vb2_working_data *wd, - struct region_device *rdev) -{ - wd->selected_region_offset = region_device_offset(rdev); - wd->selected_region_size = region_device_sz(rdev); -} - -static inline int vboot_is_slot_selected(struct vb2_working_data *wd) -{ - return wd->selected_region_size > 0; -} - -static inline int vboot_is_readonly_path(struct vb2_working_data *wd) -{ - return wd->selected_region_size == 0; -} +int vb2_get_selected_region(struct region_device *rdev); +void vb2_set_selected_region(struct region_device *rdev); +int vboot_is_slot_selected(void); +int vboot_is_readonly_path(void); #endif /* __CHROMEOS_VBOOT2_MISC_H__ */ diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c index 8e12fdcad0..bf7d6542eb 100644 --- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c +++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c @@ -130,9 +130,8 @@ void vboot_fill_handoff(void) struct region_device fw_main; struct vboot_components *fw_info; size_t metadata_sz; - struct vb2_working_data *wd = vboot_get_working_data(); - sd = vboot_get_work_buffer(wd); + sd = vb2_get_shared_data(); sd->workbuf_hash_offset = 0; sd->workbuf_hash_size = 0; @@ -149,10 +148,10 @@ void vboot_fill_handoff(void) fill_vboot_handoff(vh, sd); /* Nothing left to do in readonly path. */ - if (vboot_is_readonly_path(wd)) + if (vboot_is_readonly_path()) return; - if (vb2_get_selected_region(wd, &fw_main)) + if (vb2_get_selected_region(&fw_main)) die("No component metadata.\n"); metadata_sz = sizeof(*fw_info); diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c index 8517a30999..bb7bc4c828 100644 --- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c +++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c @@ -65,7 +65,6 @@ static int verstage_should_load(void) static int vboot_active(struct asset *asset) { - struct vb2_working_data *wd; int run_verification; run_verification = verification_should_run(); @@ -104,12 +103,7 @@ static int vboot_active(struct asset *asset) if (ENV_ROMSTAGE) vboot_fill_handoff(); - wd = vboot_get_working_data(); - - if (vboot_is_slot_selected(wd)) - return 1; - - return 0; + return vboot_is_slot_selected(); } static int vboot_locate_by_components(const struct region_device *fw_main, @@ -189,7 +183,6 @@ static int vboot_asset_locate(const struct region_device *fw_main, * means we are taking vboot paths. */ static int vboot_locate(struct asset *asset) { - struct vb2_working_data *wd; struct region_device fw_main; /* Code size optimization. We'd never actually get called under the @@ -198,8 +191,7 @@ static int vboot_locate(struct asset *asset) if (verstage_should_load() && !IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) return 0; - wd = vboot_get_working_data(); - if (vb2_get_selected_region(wd, &fw_main)) + if (vb2_get_selected_region(&fw_main)) die("failed to reference selected region\n"); return vboot_asset_locate(&fw_main, asset); diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c index 76355ecdab..0767454db4 100644 --- a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c +++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c @@ -209,22 +209,6 @@ static uint32_t extend_pcrs(struct vb2_context *ctx) tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR); } -static void init_vb2_working_data(void) -{ - struct vb2_working_data *wd; - size_t work_size; - - work_size = vb2_working_data_size(); - wd = vboot_get_working_data(); - memset(wd, 0, work_size); - /* - * vboot prefers 16-byte alignment. This takes away 16 bytes - * from the VBOOT2_WORK region, but the vboot devs said that's okay. - */ - wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16); - wd->buffer_size = work_size - wd->buffer_offset; -} - /** * Verify and select the firmware in the RW image * @@ -235,16 +219,12 @@ void verstage_main(void) { struct vb2_context ctx; struct region_device fw_main; - struct vb2_working_data *wd; int rv; - init_vb2_working_data(); - wd = vboot_get_working_data(); + timestamp_add_now(TS_START_VBOOT); /* Set up context and work buffer */ - memset(&ctx, 0, sizeof(ctx)); - ctx.workbuf = vboot_get_work_buffer(wd); - ctx.workbuf_size = wd->buffer_size; + vb2_init_work_context(&ctx); /* Read nvdata from a non-volatile storage */ read_vbnv(ctx.nvdata); @@ -347,6 +327,6 @@ void verstage_main(void) } printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B'); - vb2_set_selected_region(wd, &fw_main); + vb2_set_selected_region(&fw_main); timestamp_add_now(TS_END_VBOOT); } -- cgit v1.2.3