diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-09-28 12:39:56 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-02 09:17:10 -0700 |
commit | 6d211585f519a3ace76b01a372523207fb695a1c (patch) | |
tree | c3987a26c18ade48440658967f34d8712fc732b5 | |
parent | 04e441e5f74e107d05578622909410259f6d6f99 (diff) | |
download | vboot-6d211585f519a3ace76b01a372523207fb695a1c.tar.gz |
futility: updater: Preserve SMMSTORE and add quirk 'eve_smm_store'
The 'SMM store' must be preserved during firmware update. On newer systems,
this can be done by preserving FMAP section 'SMMSTORE' (CL:1221210).
For Eve, the SMM store did not have its own FMAP section and needs to be
reserved by explicit cbfstool calls.
BRANCH=None
BUG=b:70682365
TEST=make futil; tests/futility/run_test_scripts.sh $(pwd)/build/futility
Change-Id: Ica043f51de0170b5c40f61d059437b9572025e2e
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1250464
Reviewed-by: Joel Kitching <kitching@chromium.org>
-rw-r--r-- | futility/updater.c | 4 | ||||
-rw-r--r-- | futility/updater.h | 2 | ||||
-rw-r--r-- | futility/updater_quirks.c | 86 | ||||
-rwxr-xr-x | tests/futility/test_update.sh | 15 |
4 files changed, 107 insertions, 0 deletions
diff --git a/futility/updater.c b/futility/updater.c index d5bc88e2..5480f7e9 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -955,6 +955,7 @@ static int preserve_images(struct updater_config *cfg) FMAP_RW_PRESERVE, FMAP_RW_NVRAM, FMAP_RW_ELOG, + FMAP_RW_SMMSTORE, /* * TODO(hungte): b/116326638: Remove RO_FSG after the migration * is finished. @@ -1539,6 +1540,9 @@ enum updater_error_codes update_firmware(struct updater_config *cfg) if (try_apply_quirk(QUIRK_ENLARGE_IMAGE, cfg)) return UPDATE_ERR_SYSTEM_IMAGE; + if (try_apply_quirk(QUIRK_EVE_SMM_STORE, cfg)) + return UPDATE_ERR_INVALID_IMAGE; + if (debugging_enabled) print_system_properties(cfg); diff --git a/futility/updater.h b/futility/updater.h index 3134bbbc..58445a1c 100644 --- a/futility/updater.h +++ b/futility/updater.h @@ -32,6 +32,7 @@ static const char * const FMAP_RO_FRID = "RO_FRID", * const FMAP_RW_ELOG = "RW_ELOG", * const FMAP_RW_PRESERVE = "RW_PRESERVE", * const FMAP_RW_LEGACY = "RW_LEGACY", + * const FMAP_RW_SMMSTORE = "SMMSTORE", * const FMAP_SI_DESC = "SI_DESC", * const FMAP_SI_ME = "SI_ME"; @@ -78,6 +79,7 @@ enum quirk_types { QUIRK_MIN_PLATFORM_VERSION, QUIRK_UNLOCK_ME_FOR_UPDATE, QUIRK_DAISY_SNOW_DUAL_MODEL, + QUIRK_EVE_SMM_STORE, QUIRK_MAX, }; diff --git a/futility/updater_quirks.c b/futility/updater_quirks.c index 6a3fa222..c1d937af 100644 --- a/futility/updater_quirks.c +++ b/futility/updater_quirks.c @@ -9,6 +9,8 @@ #include <assert.h> #include <stdio.h> #include <string.h> +#include <sys/types.h> +#include <sys/stat.h> #include "updater.h" #include "host_misc.h" @@ -31,6 +33,9 @@ static const struct quirks_record quirks_records[] = { { .match = "Google_Caroline.", .quirks = "unlock_me_for_update" }, { .match = "Google_Cave.", .quirks = "unlock_me_for_update" }, + { .match = "Google_Eve.", + .quirks = "unlock_me_for_update,eve_smm_store" }, + { .match = "Google_Poppy.", .quirks = "min_platform_version=6" }, { .match = "Google_Scarlet.", .quirks = "min_platform_version=1" }, @@ -220,6 +225,81 @@ static int quirk_daisy_snow_dual_model(struct updater_config *cfg) } /* + * Extracts files from a CBFS on given region (section) of image_file. + * Returns the path to a temporary file on success, otherwise NULL. + */ +static const char *extract_cbfs_file(struct updater_config *cfg, + const char *image_file, + const char *cbfs_region, + const char *cbfs_name) +{ + const char *output = create_temp_file(cfg); + char *command, *result; + + if (asprintf(&command, "cbfstool \"%s\" extract -r %s -n \"%s\" " + "-f \"%s\" 2>&1", image_file, cbfs_region, + cbfs_name, output) < 0) { + ERROR("Failed to allocate internal buffer."); + return NULL; + } + result = host_shell(command); + free(command); + + if (!*result) + output = NULL; + + free(result); + return output; +} + +/* + * Quirk to help preserving SMM store on devices without a dedicated "SMMSTORE" + * FMAP section. These devices will store "smm store" file in same CBFS where + * the legacy boot loader lives (i.e, FMAP RW_LEGACY). + * Note this currently has dependency on external program "cbstool". + * Returns 0 if the SMM store is properly preserved, or if the system is not + * available to do that (problem in cbfstool, or no "smm store" in current + * system firmware). Otherwise non-zero as failure. + */ +static int quirk_eve_smm_store(struct updater_config *cfg) +{ + const char *smm_store_name = "smm store"; + const char *temp_image = create_temp_file(cfg); + const char *old_store; + char *command; + + if (write_image(temp_image, &cfg->image_current) != VBERROR_SUCCESS) + return -1; + + old_store = extract_cbfs_file(cfg, temp_image, FMAP_RW_LEGACY, + smm_store_name); + if (!old_store) { + DEBUG("cbfstool failure or SMM store not available. " + "Don't preserve."); + return 0; + } + + /* Reuse temp_image. */ + if (write_image(temp_image, &cfg->image) != VBERROR_SUCCESS) + return -1; + + /* crosreview.com/1165109: The offset is fixed at 0x1bf000. */ + if (asprintf(&command, + "cbfstool \"%s\" remove -r %s -n \"%s\" 2>/dev/null; " + "cbfstool \"%s\" add -r %s -n \"%s\" -f \"%s\" " + " -t raw -b 0x1bf000", temp_image, FMAP_RW_LEGACY, + smm_store_name, temp_image, FMAP_RW_LEGACY, + smm_store_name, old_store) < 0) { + ERROR("Failed to allocate internal buffer."); + return -1; + } + host_shell(command); + free(command); + + return reload_image(temp_image, &cfg->image); +} + +/* * Registers known quirks to a updater_config object. */ void updater_register_quirks(struct updater_config *cfg) @@ -248,6 +328,12 @@ void updater_register_quirks(struct updater_config *cfg) quirks->name = "daisy_snow_dual_model"; quirks->help = "b/35525858; needs an image RW A=[model x16], B=x8."; quirks->apply = quirk_daisy_snow_dual_model; + + quirks = &cfg->quirks[QUIRK_EVE_SMM_STORE]; + quirks->name = "eve_smm_store"; + quirks->help = "b/70682365; preserve UEFI SMM store without " + "dedicated FMAP section."; + quirks->apply = quirk_eve_smm_store; } /* diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh index 1b80e2e5..d45e114c 100755 --- a/tests/futility/test_update.sh +++ b/tests/futility/test_update.sh @@ -287,3 +287,18 @@ if type flashrom >/dev/null 2>&1; then -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1,3 >&2 cmp "${TMP}.emu" "${TMP}.expected.full" fi + +if type cbfstool >/dev/null 2>&1; then + echo "SMM STORE" >"${TMP}.smm" + truncate -s 262144 "${TMP}.smm" + cp -f "${FROM_IMAGE}" "${TMP}.from.smm" + cp -f "${TMP}.expected.full" "${TMP}.expected.full_smm" + cbfstool "${TMP}.from.smm" add -r RW_LEGACY -n "smm store" \ + -f "${TMP}.smm" -t raw + cbfstool "${TMP}.expected.full_smm" add -r RW_LEGACY -n "smm store" \ + -f "${TMP}.smm" -t raw -b 0x1bf000 + test_update "Legacy update (--quirks eve_smm_store)" \ + "${TMP}.from.smm" "${TMP}.expected.full_smm" \ + -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1 \ + --quirks eve_smm_store +fi |