diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-08-30 23:23:53 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-05 21:04:17 -0700 |
commit | 9c5cf4bf47f3f58097d5fde3a1c03cdcd0c9449f (patch) | |
tree | 56c042c676b168baa0a7ddef49e905d2e020024e /futility/cmd_update.c | |
parent | 90ee96f5c76a78aad8fddbd8eb7f9c6035d69996 (diff) | |
download | vboot-9c5cf4bf47f3f58097d5fde3a1c03cdcd0c9449f.tar.gz |
futility: cmd_update: Preserve sections blocked by management engine
On Intel platforms, when management engine is not in manufacturing mode the
SI_DESC will be read only and SI_ME can't be accessed by CPU.
For RW-FULL mode when we want to reflash whole firmware, flashrom will skip
SI_ME but it'll still try to update SI_DESC if the content looks different,
which would make all firmware update to fail when a new image is pushed with
different SI_DESC contents.
As a result, we have to preserve and skip SI_DESC changes when ME is locked.
BUG=chromium:875551
TEST=make futil; tests/futility/run_test_scripts.sh $(pwd)/build/futility
BRANCH=None
Change-Id: I834405ad519dcb7ccd44073addfd63e844b74168
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1197022
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'futility/cmd_update.c')
-rw-r--r-- | futility/cmd_update.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c index 3996901e..3e44cd65 100644 --- a/futility/cmd_update.c +++ b/futility/cmd_update.c @@ -40,7 +40,9 @@ static const char * const FMAP_RO_FRID = "RO_FRID", * const FMAP_RW_FWID_B = "RW_FWID_B", * const FMAP_RW_SHARED = "RW_SHARED", * const FMAP_RW_NVRAM = "RW_NVRAM", - * const FMAP_RW_LEGACY = "RW_LEGACY"; + * const FMAP_RW_LEGACY = "RW_LEGACY", + * const FMAP_SI_DESC = "SI_DESC", + * const FMAP_SI_ME = "SI_ME"; /* System environment values. */ static const char * const FWACT_A = "A", @@ -442,6 +444,23 @@ static int firmware_section_exists(const struct firmware_image *image, } /* + * Checks if the section is filled with given character. + * If section size is 0, return 0. If section is not empty, return non-zero if + * the section is filled with same character c, otherwise 0. + */ +static int section_is_filled_with(const struct firmware_section *section, + uint8_t c) +{ + uint32_t i; + if (!section->size) + return 0; + for (i = 0; i < section->size; i++) + if (section->data[i] != c) + return 0; + return 1; +} + +/* * Loads the firmware information from an FMAP section in loaded firmware image. * The section should only contain ASCIIZ string as firmware version. * If successful, the return value is zero and *version points to a newly @@ -844,6 +863,29 @@ static int preserve_gbb(const struct firmware_image *image_from, } /* + * Preserves the regions locked by Intel management engine. + */ +static int preserve_management_engine(const struct firmware_image *image_from, + struct firmware_image *image_to) +{ + struct firmware_section section; + + find_firmware_section(§ion, image_from, FMAP_SI_ME); + if (!section.data) { + Debug("%s: Skipped because no section %s\n", __FUNCTION__, + FMAP_SI_ME); + return 0; + } + if (section_is_filled_with(§ion, 0xFF)) { + Debug("%s: ME is probably locked - preserving %s.\n", + __FUNCTION__, FMAP_SI_DESC); + return preserve_firmware_section( + image_from, image_to, FMAP_SI_DESC); + } + return 0; +} + +/* * Preserves the critical sections from the current (active) firmware. * Currently only GBB, VPD (RO+RW) and NVRAM sections are preserved. * Returns 0 if success, non-zero if error. @@ -853,6 +895,7 @@ static int preserve_images(struct updater_config *cfg) int errcnt = 0; struct firmware_image *from = &cfg->image_current, *to = &cfg->image; errcnt += preserve_gbb(from, to); + errcnt += preserve_management_engine(from, to); errcnt += preserve_firmware_section(from, to, FMAP_RO_VPD); errcnt += preserve_firmware_section(from, to, FMAP_RW_VPD); errcnt += preserve_firmware_section(from, to, FMAP_RW_NVRAM); |